Adel 提供的方法实际上是我创建这个问题的原因。我正在按照他的概述进行操作,并偶然发现它仅在大约 75% 的时间内有效。让我详细说明……
Adel 是正确的——只要您需要尚未通过 API 提供但可以使用 ServiceHub 的 RPC 客户端功能,您可以创建一个流,使用 @StartableByRPC 对其进行注释并执行必要的步骤返回一个结果。然后只需从您的 RPC 客户端调用该流。我强调了 cordaRPCOps.internalFindVerifiedTransaction() more 的弃用,这表明 R3 正在朝着减少从 RPC 搜索事务的能力而不是更多的能力发展。
我对 Corda 还是很陌生,但我的州通常遵循一致的“生命周期”。对于令牌尤其如此。让我们讨论每个阶段以及 I/Adel 使用的方法是否有效:
第 1 阶段 - 创建/发布
此方法将始终有效,因为交易将产生一个您将成为参与者的输出状态,因此您将其保存在您的保险库中。当您搜索LinearID 时,将找到此状态,您可以交叉引用事务。
第 2 阶段 - 更新/移动
此方法可能起作用,具体取决于您的 CordApp 的性质以及您编写流程的方式。例如,TokenSDK 中的 MoveNonFungibleTokens() 流将某些东西从您的保管库移出到其他人的保管库。在这个新状态下,您将不是Participant,因此您的保管库中不会有它的记录。当您在您的保管库中搜索 LinearID 时,它不会返回您可以交叉引用此交易的任何状态。
我认为,如果您以不同的方式构建流程,则可以避免这种情况。例如,通过在FinalityFlow 中包含StatesToRecord.ALL_VISIBLE,您可以强制存储您不是Participant 的状态。我还没有查看代码,但我认为 R3 选择不使用 MoveNonFungibleTokens() 流。
第 3 阶段 - 删除/赎回
这个方法不起作用,因为没有产生输出状态。因此,当您在您的保管库中搜索 LinearID 时,它不会返回任何您可以交叉引用此交易的状态。我想出找到这些交易的唯一方法是:
- 获取从
QueryCriteria.VaultQueryCriteria 返回的StateMetaData 中的ConsumedTime
- 利用这段时间通过
TIMESTAMP查询NODE_TRANSACTIONS表并抓取TX_ID
- 检查从该查询返回的每个事务的输入,看看它们是否包含我正在寻找的
LinearID
(如果有人有更好的想法,请告诉我)
我希望我在分析/测试中没有犯一些新手错误。如果 Corda 将消费事务 ID 与其他 MetaData 一起保存,那就太好了。这将使在任何情况下都可以轻松定位交易。
Adel 非常感谢您花时间回答我的问题。我不会将其标记为已解决,因为我希望您或其他人可以告诉我我忽略了某些东西。如果没有更好的方法,也许 R3 的人会看到并考虑它。
附录
下面我包含了一些我用来帮助分析事务的日志记录。如果您刚刚进入 Corda,这是一种很好的可视化方式来查看我正在谈论的一些示例。如果它令人困惑,请忽略它。
这是一个交易,其中甲方将一个 NonFungibleToken 移动到乙方。请注意,输出状态没有将 PartyA 列为 Participant,这意味着 PartyA 不会存储此状态。所以如果你搜索LinearID 什么都找不到:
______________________________________________________________________________________
SignedTransaction Info from node: PartyA...
_____________________________________________________________________________________
- getID: 8AD8CEE3340EE23BA1751C24D0652253A8ABB2EA19755704C6A8F42466B14A72 (SecureHash)
- Notes: []
- getNotary: O=Notary, L=London, C=GB (Party)
- # of RequiredSigningKeys: 2 (Set<PublicKey>)
PartyA with PublicKey: DL363eMqRKM8FegtiyEbF1F1zpq4nLp4paaTrKYbMjdKKg (Base58)
Notary with PublicKey: DL47z5vzXwPzFeMnfHsPiWru7wpWi7c5QmthPw4P8az7Ay (Base58)
- # of MissingSigners: 0 (Set<PublicKey>)
______________________________________________________________________________________
WireTransaction Info from node: PartyA...
______________________________________________________________________________________
- getID: 8AD8CEE3340EE23BA1751C24D0652253A8ABB2EA19755704C6A8F42466B14A72 (SecureHash)
- # of Commands: 1 (List<Command>)
MoveTokenCommand
# of Signers: 1 List<PublicKey>
PartyA with PublicKey: DL363eMqRKM8FegtiyEbF1F1zpq4nLp4paaTrKYbMjdKKg (Base58)
- # of Inputs: 1 (List<StateRef>)
SecureHash: B4AD7096BDF29628E1D30907DCFF84E68C1AF8344F1781DE7D549B96D112A836 Index: 0
TransactionState<NonFungibleToken>
getData <ContractState>: TokenType(tokenIdentifier='Ruby-3b1f1ccd-b175-48f1-af0f-e4d82015d31e', fractionDigits=0) issued by PartyA held by PartyA
Participants: PartyA with PublicKey: DL363eMqRKM8FegtiyEbF1F1zpq4nLp4paaTrKYbMjdKKg
getContract (String): com.r3.corda.lib.tokens.contracts.NonFungibleTokenContract
getNotary (Party): O=Notary, L=London, C=GB
getConstraint (AttachmentConstraint): Type - SignatureAttachmentConstraint, PublicKey - DLGqTr8CsXnGGh9d8uve8NWhHsHNm5b6eKzUpNPGqeNVMH (Base58)
getEncumbrance (Int, max allowed = 1): null
- # of Outputs: 1 (List<TransactionState<ContractState>>)
Index 0:
TransactionState<NonFungibleToken>
getData <ContractState>: TokenType(tokenIdentifier='Ruby-3b1f1ccd-b175-48f1-af0f-e4d82015d31e', fractionDigits=0) issued by PartyA held by PartyB
Participants: PartyB with PublicKey: DL5nGmwTZ6jF6FrpNRZ4hbDAW48ut8DxjJ8YZTQw4xY339 !!! PartyA is not listed !!!
getContract (String): com.r3.corda.lib.tokens.contracts.NonFungibleTokenContract
getNotary (Party): O=Notary, L=London, C=GB
getConstraint (AttachmentConstraint): Type - SignatureAttachmentConstraint, PublicKey - DLGqTr8CsXnGGh9d8uve8NWhHsHNm5b6eKzUpNPGqeNVMH (Base58)
getEncumbrance (Int, max allowed = 1): null
- # of Attachments: 1 (List<SecureHash>)
SecureHash: 34705DC9A2C8599998BBDBA7C3D13609AF04D8B3A772F7134D685ECC926D8320 (CordaRPC successfully located Attachment in storage)
- getTimeWindow: null (TimeWindow)
这里是删除LinearState 的示例(兑换令牌看起来相同)。请注意,没有输出,因此如果您搜索LinearID,将找不到任何状态,从而无法交叉引用此交易:
__________________________________________________________________________________
SignedTransaction Info from node: PartyA...
__________________________________________________________________________________
- getID: 4D09C6CBACD104821BEB3095E90C350FE4EA690FD7F8CEA24B71E847EEE10684 (SecureHash)
- Notes: []
- getNotary: O=Notary, L=London, C=GB (Party)
- # of RequiredSigningKeys: 2 (Set<PublicKey>)
PartyA with PublicKey: DL363eMqRKM8FegtiyEbF1F1zpq4nLp4paaTrKYbMjdKKg (Base58)
Notary with PublicKey: DL47z5vzXwPzFeMnfHsPiWru7wpWi7c5QmthPw4P8az7Ay (Base58)
- # of MissingSigners: 0 (Set<PublicKey>)
______________________________________________________________________________________
WireTransaction Info from node: PartyA...
______________________________________________________________________________________
- getID: 4D09C6CBACD104821BEB3095E90C350FE4EA690FD7F8CEA24B71E847EEE10684 (SecureHash)
- # of Commands: 1 (List<Command>)
Delete
# of Signers: 1 List<PublicKey>
PartyA with PublicKey: DL363eMqRKM8FegtiyEbF1F1zpq4nLp4paaTrKYbMjdKKg (Base58)
- # of Inputs: 1 (List<StateRef>)
SecureHash: A45446E1764AB7055B348BC6AAB5E9332BCCFEF21E157A1B28360CC986CDD459 Index: 0
TransactionState<MyLinearState>
getData <ContractState>: linearID: 73fac293-2c89-42fa-8572-7d31e0de567f ExternalID: LinearSate-123 administrator: O=PartyA, L=London, C=GB badPeople: []
Participants: PartyA with PublicKey: DL363eMqRKM8FegtiyEbF1F1zpq4nLp4paaTrKYbMjdKKg
getContract (String): com.template.contracts.MyLinearStateContract
getNotary (Party): O=Notary, L=London, C=GB
getConstraint (AttachmentConstraint): Type - SignatureAttachmentConstraint, PublicKey - DLCTymWiNxvGWE117QUKSjeW71yaaGc5tNL2i8Zp8dFUvE (Base58)
getEncumbrance (Int, max allowed = 1): null
- # of Outputs: 0 (List<TransactionState<ContractState>>) !!! No Outputs !!!
- # of Attachments: 1 (List<SecureHash>)
SecureHash: DB05B1A5B285C73C3C48F81E8D07B8DDF51E7EE9852219D4D65EE934F9524527 (CordaRPC successfully located Attachment in storage)
- getTimeWindow: 22-Oct-2020 15:24:40 to 22-Oct-2020 15:24:50 (TimeWindow)