Background
In the Anoma Resource Machine (ARM), a resource kind is derived from the resource logic verifying key and the resource label.
resource_kind = H(logic_vk || resource_label)
This property is desirable because it cryptographically commits every resource to the exact logic that governs it. Resource kinds are immutable, and historical resources remain verifiable forever.
However, this also makes application upgrades difficult. Any modification to the resource logic produces a new verifying key, resulting in a new resource kind. Consequently, existing resources cannot be directly balanced against resources created by the new logic.
Instead of introducing mutable logic registries or application-specific migration circuits, we can adapt Namada’s conversion circuit mechanism to support resource-kind conversions.
The key idea is that a logic upgrade is simply an authorized equivalence between two resource kinds.
Unlike migration circuits, the conversion circuit never consumes resources or creates resources. It only contributes an additional balancing term to the transaction.
Logic Conversion Tree
Introduce a global Logic Conversion Tree, analogous to Namada’s Conversion Tree.
Each leaf contains an authorized conversion pair:
(old_resource_kind, new_resource_kind)
For example:
(KindV1, KindV2)
(KindV2, KindV3)
(KindA, KindB)
Every conversion is implicitly 1:1.
Registering a conversion pair indicates that resources of the two kinds are considered equivalent for balancing purposes.
How conversion pairs are registered is intentionally orthogonal to this proposal. They may be authorized by application governance, multisig approval, protocol governance, or any other mechanism.
Once registered, every user may utilize the conversion permissionlessly.
Generic Conversion Circuit
ARM provides a single generic conversion circuit.
The circuit receives as public inputs:
- the Logic Conversion Tree root,
- the conversion commitment.
The circuit receives as private witness:
- the old resource kind,
- the new resource kind,
- the converted quantity,
- a Merkle proof against the above root,
- a random blinding factor.
The circuit proves:
- the Merkle proof is valid against the declared tree root;
- the conversion pair exists at the proven leaf;
- the conversion ratio is 1:1;
- the conversion commitment is correctly formed from the witness.
The tree root is committed on-chain at each block. A transaction proof must reference a root that the protocol considers current or within an acceptable anchor window. Proofs against stale roots are rejected.
Importantly, the circuit never verifies resource logic, consumes resources, or creates resources.
Its sole purpose is to prove membership in the authorised conversion set and produce a well-formed balancing commitment.
Conversion Commitment
Rather than revealing the conversion publicly, the circuit outputs a commitment:
C = Commit(
old_kind,
new_kind,
quantity,
randomness
)
The commitment is both binding and hiding. Only the commitment is revealed; the following remain private:
- the source resource kind,
- the destination resource kind,
- the converted quantity,
- the randomness.
To external observers, every conversion commitment appears as a random group element.
Transaction Balancing
Suppose a transaction consumes a resource of KindV1 with quantity q and creates a resource of KindV2 with the same quantity. Without a conversion proof, the balancing equation fails because the resource kinds differ.
The conversion circuit contributes a hidden balancing term:
Commit(KindV1, KindV2, q, r)
The transaction proof then demonstrates:
Inputs − Outputs + ConversionCommitments = 0
without revealing the underlying kinds or quantities.
Conceptually, the conversion commitment acts exactly like Namada’s conversion balance: it adjusts the balancing equation without touching any resources.
Composable Upgrades
Since conversion only affects balancing, upgrades compose naturally with arbitrary application logic.
For example:
Consume: OldToken
Create: NewToken, Payment, Change
Conversion: Commit(OldKind, NewKind, amount, r)
The conversion is invisible to the rest of the transaction. Applications do not require dedicated migration transactions; users simply spend old resources as usual and the balancing proof accounts for the version upgrade.
Sunset of Old Resource Kinds(optional)
Registering a conversion pair does not invalidate the old resource kind. Resources of KindV1 remain creatable under V1 logic indefinitely. This matters when a logic upgrade is motivated by a security fix: an attacker can still exploit the vulnerability in V1 to mint illegitimate resources and immediately convert them to KindV2, bypassing the fix entirely.
To close this gap, the conversion tree leaf may carry an optional sunset block height:
(old_kind, new_kind, sunset_height)
After sunset_height, the protocol refuses to consume or create resources of old_kind. The conversion circuit includes sunset_height in the leaf commitment, and the transaction proof checks that the current block is at or before the sunset.
This gives users a finite window to migrate their resources, after which the old logic is effectively retired by consensus rather than by logic modification.
Two approaches are worth considering:
Protocol-enforced sunset. The sunset height is committed in the conversion tree leaf and enforced by the balance circuit. This requires no change to existing resource logic but adds a protocol-level mechanism outside the conversion circuit itself.
Logic-gated sunset. The V1 logic itself gates spending on the absence of a registered conversion pair, or checks a block-height condition. This keeps enforcement inside resource logic but requires V1 to have been written with migration awareness.
For security-motivated upgrades, a protocol-enforced sunset is preferred because it does not depend on the old logic having been written correctly.
Privacy
Publishing conversion pairs directly would reveal which application is upgrading, which logic versions are involved, and how many resources were migrated.
Using commitments hides all of this. An observer cannot distinguish whether a conversion KindV1 → KindV2 or KindX → KindY was used, nor can they determine the quantity converted. This preserves ARM’s privacy guarantees even during application upgrades.
Homomorphic Construction
Ideally, the conversion commitment shares the same algebraic structure as the commitments already used in transaction balancing. A natural choice is:
ConversionCommitment = q · G(new_kind) − q · G(old_kind) + r · H
where G(kind) is a generator deterministically derived from the resource kind, H is the blinding generator, and r is fresh randomness.
The generic conversion circuit proves that the generators correspond to a registered conversion pair and that the commitment is correctly formed. Transaction balancing then reduces to simple group addition: the verifier observes only the final sum and a zero-knowledge proof, learning nothing about the resource kinds or quantity.
Advantages
Compared with application-specific migration circuits, this approach has several advantages.
Generic
A single conversion circuit supports every application.
Immutable Logic
Resource kinds remain cryptographically bound to immutable verification keys.
Permissionless
Once a conversion pair is registered, every user can upgrade resources without requiring application-specific circuits.
Private
Neither the converted resource kinds nor the migrated quantity are revealed.
Composable
Conversions participate only in balancing, so they compose naturally with arbitrary resource operations.
Protocol Minimality
No mutable logic registry, version identifiers, or upgrade mechanisms are introduced into ARM itself.
The only additional component is a conversion tree and a reusable conversion circuit.
Open Questions
Several design questions remain open.
Registration Policy
Who may register conversion pairs? Possible choices include:
- application governance,
- protocol governance,
- multisignature approval,
- cryptographic authorization from both logic versions.
This proposal intentionally separates authorization from the conversion mechanism itself.
Resource Equivalence
A registered conversion asserts that two resource kinds represent equivalent resources. How this equivalence is established is outside the scope of the conversion circuit. The registration authority is responsible for ensuring that the upgraded logic preserves the intended semantics.
Sunset Policy
If a sunset height is included in the leaf, who chooses it and can it be extended? Extending a sunset requires updating the tree (and the root), which may invalidate in-flight proofs. A conservative default is to make sunset heights immutable once registered and to require a new conversion pair registration if an extension is needed.
Conversion Ratios
This proposal assumes all logic upgrades are 1:1 conversions. Future extensions could support more general ratios, although these are unlikely to be necessary for logic upgrades.
Conclusion
This proposal adapts Namada’s conversion-circuit design from asset conversions to logic upgrades.
Instead of treating a logic upgrade as a resource transformation, it is modeled as an additional balancing relation between two resource kinds.
A global Logic Conversion Tree authorizes valid conversions, while a single generic conversion circuit proves membership in that tree and produces a private conversion commitment. The commitment participates in transaction balancing without revealing the resource kinds or quantities involved.
The result is a generic, composable, and privacy-preserving upgrade mechanism that preserves ARM’s fundamental property that every resource kind is permanently bound to an immutable resource logic.