如何更新保险库中的项目?
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
)。
我目前正在接受培训以成为一名 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
)。