Corda中OwnableState的Vault存储规则与状态追踪问题
关于Corda OwnableState Vault存储与状态追踪的问题
我来帮你拆解下这个问题哈,先从核心原因说起,再给你几个实用的解决方案:
为什么节点A看不到发送后的状态?
你对Vault默认存储规则的理解是完全正确的:
- 对于
OwnableState类型的状态,只有当前owner节点会持久化存储该状态 - 非
OwnableState的状态,只要节点是参与者之一就会存储
你的MyPersistentState实现了OwnableState,且把owner设为了接收方节点B,哪怕participants里包含节点A,也会被Vault的规则过滤掉——这就是你在A节点查不到任何相关状态的根本原因。
状态追踪的解决方案
你担心的「节点B追不到来源、节点A追不到去向」是可以解决的,给你几个符合Corda设计思路的方案:
1. 结合LinearState实现全链路追踪
如果需要留存状态的流转记录,可以让你的状态同时实现LinearState(线性状态):
- 每个线性状态都有唯一的
linearId,哪怕发送方不存储当前的活跃状态,也能通过这个ID查询到所有关联的交易历史 - 同时可以明确把
participants设为包含发送方和接收方,配合LinearState的特性,让参与节点都能追踪到状态的完整流转路径
2. 利用交易历史做审计
Corda的每个交易都会被所有参与节点记录在交易存储中,哪怕节点A的Vault里没有该状态,也能通过以下方式查询:
- 调用
serviceHub.validatedTransactions.getTransaction(txId)获取具体交易详情,从中提取状态的发送方、接收方信息 - 用
serviceHub.validatedTransactions.track()订阅交易事件,筛选所有涉及自己的交易,实时监控状态流转
3. 参考官方Cash合约的设计思路
你代码里引入了官方的Cash合约,它也是OwnableState,但完美解决了追踪问题:
- 转账交易中,节点A的Vault会保留已消耗的输入状态(可以用
VaultQueryCriteria指定Status.CONSUMED查询),通过这个就能看到自己的现金去向 - 节点B的Vault里是未消耗的输出状态,同时可以通过交易记录追溯到输入状态的所有者(也就是节点A)
你的状态类优化示例
结合LinearState的思路,给你调整后的代码参考:
package com.shailesh import net.corda.core.contracts.OwnableState import net.corda.core.contracts.LinearState import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState import net.corda.core.serialization.CordaSerializable @CordaSerializable data class MyPersistentState( val amount: Int, val sender : AbstractParty, val receiver : AbstractParty, override val linearId: UniqueIdentifier = UniqueIdentifier() ) : OwnableState, LinearState { override val owner: AbstractParty get() = receiver // 明确包含发送方和接收方作为参与者 override val participants: List<AbstractParty> get() = listOf(sender, receiver) }
这样调整后:
- 节点A可以通过
linearId查询交易历史,追踪状态的去向 - 节点B能直接通过状态的
sender字段看到来源,也能查交易历史做完整追溯 - 同时保留了
OwnableState的归属权核心特性
内容的提问来源于stack exchange,提问作者Shailesh Pratapwar
相关产品推荐
相关产品推荐

