-
Notifications
You must be signed in to change notification settings - Fork 7
ICRC-122: ledger blocks recording management actions -- authorised mint, authorised burn blocks #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
bogwar
wants to merge
24
commits into
main
Choose a base branch
from
bw/icrc-122
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
ICRC-122: ledger blocks recording management actions -- authorised mint, authorised burn blocks #125
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
bae8b8f
initial dir and md file
bogwar e2c022d
first draft
bogwar 8d2e3be
added a mint block, added example blocks
bogwar 4fa7042
restructuring
bogwar 7b7a180
removed some unncessary stuff
bogwar ff19295
fixed the urls
bogwar daf5a77
fixed some blobs
bogwar 97744ab
Revert "fixed some blobs"
bogwar 89eba86
Revert "fixed the urls"
bogwar 3e15786
addex a tx structure in the block
bogwar 9fcf09e
appended -> recorded
bogwar a7c66d9
fixed conflicts
bogwar c05a1b6
cleaned the examples
bogwar aa9e592
refined explanations
bogwar 104a2f3
small fix
bogwar 7ca3a59
Update ICRCs/ICRC-122/ICRC-122.md
bogwar 5ae6ffe
Update ICRCs/ICRC-122/ICRC-122.md
bogwar 925597f
Update ICRCs/ICRC-122/ICRC-122.md
bogwar fa7ca98
implemented Thomas' suggestions; alignment with the ICRC-107 structure
bogwar 2e80b70
alignment with new icrc-3 guideliness
bogwar a22efd8
Merge branch 'bw/icrc-122' of github.com:dfinity/ICRC into bw/icrc-122
bogwar 8f3fb0b
dedup information in blocks
bogwar f46e7bd
added interaction with other standards section
bogwar 3a39cbb
clarify it's blocks that are being standardised
bogwar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| # ICRC-122: Token Burning & Minting Blocks | ||
|
|
||
| ICRC-122 introduces new block types for recording token minting and burning events in ICRC-compliant ledgers. These blocks provide a standardized way to document authorized supply modifications, ensuring transparent tracking of token issuance and removal. The `122burn` block records token reductions, while the `122mint` block tracks token increases. | ||
|
|
||
| ## Common Elements | ||
| This standard follows the conventions set by ICRC-3, inheriting key structural components. | ||
| - **Accounts** are represented using the ICRC-3 `Value` type, specifically as a `variant { Array = vec { V1 [, V2] } }` where `V1` is `variant { Blob = <owner_principal> }` representing the account owner, and `V2` is `variant { Blob = <subaccount> }` representing the subaccount. If no subaccount is specified, the `Array` MUST contain only one element (`V1`, the owner's principal). | ||
| - **Principals** (such as the `caller`) are represented using the ICRC-3 `Value` type as `variant { Blob = <principal_bytes> }`. | ||
| - Each block includes `phash`, a `Blob` representing the hash of the parent block, and `ts`, a `Nat` representing the timestamp of the block. | ||
|
|
||
| ## Block Types & Schema | ||
|
|
||
| Each block introduced by this standard MUST include a `tx` field containing a map. This map encodes information about the mint or burn operation sufficient to compute balances. Additional provenance data MAY be included but is not required for semantics. | ||
|
|
||
|
|
||
| Each `122burn` or `122mint` block consists of the following top-level fields: | ||
|
|
||
| | Field | Type (ICRC-3 `Value`) | Required | Description | | ||
| |----------|------------------------|----------|-------------| | ||
| | `btype` | `Text` | Yes | MUST be one of: `"122burn"` or `"122mint"`. | | ||
| | `ts` | `Nat` | Yes | Timestamp (in nanoseconds since the Unix epoch) when the block was added to the ledger. | | ||
| | `phash` | `Blob` | Yes | Hash of the parent block. | | ||
| | `tx` | `Map(Text, Value)` | Yes | Encodes information about the token mint or burn transaction sufficient to compute balances. See schemas below. | | ||
|
|
||
| ### `tx` Field Schemas | ||
|
|
||
| #### For `122burn` | ||
|
|
||
| | Field | Type (ICRC-3 `Value`) | Required | Description | | ||
| |--------------|--------------------------------------------------------------|----------|-------------| | ||
| | `from` | `Value` (Must be `variant { Array = vec { V1 [, V2] } }`)¹ | Yes | The account from which tokens are burned. | | ||
| | `amt` | `Nat` | Yes | The number of tokens to burn. This value **MUST be greater than 0**. | | ||
|
|
||
|
|
||
| #### For `122mint` | ||
|
|
||
| | Field | Type (ICRC-3 `Value`) | Required | Description | | ||
| |--------------|--------------------------------------------------------------|----------|-------------| | ||
| | `to` | `Value` (Must be `variant { Array = vec { V1 [, V2] } }`)¹ | Yes | The account to which tokens are minted. | | ||
| | `amt` | `Nat` | Yes | The number of tokens to mint. This value **MUST be greater than 0**. | | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Comparison with ICRC-1 Mint/Burn | ||
|
|
||
| The `122mint` and `122burn` blocks introduced in ICRC-122 provide a more explicit and structured mechanism for tracking token supply changes compared to how these operations are represented under ICRC-1. A ledger that supports both ICRC-1 and ICRC-122 may therefore produce blocks of both kinds, reflecting distinct ways of invoking supply modifications. | ||
|
|
||
| - **ICRC-1 Mint/Burn Mechanism**: | ||
| - *Operation & Block Type*: ICRC-1 defines a `minting_account`. Minting is achieved by an `icrc1_transfer` from this account to a recipient, increasing total supply. Burning is an `icrc1_transfer` to the `minting_account`, reducing supply. ICRC-3-compliant ledgers typically encode these as legacy blocks with `op = "mint"` or `op = "burn"`. | ||
| - *Authorization*: Control of the `minting_account` implies authority to mint. Only the principal able to submit `icrc1_transfer` calls from this account can change supply. | ||
| - *Contextual Data*: These legacy blocks do not have a dedicated field for the supply change rationale; any context must be encoded in the generic `memo`. They also do not explicitly identify the ultimate caller beyond the fact that the `from` account was the `minting_account`. | ||
|
|
||
| - **ICRC-122 Mint/Burn Blocks**: | ||
| - *Typed Blocks*: This standard defines distinct block types, `122mint` and `122burn`. They are not special cases of `icrc1_transfer`; they represent supply changes directly. | ||
| - *Minimal Structure*: The minimal `tx` structure contains only the target account (`to` for mint, `from` for burn) and the amount (`amt`). These fields are sufficient to determine the ledger’s state transition. | ||
| - *Optional Provenance*: Producers may include additional non-semantic fields in `tx` such as `caller` (the principal that invoked the supply change), `reason` (a human-readable string), or `created_at_time`. These fields aid transparency and auditability but do not affect ledger semantics. | ||
| - *Auditability*: By separating the minimal state-changing fields from optional provenance, ICRC-122 ensures clear semantics while still supporting enhanced transparency compared to the ICRC-1 mechanism. | ||
|
|
||
| ### Guidance for Standards That Define Methods | ||
|
|
||
| ICRC-122 itself defines only block types (`122mint`, `122burn`) and their semantics. | ||
| It does not define ledger methods. However, other standards may define methods that | ||
| directly produce ICRC-122 blocks. | ||
|
|
||
| Such standards SHOULD: | ||
|
|
||
| 1. **Include `tx.op`** in the resulting block’s `tx` map. | ||
| - Use a namespaced value as recommended in ICRC-3: `<icrc_number><op_name>`. | ||
| - Examples: `145mint`, `145burn` if defined in ICRC-145. | ||
| - This **prevents collisions** between blocks created by different methods or standards; it does *not* uniquely identify an individual call. | ||
|
|
||
| 2. **Define a canonical mapping** from method arguments to the minimal `tx` fields: | ||
| - `icrcX_mint` → `tx.to`, `tx.amt`. | ||
| - `icrcX_burn` → `tx.from`, `tx.amt`. | ||
| - Optional provenance (`caller`, `reason`, `created_at_time`) MAY be included but MUST NOT affect semantics. | ||
|
|
||
| 3. **Document deduplication inputs** (if any). If a method accepts a caller-supplied timestamp, | ||
| it SHOULD be recorded in `tx.created_at_time` (nanoseconds, MUST fit into `nat64`). | ||
|
|
||
| This guidance ensures that when future standards define mint/burn methods, they can be | ||
| reliably mapped into ICRC-122 block types while remaining compatible with ICRC-3 rules | ||
| for canonical `tx` mappings and optional provenance. | ||
|
|
||
|
|
||
|
|
||
| ## Compliance Reporting | ||
|
|
||
| Ledgers implementing this standard MUST return the following response to `icrc3_supported_block_types` with a URL pointing to the standard defining each block type: | ||
|
|
||
| ```candid | ||
| vec { | ||
| variant { Record = vec { | ||
| record { "btype"; variant { Text = "122burn" }}; | ||
| record { "url"; variant { Text = "https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-122.md" }}; // Placeholder URL | ||
| }}; | ||
| variant { Record = vec { | ||
| record { "btype"; variant { Text = "122mint" }}; | ||
| record { "url"; variant { Text = "https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-122.md" }}; // Placeholder URL | ||
| }}; | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| ## Example Blocks | ||
|
|
||
| The following examples illustrate how `122burn` and `122mint` blocks are encoded on-chain. | ||
| Each operation is shown in two forms: | ||
|
|
||
| - **Minimal form**, which includes only the required fields needed to define the state change. | ||
| - **Extended form**, which demonstrates how optional provenance fields such as `caller`, `reason`, or `created_at_time` may be included to enhance transparency and auditability. | ||
|
|
||
| These examples are intended to guide implementers and tool builders in interpreting both the essential and optional elements of ICRC-122 blocks. | ||
|
|
||
|
|
||
| ### 122burn Example | ||
|
|
||
| ### 122burn (Minimal Example) | ||
| The following block shows the minimal `122burn` structure with only the required `from` and `amt` fields inside the `tx` map. | ||
|
|
||
|
|
||
|
|
||
| ``` | ||
| variant { Map = vec { | ||
| record { "btype"; variant { Text = "122burn" }}; | ||
| record { "ts"; variant { Nat = 1_741_317_147_000_000_000 : nat }}; | ||
| record { "phash"; variant { Blob = blob "\6f\7e\d9\13\75\69\91\bc\d0\0d\04\b6\60\7b\82\f9\e9\62\a8\39\d3\02\80\f2\88\e4\d7\0e\23\2d\29\87" }}; | ||
| record { "tx"; variant { Map = vec { | ||
| record { "from"; variant { Array = vec { | ||
| variant { Blob = blob "\00\00\00\00\02\00\01\0d\01\01" }; | ||
| variant { Blob = blob "\06\ec\cd\3a\97\fb\a8\5f\bc\8d\a3\3e\5d\ba\bc\2f\38\69\60\5d\c7\a1\c9\53\1f\70\a3\66\c5\a7\e4\21" }; | ||
| }}}; | ||
| record { "amt"; variant { Nat = 1_000_000 : nat }}; | ||
| }}}; | ||
| }} | ||
| ``` | ||
|
|
||
|
|
||
| ### 122burn (Extended Example with Provenance and Deduplication Information) | ||
| This block demonstrates an extended `122burn` including optional provenance and deduplication information fields (`caller`, `reason`, `created_at_time`) alongside the required fields. These additions provide auditability and deduplication functionality without altering semantics. | ||
|
|
||
|
|
||
|
|
||
| ``` | ||
| variant { Map = vec { | ||
| record { "btype"; variant { Text = "122burn" }}; | ||
| record { "ts"; variant { Nat = 1_741_317_147_000_000_000 : nat }}; | ||
| record { "phash"; variant { Blob = blob "\6f\7e\d9\13\75\69\91\bc\d0\0d\04\b6\60\7b\82\f9\e9\62\a8\39\d3\02\80\f2\88\e4\d7\0e\23\2d\29\87" }}; | ||
| record { "tx"; variant { Map = vec { | ||
| record { "from"; variant { Array = vec { | ||
| variant { Blob = blob "\00\00\00\00\02\00\01\0d\01\01" }; | ||
| variant { Blob = blob "\06\ec\cd\3a\97\fb\a8\5f\bc\8d\a3\3e\5d\ba\bc\2f\38\69\60\5d\c7\a1\c9\53\1f\70\a3\66\c5\a7\e4\21" }; | ||
| }}}; | ||
| record { "amt"; variant { Nat = 1_000_000 : nat }}; | ||
| record { "caller"; variant { Blob = blob "\00\00\00\00\00\00\00\00\01\01" }}; | ||
| record { "reason"; variant { Text = "Token supply adjustment" }}; | ||
| record { "created_at_time"; variant { Nat = 1_741_317_146_900_000_000 : nat }}; | ||
| }}}; | ||
| }} | ||
| ``` | ||
|
|
||
| ### 122mint (Minimal Example) | ||
| The following block shows the minimal `122mint` structure with only the required `to` and `amt` fields inside the `tx` map. | ||
|
|
||
|
|
||
| ``` | ||
| variant { Map = vec { | ||
| record { "btype"; variant { Text = "122mint" }}; | ||
| record { "ts"; variant { Nat = 1_741_317_147_000_000_000 : nat }}; | ||
| record { "phash"; variant { Blob = blob "\7a\61\cf\18\a4\9d\ac\20\39\33\78\f1\c2\fd\45\81\ab\55\37\20\1d\fe\77\a3\c6\55\de\01\92\a4\3b\ee" }}; | ||
| record { "tx"; variant { Map = vec { | ||
| record { "to"; variant { Array = vec { | ||
| variant { Blob = blob "\00\00\00\00\02\00\01\0d\01\01" }; | ||
| variant { Blob = blob "\06\ec\cd\3a\97\fb\a8\5f\bc\8d\a3\3e\5d\ba\bc\2f\38\69\60\5d\c7\a1\c9\53\1f\70\a3\66\c5\a7\e4\21" }; | ||
| }}}; | ||
| record { "amt"; variant { Nat = 2_000_000 : nat }}; | ||
| }}}; | ||
| }} | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### 122mint (Extended Example with Provenance and Deduplication Information) | ||
| This block demonstrates an extended `122mint` including optional provenance and deduplication fields (`caller`, `reason`, `created_at_time`) alongside the required fields. These additions provide auditability and deduplication functionality without altering semantics. | ||
|
|
||
|
|
||
| ``` | ||
| variant { Map = vec { | ||
| record { "btype"; variant { Text = "122mint" }}; | ||
| record { "ts"; variant { Nat = 1_741_317_147_000_000_000 : nat }}; | ||
| record { "phash"; variant { Blob = blob "\7a\61\cf\18\a4\9d\ac\20\39\33\78\f1\c2\fd\45\81\ab\55\37\20\1d\fe\77\a3\c6\55\de\01\92\a4\3b\ee" }}; | ||
| record { "tx"; variant { Map = vec { | ||
| record { "to"; variant { Array = vec { | ||
| variant { Blob = blob "\00\00\00\00\02\00\01\0d\01\01" }; | ||
| variant { Blob = blob "\06\ec\cd\3a\97\fb\a8\5f\bc\8d\a3\3e\5d\ba\bc\2f\38\69\60\5d\c7\a1\c9\53\1f\70\a3\66\c5\a7\e4\21" }; | ||
| }}}; | ||
| record { "amt"; variant { Nat = 2_000_000 : nat }}; | ||
| record { "caller"; variant { Blob = blob "\00\00\00\00\00\00\00\00\01\01" }}; | ||
| record { "reason"; variant { Text = "Initial distribution" }}; | ||
| record { "created_at_time"; variant { Nat = 1_741_317_146_900_000_000 : nat }}; | ||
| }}}; | ||
| }} | ||
| ``` | ||
|
|
||
| ### Informative Example: Integration with a Standardized Method | ||
|
|
||
| ICRC-122 defines only block types (`122mint`, `122burn`) and their semantics. | ||
| It does not define ledger methods. However, future standards may specify methods | ||
| that directly produce these block types. | ||
|
|
||
| For illustration, suppose a future standard (e.g., ICRC-145) introduces the method: | ||
|
|
||
| ```icrc145_mint : (account, nat, opt text) -> result nat``` | ||
|
|
||
|
|
||
| Calling this method with a target account, an amount, and an optional reason could | ||
| produce a `122mint` block on-chain. A possible encoding is shown below: | ||
|
|
||
| ``` | ||
| variant { Map = vec { | ||
| record { "btype"; variant { Text = "122mint" }}; | ||
| record { "ts"; variant { Nat = 1_747_900_000_000_000_000 : nat }}; | ||
| record { "phash"; variant { Blob = blob "\aa\bb\cc\dd\ee\ff\00\11\22\33\44\55\66\77\88\99" }}; | ||
| record { "tx"; variant { Map = vec { | ||
| // Namespaced op from the method-defining standard (ICRC-145) | ||
| record { "op"; variant { Text = "145mint" }}; | ||
| // Optional provenance (non-semantic) | ||
| record { "caller"; variant { Blob = blob "\00\00\00\00\00\00\f0\0d\01\02" }}; | ||
| record { "to"; variant { Array = vec { | ||
| variant { Blob = blob "\00\00\00\00\02\00\01\0d\01\01" }; | ||
| variant { Blob = blob "\06\ec\cd\3a\97\fb\a8\5f\bc\8d\a3\3e\5d\ba\bc\2f\38\69\60\5d\c7\a1\c9\53\1f\70\a3\66\c5\a7\e4\21" }; | ||
| }}}; | ||
| record { "amt"; variant { Nat = 1_000_000 : nat }}; | ||
| record { "reason"; variant { Text = "Community treasury distribution" }}; | ||
| }}}; | ||
| }} | ||
| ``` | ||
|
|
||
| This example is non-normative and illustrates how a standardized method can map into | ||
| the ICRC-122 block structure while using a namespaced `tx.op` to prevent collisions | ||
| across standards. The authoritative semantics remain defined by the ICRC-122 block types. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.