Adrian
Adrian

Reputation: 444

How to upgrade stateV1 to V2 without changing the Contract version?

I have an ObligationV1 and two states ObligationStateV1 and ObligationStateV2.

How do I achieve A state is upgraded while the contract stays the same. where the state goes from V1 to V2 without changing the contract version. Based on the examples exampleLink, docs

It seems that the code will end up looking like this where you have a new ObligationContractV2? The example was trying to achieve This CorDapp shows how to upgrade a state without upgrading the Contract. But I don't see how does the implementation actually prove that the new states is still referring to the old contract?

open class ObligationContractV2 : UpgradedContractWithLegacyConstraint {

    override val legacyContract: ContractClassName = ObligationContractV1.id

    override val legacyContractConstraint: AttachmentConstraint = AlwaysAcceptAttachmentConstraint

    override fun upgrade(oldState: ObligationStateV1) = ObligationContractV2.ObligationStateV2(oldState.a, oldState.b, 0)

    data class ObligationStateV2(val a: AbstractParty, val b: AbstractParty, val value:Int ) : ContractState {
        override val participants get() = listOf(a, b)
    }

    override fun verify(tx: LedgerTransaction) {}
}

Upvotes: 0

Views: 108

Answers (1)

Joel
Joel

Reputation: 23210

The contract class must change whenever you upgrade a state, but the rules it imposes can remain the same.

You could achieve this by delegating the transaction checking to the old contract:

override fun verify(tx: LedgerTransaction) {
    ObligationContractV1().verify()
}

You could also delegate the checking to the old contract, and adding additional checks:

override fun verify(tx: LedgerTransaction) {
    ObligationContractV1().verify()
    additionalChecks()
}

However, note that delegating verify in this way while upgrading states will only work if the original contract isn't hardcoded to verify the transaction in terms of the old state. You'd have to write the original contract in terms of some interface or abstract class implemented by both the old state class and the new state class, or in some other way write the old contract in an open-ended manner. If you didn’t write the old contract in this forward-thinking way initially, you'll have to re-write the verify method.

Upvotes: 1

Related Questions