#corda
#corda
Вопрос:
В настоящее время я обучаюсь, чтобы стать разработчиком corda.
Я создал простое CorDapp, в котором есть только 1 участник, вот созданное мной состояние:
@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
Но то, что я хочу сделать, это обновить хранилище. Я бы, например, хотел обновить адрес с «Пампанга» на «Манила», но я не знаю, с чего начать. Все, что я знаю, это то, что, поскольку состояния неизменяемы, вы должны сначала использовать состояние.
Я попытался создать поток:
@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))
}
Но это не работает.
Ответ №1:
- Вы правы, состояния неизменяемы в Corda, и для имитации обновления вам в основном нужно создать транзакцию, в которой входными данными является ваша текущая версия состояния (т. Е. address = Pampanga), а на выходе будет новый экземпляр
UserState
, который имеет те жеlinearId
и другие значения атрибутов, что и входные данные, нодругое значение адреса (например, Manila). - Таким образом, вы создаете новое состояние (выходные данные транзакции), но поскольку оно будет иметь то же
linearId
значение; это было бы так, как если бы вы обновили входные данные, чтобы они стали выходными, это позволит вам увидеть все предыдущие версии состояния, запрашивая хранилище по егоlinearId
. - Вы не поделились кодом своего контракта, но вам нужно добавить новую команду (назовем ее
Update
); а также вам нужно добавить правила проверки, которые применяются к нему. - Внутри вашего потока вы бы использовали эту команду (вместо
Issue
).