The Consensus::Unstake and Money::Unstake functions are used in
order to fully exit from the consensus participation and move back
the staked funds into the Money state.
The Unstake transaction consists of two contract calls, calling the above mentioned functions. The parameters, respectively, are:
{{#include ../../../../src/contract/money/src/model.rs:ConsensusUnstakeParams}}
{{#include ../../../../src/contract/money/src/model.rs:MoneyUnstakeParams}}
These two contract calls need to happen atomically, meaning they should
be part of a single transaction being executed on the network. On a
high level, what is happening in the unstake process is burning the
coin previously created through UnstakeRequest
in the Consensus state and minting a new coin in the Money state
where it can then again be used for other functionality outside
of consensus.
The contract calls execute in sequence:
Consensus::UnstakeMoney::UnstakeThe ZK proof we use to prove burning of the coin in Consensus is the
ConsensusBurn_V1 circuit:
{{#include ../../../../src/contract/consensus/proof/consensus_burn_v1.zk}}
The ZK proof we use to prove minting of the coin in Money is the
Mint_V1 circuit:
{{#include ../../../../src/contract/money/proof/mint_v1.zk}}
Consensus::get_metadata()In the consensus_unstake_get_metadata_v1 function, we gather the
public inputs necessary to verify the ConsensusBurn_V1 ZK proof,
and additionally the public key used to verify the transaction
signature. This pubkey is also derived and enforced in ZK.
Consensus::process_instruction()For the Consensus state transition, we use the
consensus_unstake_process_instruction_v1 function. We enforce that:
call_idx is a call to the Money::UnstakeV1 functionUnstakeRequest has expiredIf these checks pass, we create a state update with the revealed nullifier:
{{#include ../../../../src/contract/money/src/model.rs:ConsensusUnstakeUpdate}}
Consensus::process_update()For the Consensus state update, we use the
consensus_unstake_process_update_v1 function. This will simply
append the revealed nullifier to the existing set of nullifiers in
order to prevent double-spending.
After the Consensus::Unstake state transition has passed, we move on
to executing the Money::Unstake state transition. This is supposed
to mint the new coin in the Money state.
Money::get_metadata()In the money_unstake_get_metadata_v1 function, we gather the public
inputs necessary to verify the Mint_V1 ZK proof. It is not necessary
to grab any public keys for signature verification, as they're already
collected in Consensus::get_metadata().
Money::process_instruction()In the money_unstake_process_instruction_v1 function, we perform
the state transition. We enforce that:
call_idx is a call to the Consensus::UnstakeV1 functionIf these checks pass, we create a state update with the revealed minted coin:
{{#include ../../../../src/contract/money/src/model.rs:MoneyUnstakeUpdate}}
Money::process_update()In money_unstake_process_update_v1 we simply append the newly minted
coin to the set of seen coins in Money, and we add it to the Merkle
tree of coins in Money so further inclusion proofs can be validated.