You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: generalize tx.op to method discriminator in ICRC-3
Replace hardcoded references to `tx.op` with the concept of a "method
discriminator" — a field whose namespaced value uniquely identifies
the standardized method that created a block. The recommended field
name remains `op`, but standards MAY use alternatives (e.g., `mthd`)
provided the choice is documented in the canonical `tx` mapping.
This accommodates ICRC-107 which uses `tx.mthd` rather than `tx.op`
as its method discriminator field, while preserving backward
compatibility with legacy ICRC-1/2 blocks that use `tx.op`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: standards/ICRC-3/README.md
+26-25Lines changed: 26 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -259,11 +259,11 @@ Not all blocks contain a `tx` field, and not all blocks with a `tx` field corres
259
259
For any ICRC standard that defines a **user-callable method which produces blocks**:
260
260
261
261
- Blocks produced by that method SHOULD include a `tx` field.
262
-
- The `tx` field for such blocks SHOULD include an operation discriminator`op`.
263
-
- The `op` value SHOULD be namespaced with the standard’s ICRC number
262
+
- The `tx` field for such blocks SHOULD include a **method discriminator** — a field whose namespaced value uniquely identifies the standardized method that created the block. The recommended field name is `op`, but standards MAY use an alternative (e.g., `mthd`) provided the choice is documented in the method’s canonical `tx` mapping.
263
+
- The discriminator value SHOULD be namespaced with the standard’s ICRC number
264
264
(e.g., `122freeze_account`, `107set_fee_collector`) to avoid collisions with operations defined by other standards.
265
265
266
-
Typed blocks that **do not** represent method calls (e.g., upgrade markers, maintenance events, migration records, or system actions) MAY omit the `tx` field entirely and therefore MAY omit `tx.op`.
266
+
Typed blocks that **do not** represent method calls (e.g., upgrade markers, maintenance events, migration records, or system actions) MAY omit the `tx` field entirely and therefore MAY omit the method discriminator.
267
267
268
268
Legacy ICRC-1/2 blocks continue to use their historical operation names (`"xfer"`, `"mint"`, `"burn"`, `"approve"`), and are exempt from namespacing requirements.
269
269
@@ -273,7 +273,7 @@ Legacy ICRC-1/2 blocks continue to use their historical operation names (`"xfer"
273
273
If a block represents the result of a **standardized user-initiated method call**, then:
274
274
275
275
- The block **SHOULD** include a `tx` field.
276
-
- For user-initiated blocks, a namespaced `tx.op`**SHOULD** be included (see above).
276
+
- For user-initiated blocks, a namespaced method discriminator**SHOULD** be included (see above).
277
277
- The `tx` field MUST follow the canonical mapping defined by the method standard.
278
278
Semantic fields required by the block type may appear **outside**`tx` when defined
279
279
as top-level fields by the block-type specification (e.g., `fee`, `caller`).
@@ -283,12 +283,12 @@ If a block represents the result of a **standardized user-initiated method call*
283
283
However:
284
284
285
285
- Blocks that are **not** created by user calls — such as system-generated blocks, upgrade or migration markers, or internal bookkeeping events — MAY omit the `tx` field entirely.
286
-
- Typed blocks created by system logic MAY include a `tx` field without an `op`, or MAY use a `tx` whose structure is defined solely by the block type (`btype`) specification.
286
+
- Typed blocks created by system logic MAY include a `tx` field without a method discriminator, or MAY use a `tx` whose structure is defined solely by the block type (`btype`) specification.
287
287
288
288
This distinction allows ICRC-3 to support both:
289
289
- canonical, audit-ready records of user calls, and
290
290
- domain-specific or system-generated events,
291
-
without over-constraining block structure or requiring the presence of `tx` or `tx.op` in every block.
291
+
without over-constraining block structure or requiring the presence of `tx` or a method discriminator in every block.
292
292
293
293
294
294
### 5. Future-Proofing and Extensibility
@@ -567,13 +567,13 @@ A standard that defines a new block type MUST:
567
567
-**Assign a unique `btype` string** for that block type.
568
568
This identifier determines how the block is interpreted.
569
569
570
-
-**Not define or constrain `tx.op`**, because:
571
-
-`tx.op` belongs to the standard that defines the *method* which creates the
570
+
-**Not define or constrain the method discriminator** (e.g., `tx.op`, `tx.mthd`), because:
571
+
-The method discriminator belongs to the standard that defines the *method* which creates the
572
572
block, not to the block-type standard.
573
573
- A single block type may be produced by multiple methods, potentially from
574
574
different standards.
575
575
- Some blocks (e.g., system-generated events or migration markers) do not
576
-
include `tx.op` at all.
576
+
include a method discriminator at all.
577
577
578
578
-**Specify the minimal structure** required to interpret the block and recover its
579
579
semantic meaning.
@@ -622,10 +622,11 @@ A standard that defines a method which produces blocks MUST:
622
622
populated, whether they live inside `tx` or at the top level.
623
623
- Include only caller-provided optional fields in `tx`; omit optionals that were
624
624
not supplied.
625
-
- For methods that represent user-initiated calls, include an `op` field in
625
+
- For methods that represent user-initiated calls, include a **method discriminator** field in
626
626
`tx` (namespaced as described below) to identify the operation and avoid
627
-
collisions.
628
-
- Ensure that a namespaced `tx.op`**uniquely identifies the standardized
627
+
collisions. The recommended field name is `op`, but standards MAY use an
628
+
alternative (e.g., `mthd`) provided the choice is documented in the canonical `tx` mapping.
629
+
- Ensure that the namespaced discriminator value **uniquely identifies the standardized
629
630
method** that created the block within the ICRC namespace.
630
631
631
632
This division of responsibility ensures that:
@@ -634,37 +635,37 @@ This division of responsibility ensures that:
634
635
- Methods define **how blocks are created** (intent capture).
635
636
- Tooling and clients can rely on predictable, non-colliding `tx` values.
636
637
637
-
#### Namespacing for Operations
638
+
#### Namespacing for Method Discriminators
638
639
639
640
The namespacing rules apply to **standards that define user-callable methods**, not to the
640
641
standards that define block types.
641
642
642
-
If a standard defines a method that produces blocks, and those blocks include a `tx.op`,
643
-
then:
643
+
If a standard defines a method that produces blocks, and those blocks include a method
644
+
discriminator in `tx` (whether named `op`, `mthd`, or otherwise), then:
644
645
645
-
-`tx.op` MUST be namespaced using the ICRC number of the **method’s standard**, not the
646
+
-The discriminator value MUST be namespaced using the ICRC number of the **method’s standard**, not the
646
647
block-type standard.
647
-
- The value of `op` MUST uniquely identify the standardized method that created the
648
+
- The discriminator value MUST uniquely identify the standardized method that created the
648
649
block within the global ICRC namespace.
649
650
650
-
Formally:
651
+
Formally, the discriminator value follows this grammar:
651
652
652
-
-`op = <method_standard_number><operation_name>`
653
-
-`method_standard_number`: a non-zero digit followed by zero or more digits
0 commit comments