internalVerifiedTransactionsSnapshot
的方法,但已经被弃用了。internalVerifiedTransactionsSnapshot
的方法,但已经被弃用了。首先需要注意的是,在 Corda 3 中,任何检索交易或其依赖关系的方法都没有稳定性保证。特别地,我们无法保证所检索到的交易集合不会随着 Corda 版本的变化而改变。
这是因为在 Corda 的未来版本中,节点可能只会以 SGX 加密形式交换交易链。然后,这些交易链将在节点上的 SGX enclave 中进行验证。这将防止节点看到他们正在验证的交易内容(请参见此处的博客文章:https://www.corda.net/2017/06/corda-sgx-privacy-update/)。这甚至可能只允许节点查看他们正在签名的交易的某些部分。
Corda 3 中检索交易的方法
1. 使用 CordaRPCOps.internalVerifiedTransactionsSnapshot
如果您通过 RPC 与节点交互,CordaRPCOps.internalVerifiedTransactionsSnapshot
返回所有已记录的交易列表。
如果您只想获取单个交易并知道它的哈希值,可以编写以下代码:
val transactions = cordaRPCOps.internalVerifiedTransactionsSnapshot()
val signedTransaction = transactions
.find { it.id == transactionHash }
?: throw IllegalArgumentException("Unknown transaction hash.")
请注意返回的交易类型为SignedTransaction
。此表单不包含交易的附件或输入(仅包含附件哈希和输入状态引用)。
要通过RPC检索交易的附件,您可以编写以下代码:
val transactions = cordaRPCOps.internalVerifiedTransactionsSnapshot()
val signedTransaction = transactions
.find { it.id == transactionHash }
?: throw IllegalArgumentException("Unknown transaction hash.")
val attachmentHashes = signedTransaction.tx.attachments
val attachmentStreams = attachmentHashes.map { hash -> cordaRPCOps.openAttachment(hash) }
通过RPC检索交易的输入,你可以这样写:
val transactions = cordaRPCOps.internalVerifiedTransactionsSnapshot()
val signedTransaction = transactions
.find { it.id == transactionHash }
?: throw IllegalArgumentException("Unknown transaction hash.")
val inputStateRefs = signedTransaction.inputs
val inputStates = inputStateRefs.map { stateRef ->
val transaction = transactions.find { it.id == stateRef.txhash }
?: throw IllegalArgumentException("Unknown transaction hash.")
transaction.tx.outputStates[stateRef.index]
}
2. 使用 ServiceHub
如果您处于可以访问节点的 ServiceHub
的情况下(例如在流程或 Corda 服务中),您可以使用 serviceHub.validatedTransactions.track().snapshot
获取所有交易,以及使用 serviceHub.validatedTransactions.getTransaction(transactionHash)
根据哈希获取特定交易。
请注意,返回的交易类型为 SignedTransaction
。这种形式不包含交易的附件或输入(仅包含附件哈希和输入状态引用)。
要将 SignedTransaction
转换为 LedgerTransaction
(其中解析了附件和输入),您可以编写以下代码:
val signedTransaction = serviceHub.validatedTransactions.getTransaction(transactionHash)
val ledgerTransaction = signedTransaction.toLedgerTransaction(serviceHub)
3. 通过连接节点的数据库
您可以直接连接支持节点的 SQL 数据库,并使用 SQL 查询检索交易。
没错,需要注意的是,ServiceHub和SQL方法基本上与已弃用的RPC相同,并且将来也可能停止工作(或不停止,这取决于我们如何管理向加密分类帐的转换)。
您可以使用其他方法。例如,您可以将关心的历史位聚合到状态的最新版本中。这还可以让您在SGX到达后限制历史记录的视图。
fun transaction(transactionId: String): List<Vault.Page<ContractState>> {
// get jdbc connection (you may simplify it within cordapp)
val jt = jt()
// get all states of transaction
val output_indexes = jt.queryForList("SELECT OUTPUT_INDEX FROM VAULT_STATES WHERE transaction_id = '$transactionId'", Int::class.java)
val transactionHash = SecureHash.parse(transactionId)
// get Rpc connection
val rpcOps = initialiseNodeRPCConnection()
val transactionStates = output_indexes.map {
val constraintTypeCriteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL, stateRefs = listOf(StateRef(transactionHash, it)))
rpcOps.vaultQueryBy<ContractState>(constraintTypeCriteria)
}
return transactionStates
}