如何获得Corda的交易记录?

时间:2018-05-29 23:17:32

标签: corda

要获得状态,我可以使用保险柜,但交易呢?我怎么能通过txHash获得它们?是否可以通过CordaRPCOps执行此操作,有internalVerifiedTransactionsSnapshot方法,但现在已弃用。

3 个答案:

答案 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
}