【问题标题】:state contract not change after execute ContractUpgradeFlow执行合约升级流程后状态合约不会改变
【发布时间】:2019-01-25 07:44:55
【问题描述】:

我尝试按照这篇文章升级合约https://docs.corda.net/contract-upgrade.html 然后在执行 ContractUpgradeFlow 后没有错误,但是当查询 Vault 时,它似乎状态仍然属于旧合同。

在表中它已经插入到 node_contract_upgrades

但是当从保险库查询状态时,我仍然得到旧合同,如果我与(旧状态+新合同)进行交易,它将显示合同约束

Flow Internal Error : java.util.concurrent.ExecutionException: net.corda.core.contracts.TransactionVerificationException$ContractConstraintRejection: Contract constraints failed for th.co.jventures.ddlp.cordapp.contracts.CustomerContractV01, transaction: 418A9A1562A1A7F3C465EC2CC5DDEFB83F5D9C71269EDF83BFBA1094274F926F

这里是我的 client.kt 用于运行流程升级

       <pre>`<pre>fun main(args: Array<String>) {
        UpgradeContractClient().main(args)
    }

    /**
     *  A utility demonstrating the contract upgrade process.
     *  In this case, we are upgrading the states' contracts, but not the states
     *  themselves.
     **/
    private class UpgradeContractClient {
        companion object {
            val logger: Logger = loggerFor<UpgradeContractClient>()
        }

        fun main(args: Array<String>) {


            val clientDs = CordaRPCClient(parse("localhost:10009"))
            val dsProxy = clientDs.start("user1", "test").proxy

            val clientPah = CordaRPCClient(parse("localhost:10008"))
            val pahProxy = clientPah.start("user1", "test").proxy

            // Authorise the upgrade of all the State instances using OldContract.
            println("Doing Authorise")
            listOf(dsProxy, pahProxy).forEach { proxy ->
                // Extract all the unconsumed State instances from the vault.
                val stateAndRefs = proxy.vaultQuery(CustomerStateV01::class.java).states
                println("Found customerState=${stateAndRefs.size} for node : ${proxy.nodeInfo()}")

                // Run the upgrade flow for each one.
                stateAndRefs.filter { stateAndRef ->
                    stateAndRef.state.contract == CustomerContractV01.CONTRACT_ID
                }.forEach { stateAndRef ->
                    proxy.startFlowDynamic(
                            ContractUpgradeFlow.Authorise::class.java,
                            stateAndRef,
                            CustomerContractV02::class.java).returnValue.getOrThrow()
                }

                println("Finished")

            }
            Thread.sleep(5000)

            // Initiate the upgrade of all the State instances using OldContract.
            println("Doing Initiate")
            dsProxy.vaultQuery(CustomerStateV01::class.java).states
                    .filter { stateAndRef ->
                        stateAndRef.state.contract == CustomerContractV01.CONTRACT_ID
                    }
                    .forEach { stateAndRef ->
                        dsProxy.startFlowDynamic(
                                ContractUpgradeFlow.Initiate::class.java,
                                stateAndRef,
                                CustomerContractV02::class.java)
                    }

            // Log all the State instances in the vault to show they are using NewContract.
            dsProxy.vaultQuery(CustomerStateV01::class.java).states.forEach { println("${it.state}") }
            dsProxy.vaultQuery(CustomerStateV01::class.java).states.forEach { println("${it.state.contract}") }
        }}`

这里是我的合同V02

class CustomerContractV02 : UpgradedContract<CustomerStateV01, CustomerStateV01>{
override val legacyContract: ContractClassName
    get() = CustomerContractV01.CONTRACT_ID


override fun upgrade(state: CustomerStateV01): CustomerStateV01 {
    return state
}

我期望旧合同的状态应该与新合同进行交易还是我误解了概念?

【问题讨论】:

  • 当您检查它们是否使用旧合同时,您如何从保险库中查询状态?请注意,合约升级过程会使用旧合约的状态来创建新合约的新状态。确保您没有查询旧状态。
  • 我的升级只想要旧状态的新合同,所以我用它来查询 dsProxy.vaultQuery(CustomerStateV01::class.java).states.forEach { println("${it.state.contract} ") } 然后所有 CustomerStateV01 仍在使用 CustomerContractV01
  • 您正在异步执行ContractUpgradeFlow.Initiate 流。您可以尝试在最终的保管库查询之前插入 10 秒睡眠 (Thread.sleep(10000)) 以让流程有时间执行吗?
  • 不走运,仍然有旧合同的状态
  • 当 vaultQuery 与 CustomerStateV01 和 vault_states 仍然有 1 行与 CustomerContractV01 时,仍然得到 th.co.jventures.ddlp.cordapp.contracts.CustomerContractV01

标签: corda


【解决方案1】:

作为我的调查。这是因为用 new_contract.jar 替换 old_contract.jar 使合约的约束,然后 Corda 不让合约升级流程。所以我的解决方案是在执行 ContractUpgradeFlow 之前更新网络参数。

【讨论】:

    猜你喜欢
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2022-07-19
    • 2022-07-09
    • 1970-01-01
    相关资源
    最近更新 更多