Skip to content
This repository was archived by the owner on Jul 10, 2026. It is now read-only.

Commit eea278c

Browse files
committed
feat: add docs
1 parent 54396ae commit eea278c

1 file changed

Lines changed: 88 additions & 1 deletion

File tree

src/multitoken_contract/README.md

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,90 @@
11
# MultiToken Contract
22

3-
Initial scaffolding for the `MultiToken` contract. It currently exposes only an empty public initializer (`constructor`) and is intended as the starting point for further development.
3+
The `MultiToken` contract implements an ERC-1155-like multi-token with Aztec-specific privacy extensions. A single contract holds many fungible token ids, each with its own independent balance, and every balance can live in either a private or a public domain with seamless moves between the two.
4+
5+
Compared to the single-asset [`Token`](../token_contract/README.md), every balance-changing function takes an extra `id: Field` selecting the token, there is no `decimals` and no `total_supply`, and the on-chain event is `TransferSingle` (ERC-1155 naming) instead of `Transfer`.
6+
7+
## ARC-403: Authorization Hook
8+
9+
Like `Token`, this contract implements the optional ARC-403 authorization hook: when an `auth_contract` is configured, every transfer and burn calls it before mutating balances, and the operation reverts if the hook reverts. If `auth_contract` is the zero address, the hook is disabled and the token behaves as a plain multi-token. The interface is **id-bearing** — the hook receives the token id so policies can differ per id:
10+
11+
- `authorize_private(from, id, amount, selector)` — called by private-context functions.
12+
- `authorize_public(from, id, amount, selector)` — called by public-context functions.
13+
14+
| Function | Hook called |
15+
|----------|-------------|
16+
| `transfer_private_to_private` | `authorize_private` |
17+
| `transfer_private_to_public` | `authorize_private` |
18+
| `transfer_private_to_commitment` | `authorize_private` |
19+
| `transfer_public_to_private` | `authorize_private` |
20+
| `transfer_public_to_public` | `authorize_public` |
21+
| `transfer_public_to_commitment` | `authorize_public` |
22+
| `burn_private` | `authorize_private` |
23+
| `burn_public` | `authorize_public` |
24+
25+
Mints (`mint_to_private`, `mint_to_public`, `mint_to_commitment`) are **not** hooked — minting is already gated by the `minter` address set at construction.
26+
27+
## TransferSingle Events
28+
29+
A public `TransferSingle { from, to, id, amount }` event is emitted only on operations whose token id is already revealed on-chain (any public-balance write or commitment completion). Fully-private operations emit nothing, since an id-bearing event would leak the token id.
30+
31+
| Operation | Event Pattern |
32+
|-----------|---------------|
33+
| Mint to public | `TransferSingle(0x0, recipient, id, amount)` |
34+
| Mint to commitment | `TransferSingle(0x0, PRIVATE_ADDRESS, id, amount)` |
35+
| Burn from public | `TransferSingle(from, 0x0, id, amount)` |
36+
| Public-to-public | `TransferSingle(from, to, id, amount)` |
37+
| Public-to-commitment | `TransferSingle(from, PRIVATE_ADDRESS, id, amount)` |
38+
| Public-to-private | `TransferSingle(from, PRIVATE_ADDRESS, id, amount)` |
39+
| Private-to-public | `TransferSingle(PRIVATE_ADDRESS, to, id, amount)` |
40+
| Mint to private / Burn from private | _(no public events)_ |
41+
| Private-to-private / Private-to-commitment | _(no public events)_ |
42+
43+
**Sentinel values:** `0x0` denotes mint origin (`from`) or burn destination (`to`), following ERC-1155. `PRIVATE_ADDRESS` (sha224 of `"PRIVATE_ADDRESS"`) denotes the private side of a balance change when the counterpart cannot be revealed.
44+
45+
## Storage Fields
46+
47+
- `name: FieldCompressedString`: Token collection name (compressed).
48+
- `symbol: FieldCompressedString`: Token collection symbol (compressed).
49+
- `private_balances: Owned<MultiBalanceSet>`: A single private note set. Each `MultiTokenNote` self-describes its token id; per-owner scoping is `private_balances.at(owner)`, and per-id operations select notes where `token_id == id`.
50+
- `public_balances: Map<Field, Map<AztecAddress, u128>>`: Public balances keyed by token id, then owner.
51+
- `minter: AztecAddress`: Account permitted to mint any token id.
52+
- `auth_contract: AztecAddress`: ARC-403 authorization contract address (zero address disables the hook).
53+
54+
## Function Reference
55+
56+
All addresses are `AztecAddress`; `id` is a `Field`, `amount` is a `u128`, and `nonce` (used for authwit) is a `Field`.
57+
58+
### Initializer
59+
60+
- `constructor_with_minter(name: FieldCompressedString, symbol: FieldCompressedString, minter, auth_contract)` — Initializes the multi-token with a minter and an optional ARC-403 auth contract.
61+
62+
### Private Functions
63+
64+
- `transfer_private_to_private(from, to, id, amount, nonce)` — Moves `amount` of `id` between private balances. Fully private (no event, no public effect).
65+
- `transfer_private_to_public(from, to, id, amount, nonce)` — Spends private notes and enqueues a public credit to `to`.
66+
- `transfer_private_to_commitment(from, id, commitment, amount, nonce)` — Spends private notes and completes an already-initialized commitment with `(id, amount)`.
67+
- `transfer_public_to_private(from, to, id, amount, nonce)` — Enqueues a public debit of `from` and emits a private note to `to`.
68+
- `initialize_transfer_commitment(to, completer) -> Field` — Creates a partial note (privacy entrance) to be completed by later transfers/mints. Id-agnostic: the completer binds `id` and `amount`.
69+
- `mint_to_private(to, id, amount)` — Minter mints `id` into a private balance. Fully private.
70+
- `burn_private(from, id, amount, nonce)` — Burns `id` from a private balance. Fully private.
71+
72+
### Public Functions
73+
74+
- `transfer_public_to_public(from, to, id, amount, nonce)` — Moves `amount` of `id` between public balances.
75+
- `transfer_public_to_commitment(from, id, commitment, amount, nonce)` — Debits `from`'s public balance and completes a commitment prepared by `initialize_transfer_commitment`.
76+
- `mint_to_public(to, id, amount)` — Minter mints `id` into a public balance.
77+
- `mint_to_commitment(id, commitment, amount)` — Minter finalizes a mint into a commitment.
78+
- `burn_public(from, id, amount, nonce)` — Burns `id` from a public balance.
79+
80+
### View Functions
81+
82+
- `balance_of_public(owner, id) -> u128` — Public balance of `owner` for `id`.
83+
- `name() -> FieldCompressedString` — Token collection name.
84+
- `symbol() -> FieldCompressedString` — Token collection symbol.
85+
- `get_minter() -> AztecAddress` — Authorized minter address.
86+
- `get_auth_contract() -> AztecAddress` — ARC-403 auth contract address (zero if disabled).
87+
88+
### Utility Functions
89+
90+
- `balance_of_private(owner, id) -> u128` — Off-chain helper that pages through the owner's notes filtered by `id` and sums their values. No on-chain or proving cost, and no fixed cap.

0 commit comments

Comments
 (0)