gpt4 book ai didi

javascript - super 账本 Composer : calling a query within a transaction that updated an asset returns old results

转载 作者:行者123 更新时间:2023-11-29 17:44:39 26 4
gpt4 key购买 nike

我有一个非常简单的 Hyperledger Composer applicationnamespace com.softwaremill.drivernetwork 的问题

participant Driver identified by licenseId {
o String licenseId
o String firstName
o String lastName
o Boolean licenseValid default =true
}

enum LaweEnforcerType {
o POLICE
o CUSTOMS
o BORDER_GUARDS
}

participant LawEnforcer identified by lawEnforcerId {
o String lawEnforcerId
o LaweEnforcerType lawEnforcerType
}

participant Court identified by courtId {
o String courtId
o String description
}

enum FineState {
o ISSUED
o REJECTED
o ACCEPTED
}

asset Fine identified by fineId {
o String fineId
o Integer penaltyPoints
o DateTime date
o FineState fineState default ="ISSUED"
--> Driver driver
--> LawEnforcer lawEnforcer
}

asset CourtCase identified by caseId {
o String caseId
--> Court court optional
--> Fine fine
}

transaction AcceptedFine {
--> Fine fine
}

transaction RejectedFine {
--> Fine fine
}

LawEnforcer 可以发出罚款。司机可以接受或拒绝罚款(然后上法庭)。

我想做的是,如果他接受的所有 penaltyPoints 罚款总和超过 20 分,则自 Action 废驾照。

所以我创建了一个事务处理器

/**
* Accept fine
* @param {com.softwaremill.drivernetwork.AcceptedFine} acceptedFine
* @transaction
*/
async function acceptedFine(acceptedFine) {
console.log(`Accepting fine ${acceptedFine}`);

const fineRegistry = await getAssetRegistry('com.softwaremill.drivernetwork.Fine');

acceptedFine.fine.fineState = 'ACCEPTED';
await fineRegistry.update(acceptedFine.fine); // [1]

const allFines = await query('selectAcceptedFinesByDriver',
{driver: `resource:com.softwaremill.drivernetwork.Driver#${acceptedFine.fine.driver.licenseId}`}); // [2]

if (allFines.reduce((acc, val) => {return acc + val.penaltyPoints;}, 0) > 20) {
console.log('Driver excceded 20 points, blocking license');

const driverRegistry = await getParticipantRegistry('com.softwaremill.drivernetwork.Driver');

acceptedFine.fine.driver.licenseValid = false;

await driverRegistry.update(acceptedFine.fine.driver);
}
}

和查询代码

query selectAcceptedFinesByDriver {
description: "Select all accepted fines for a given driver"
statement:
SELECT com.softwaremill.drivernetwork.Fine
WHERE (driver == _$driver AND fineState == "ACCEPTED")
}

现在代码应该在 [1] 处将 Fine 状态设置为 ACCEPTED。这行得通 - 处理完交易后,我可以看到属性发生了变化。

但问题是,在 [2] 执行查询时,刚刚在 [1] 更新的 Fine 仍然处于 ISSUED(我删除了查询中 where 的正确部分以对其进行调试)。

我在这里错过了什么?区 block 链的形状有人为交易卡住吗?这是怎么回事?

最佳答案

问题是你不能“读你自己写的”。事务是原子的(因此在一个事务中更改的所有状态都作为一个事务从当前状态提交,或者 - 整个事务被拒绝。

因此,您正在读取(在查询中)的“状态”是上次提交状态的已知状态(当前事务尚未提交,因此 [2] 不能可能在那时获得“已接受”状态。Composer 中的这种行为与您从底层 Hyperledger Fabric 区 block 链获得的行为完全相同;GetState(query) 将仅读取已提交的状态更改,并且不是由先前的 PutState(同一事务中的先前更新)写入的数据(在当前事务中)。只有当该事务已经提交时,查询才有效(在这种情况下),即由组织的背书/提交交易(原子交易)到一个区 block (和世界状态)的节点。

您可以在此处阅读有关交易处理器的更多信息 -> https://hyperledger.github.io/composer/latest/reference/js_scripts

关于javascript - super 账本 Composer : calling a query within a transaction that updated an asset returns old results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50857955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com