如何更新保险库中的项目?

How to update the items in the vault?

我目前正在接受培训以成为一名 corda 开发人员。

我创建了一个只有 1 个参与者的简单 corDapp,这是我创建的状态:

@BelongsToContract(UserContract::class)
class UserState(val name: String,
                val age: Int,
                val address: String,
                val gender: GenderEnums,
                val node: Party,
                val status: StatusEnums,
                override val linearId: UniqueIdentifier,
                override val participants : List<Party>
) : LinearState

所以当我 运行 corDapp 时,我得到了我想要的输出 https://imgur.com/mOKhNpI

但我想做的是更新保险库。例如,我想将地址从“Pampanga”更新为“Manila”,但我不知道从哪里开始。我所知道的是,由于状态是不可变的,因此您必须先使用状态。

我尝试创建一个流程:

@InitiatingFlow
@StartableByRPC
class UpdateUserFlows(private val name :String,
                      private val age : Int,
                      private val address : String,
                      private val gender: GenderEnums,
                      private val status : StatusEnums,
                      private val counterParty: Party): FlowLogic<SignedTransaction>() {

    private fun userStates(): UserState {
        return UserState(
                name = name,
                age = age,
                address = address,
                gender = gender,
                status = status,
                node = ourIdentity,
                linearId = UniqueIdentifier(),
                participants = listOf(ourIdentity, counterParty)
        )
    }

    @Suspendable
    override fun call(): SignedTransaction {
        val transaction: TransactionBuilder = transaction()
        val signedTransaction: SignedTransaction = verifyAndSign(transaction)
        val sessions: List<FlowSession> = (userStates().participants - ourIdentity).map { initiateFlow(it) }.toSet().toList()
        val transactionSignedByAllParties: SignedTransaction = collectSignature(signedTransaction, sessions)
        return recordTransaction(transactionSignedByAllParties, sessions)
    }

    private fun transaction(): TransactionBuilder {
        val notary: Party = serviceHub.networkMapCache.notaryIdentities.first()
        val issueCommand = Command(UserContract.Commands.Issue(), userStates().participants.map { it.owningKey })
        val builder = TransactionBuilder(notary = notary)
        builder.addOutputState(userStates(), UserContract.ID)
        builder.addCommand(issueCommand)
        return builder
    }

    private fun verifyAndSign(transaction: TransactionBuilder): SignedTransaction {
        transaction.verify(serviceHub)
        return serviceHub.signInitialTransaction(transaction)
    }


    @Suspendable
    private fun collectSignature(
            transaction: SignedTransaction,
            sessions: List<FlowSession>
    ): SignedTransaction = subFlow(CollectSignaturesFlow(transaction, sessions))

    @Suspendable
    private fun recordTransaction(transaction: SignedTransaction, sessions: List<FlowSession>): SignedTransaction =
            subFlow(FinalityFlow(transaction, sessions))
}

但它不起作用。

  • 你是对的,Corda 中的状态是不可变的,为了模拟更新,你基本上需要创建一个交易,其中输入是你当前的状态版本(即地址 = Pampanga),并且输出将是 UserState 的新实例,它具有与输入相同的 linearId 和其他属性值,但地址值不同(即马尼拉)。

  • 这样你创建了一个新的状态(交易的输出),但是因为它将有相同的linearId值;就像您将输入更新为输出一样,这将允许您通过 linearId.

    查询保险库来查看状态的所有先前版本
  • 你没有分享你合约的代码,但你需要添加一个新命令(我们称之为Update);并且你还需要添加适用于它的验证规则。

  • 在您的流程中,您将使用该命令(而不是 Issue)。