Let $\t{PoseidonHash}$ be defined as in the section PoseidonHash Function.
This function transfers value by burning a set of coins $𝐂$, and minting a set of coins, such that the value spent and created are equal.
src/contract/money/src/client/transfer_v1/builder.rssrc/contract/money/src/client/transfer_v1/mod.rssrc/contract/money/src/client/transfer_v1/proof.rssrc/contract/money/src/entrypoint/transfer_v1.rssrc/contract/money/proof/burn_v1.zksrc/contract/money/proof/mint_v1.zkLet $\t{MoneyClearInput}, \t{MoneyInput}, \t{MoneyOutput}$ be defined as in Inputs and Outputs.
Define the Money transfer function params $$ \begin{aligned} 𝐣 &∈ \t{MoneyClearInput}^* \ 𝐢 &∈ \t{MoneyInput}^* \ 𝐨 &∈ \t{MoneyOutput}^* \end{aligned} $$
{{#include ../../../../../src/contract/money/src/model/mod.rs:money-params}}
Let $π\t{mint}, π\t{burn}$ be defined as in ZK Proofs.
Mint_V1Using the Mint_V1 circuit, we are able to create outputs
in our UTXO set. It is used along with the Burn_V1 circuit in
MoneyFunction::TransferV1 where we perform a payment to some address
on the network.
Denote this proof by $π_\t{mint}$.
Circuit witnesses:
Circuit public inputs:
Circuit:
$$ C = \text{PoseidonHash}(P, v, t, s, h, u) $$ $$ \text{RangeCheck}(64, v) $$ $$ V = vG + v{\text{blind}}H $$ $$ T = \text{PoseidonHash}(t, t{\text{blind}}) $$
$G$ and $H$ are constant well-known generators that are in the codebase
as VALUE_COMMIT_VALUE and VALUE_COMMIT_RANDOM:
src/sdk/src/crypto/constants/fixed_bases/value_commit_v.rssrc/sdk/src/crypto/constants/fixed_bases/value_commit_r.rsBurn_V1Using the Burn_V1 circuit, we are able to create inputs in
our UTXO set. It is used along with the Mint_V1 circuit in
MoneyFunction::TransferV1 where we perform a payment to some address
on the network.
Denote this proof by $π_\t{burn}$.
Circuit witnesses:
Circuit public inputs:
Circuit:
$$ N = \text{PoseidonHash}(x, s) $$ $$ V = vG + v{\text{blind}}H $$ $$ T = \text{PoseidonHash}(t, t{\text{blind}}) $$ $$ P = xK $$ $$ C = \text{PoseidonHash}(P, v, t, s, h, u) $$ $$ C' = \text{ZeroCond}(v, C) $$ $$ R = \text{MerkleRoot}(l, p, C') $$ $$ U = \text{PoseidonHash}(u, u_{\text{blind}}) $$ $$ Z = zK $$
$G$ and $H$ are the same generators used in Mint_V1, $K$ is the
generator in the codebase known as NULLIFIER_K:
src/sdk/src/crypto/constants/fixed_bases/nullifier_k.rsZeroCond is a conditional selection: f(a, b) = if a == 0 {a} else {b}.
We use this because the Merkle tree is instantiated with a fake coin of
value 0 and so we're able to produce dummy inputs of value 0.
Assuming a coin $C$ exists on the blockchain on leaf position $l$ and does not have a corresponding published nullifier $N$, it can be spent. To create the necessary proofs, Alice uses the known values of her coin $C$ and picks other values that are needed to create a new coin $C'$ that will be minted to Bob after $C$ is spent.
Values for Burn_V1:
Burn_V1 ZK proof using the existing known values
of her coin $C$ and the values picked above.Values for Mint_V1:
ZERO
if $h$ does not have to call another contract.ZERO
if no data has to be passed.Mint_V1 ZK proof using the existing known values
and the values picked above.After creating the proofs, Alice builds a transaction containing a
number of inputs that were created with Burn_V1 and a number of
outputs created with Mint_V1.
{{#include ../../../../../src/contract/money/src/model/mod.rs:money-params}}
This gets encoded into the Transaction format and the transaction is
signed with a Schnorr signature scheme using the $z$ secret key chosen
in Burn_V1.
For MoneyFunction::TransferV1, we have the following functions, in
order: