我有一个状态SomeBond,我想在 Corda 网络上发布和交易。当参与者 A 将SomeBond状态转移给参与者 B 时,期望是 A 从 X 获得状态,或者 A 被发布SomeBond(假设是 Y)。为了验证这一点,B 运行与交易中所有状态相关的合约。预期的合同是SomeBondContract,但 B 不能保证它会运行。为确保此事务中的状态将运行SomeBondContract,他必须在签名之前实际在流程中进行检查。val outputsLegit = stx.tx.outputs.all { it.contract == "com.example.SomeBondContract" }
val inputsLegit = stx.tx.toLedgerTransaction(serviceHub).inputs.all { it.state.contract == "com.example.SomeBondContract" }但是,如果他只在流程中进行检查,那么它只会验证当前的交易。我们仍然不能确定之前的交易(C 将状态发送给 A)是否具有分配给其输入状态的相同合约。也许它是这样的:C 创建一个事务 (101):输入(空)输出:SomeBondState,合同 ID:com.example.EmptyContract然后创建事务(102):输入:101[0]输出:SomeBondState,合同 ID:com.example.SomeBondContract并使用该交易的输出(即 102[0])作为向 B 转移的输入。这里的问题是 C 从来不是 的合法发行人SomeBondState,而且交易本不应该发生,但由于他给国家分配了一份错误的合同,他毫无问题地创造了它。防止这种情况的一种方法是在合同中也进行相同的检查。这样,流程可以检查当前交易是否具有分配给其状态的合约,并且合约本身可以检查输入状态是否具有分配的合约。这样,交易 102 永远不会成功,因为它有一个类型的输入,SomeBondState但没有 acom.example.SomeBondState作为合同。由于依赖关系图在出现问题之前被递归验证,因此即使有故障的节点也无法将假状态作为真实状态传递。当然,更简单的方法是确保EmptyContractjar 中没有任何内容,但可能会更微妙地滥用任何现有合约来绕过不需要的状态。我只是EmptyContract作为一个例子。但是在流和合同中检查包名似乎有点不安全和hacky。我不完全了解类加载器是如何工作的,以及如何处理具有相同包名的两个相同类名,以及恶意节点是否有办法做事。另外,我真的不明白为什么我们被要求在建立交易时将合同绑定到一个状态?为什么合同不能绑定到状态定义本身的状态?也许一个状态可以用它的相关合同来注释?是否可以在不同的时间以相同的状态使用不同的合约?但这不是命令的用途吗?那么同一份合约在不同的时间会有不同的表现吗?还是我对“我如何确保正确的合同在交易中运行”的全部担忧遗漏了什么?提前感谢您的回答。
1 回答

一只名叫tom的猫
TA贡献1906条经验 获得超3个赞
为了防止这种情况,Corda 4 将引入@BelongsToContract注解。此注释将状态与给定合约联系起来,并防止任何其他合约与此状态一起使用。
示例用法:
@BelongsToContract(TemplateContract::class)
class TemplateState(override val participants: List<AbstractParty>) : ContractState
添加回答
举报
0/150
提交
取消