要获得状态,我可以使用保险柜,但交易呢?我怎么能通过txHash获得它们?是否可以通过CordaRPCOps执行此操作,有internalVerifiedTransactionsSnapshot
方法,但现在已弃用。
答案 0 :(得分:4)
首先,请注意,从Corda 3开始,没有关于任何方法检索事务或其依赖关系的行为的稳定性保证。特别是,我们无法保证检索到的事务集不会在Corda版本中发生变化。
这是因为在未来的Corda版本中,节点可能只会以SGX加密的形式交换事务链。然后,将在节点上的SGX包围区内验证这些事务链。这将阻止节点查看正在验证的事务的内容(请参阅此处的博文: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
来获取所有交易,{{1}通过哈希获取特定事务。
请注意,返回的交易类型为serviceHub.validatedTransactions.getTransaction(transactionHash)
。此表单不包含事务的附件或输入(仅附件哈希和输入状态引用)。
要将SignedTransaction
转换为SignedTransaction
(解析附件和输入的位置),您可以写道:
LedgerTransaction
第3。通过连接到节点的数据库
您可以直接连接到支持该节点的SQL数据库,并使用SQL查询检索事务。
答案 1 :(得分:0)
是的,尽管请注意,ServiceHub和SQL方法与已弃用的RPC基本相同,并且将来可能还会停止工作(或取决于我们管理向加密分类帐过渡的方式)。
还有其他方法可以使用。例如,您可以将您关心的历史记录汇总到该状态的最新版本中。这也使您可以在SGX登陆后限制历史记录的视图。
答案 2 :(得分:0)
第一个解决方案(使用CordaRPCOps.internalVerifiedTransactionsSnapshot)确实很慢。
这是获取交易历史记录的另一种方法,并且非常有效。
您可以使用rpcOps.vaultQueryBy
完成此操作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
}