客户端调用rest-api,然后将数据发送到验证器,事务处理器和验证器进行对话,最后在验证器处理事务并创建块时。至此,对于我来说,它显示以下错误日志:
> sawtooth-validator-default | [2018-12-31 07:36:44.519 DEBUG
> block_validator] Adding block
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
> for processing sawtooth-validator-default | [2018-12-31 07:36:44.532
> WARNING block_validator] Block
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
> (block_num:3,
> state:08afc967eb593120ba5db6d1db548c4b91f26801c3d290fd655a789d51753114,
> previous_block_id:b79c22c94151e76cefcb21ed3c374aa512bff68981bb6b677610e76a8c12a6b2211c3634deb31c0d46ec26f568ed98f27f571625d76e37ee160ca0a9c071ff37)
> failed validation: Block
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
> (block_num:3,
> state:08afc967eb593120ba5db6d1db548c4b91f26801c3d290fd655a789d51753114,
> previous_block_id:b79c22c94151e76cefcb21ed3c374aa512bff68981bb6b677610e76a8c12a6b2211c3634deb31c0d46ec26f568ed98f27f571625d76e37ee160ca0a9c071ff37)
>
> failed state root hash validation. Expected
> 08afc967eb593120ba5db6d1db548c4b91f26801c3d290fd655a789d51753114 but
> got 92673edb4422d913aadb6e49fa1e82688a27589ac98acdd7a8f713d6accd1f25
>
> ========================================================================
>
> sawtooth-validator-default | [2018-12-31 07:36:44.532 DEBUG
> block_validator] Removing block from processing
> 5cad74473aec314bae031acece18fd2b3866ace5c53652118440204e71fc493f4e2251f76298dc7721e8476ad629e0ba0ac533b9fe925bcc63f29c1a6c60795a
实际预期结果是:应该创建该区块并将其添加到区块链中
答案 0 :(得分:1)
验证器将多次向您的TP发送相同的交易请求。如果您的TP使用与验证程序不同的地址和/或数据哈希值在链上设置数据,则交易失败。这样做是出于安全性考虑,但会影响您的TP。
您的TP 绝不能 在TP中创建地址或数据,只要给定相同的输入就会产生不同的输出。交易中的TP地址和数据集必须是确定性的。
如果您正在生成一些唯一的信息(例如时间或加密),则应先在客户端中执行此操作,然后再将其发送到TP。
已更新:
如前所述,要存储的数据是一个关联结构。由于本机关联中的顺序不是确定性的,因此很可能是根本问题。添加另一个protobuf结构来捕获name/value
,然后在将数据(集合)保存到链中之前将其添加到有序数组中即可解决此问题。
根据文档:
不强制执行有序序列化的数据结构(例如集合, 地图,字典)。
答案 1 :(得分:0)
上面提到的状态根问题是由于用Javascript编写的事务处理器代码几乎没有在设置状态时做出承诺链问题。设法兑现诺言正确地解决了我的问题。
apply(transactionRequest, context) {
var payload=cbor.decode(transactionRequest.payload)
if (!payload.action) {
throw new InvalidTransaction("Payload doesn't contain the
action");
}
if (!payload.data) {
throw new InvalidTransaction("Payload doesn't contain the Data");
}
let action = payload.action;
let address = NAMESPACE + hash(payload.data.productID).substring(0,
64);
switch (action) {
case "updateProduct":
return context.getState([address])
.then((possibleAddressValues)=>{
let stateValue = possibleAddressValues[address];
if (stateValue && stateValue.length) {
let value = JSON.parse(cbor.decode(stateValue));
console.log("decoded values : ",value)
if (payload.data.price) {
value.price = payload["data"]["price"]
}
if (payload.data.itemsInInventory) {
value.itemsInInventory = payload["data"]["itemsInInventory"]
}
console.log("values after updating status : ",value)
let entries = {
[address]: cbor.encode(JSON.stringify(value))
}
return context.setState(entries);
}else{
throw new InvalidTransaction("there is no Product for given Product ID : ",payload.data.purchaseId);
}
})
.catch((err)=>{
console.log(new Date()+"Error while getting and setting confirm status for Product ID : ",payload.purchaseId );
})
break;
default:
throw new InvalidTransaction("The action is Invalid or not supported by this transaction processor");
}
}