As the ICRC-3 standard matures, it’s worth reconsidering some core design decisions — particularly how transaction blocks are structured. Two key issues have emerged that point to a lack of principled foundations in the current design and suggest that a revision is warranted.
Issue: Dual Formats for ICRC-1 and ICRC-2 Blocks
ICRC-3 currently allows two different formats for ICRC-1 and ICRC-2 transactions:
-
The legacy ICRC-1 format, where the transaction type is inferred from block content.
-
The ICRC-3 format, which wraps transaction details in a tx field and introduces an explicit btype.
This duality creates ambiguity. When a user submits a simple transfer, there’s no guarantee how it will be recorded on-chain. It could appear as a legacy-style block with no btype, or as a typed ICRC-3-style block. This inconsistency makes it harder to reason about transactions, compare behavior across ledgers, and build reliable tooling like explorers or indexers.
Some early ICRC-3 implementations have already diverged in how they log ICRC-1 transactions — creating incompatibilities between ledgers that all claim ICRC-3 support.
Issue: User Intent Is Not Isolated
In the current ICRC-3 design, the block format encodes user intent (e.g., “approve”, “transfer_from”) in the btype field, while spreading the rest of the transaction across other parts of the block.
This poses challenges for any tooling that tries to work directly with user intent:
-
A frontend cannot easily hash the user’s transaction to generate a transaction ID for later lookup.
-
A block explorer must reverse-engineer intent from multiple scattered fields.
-
Ledger implementers must guess which parts of a user’s request should be preserved and which are optional metadata.
These issues, too, stem from a lack of a principled and consistent mapping from user input to recorded transaction. Without a canonical definition — or at the very least, clear guidelines — for what gets logged in a block, we lack a foundation for interoperability, auditability, and reliable tooling.
Principles Behind the Proposed Revision
The revision to ICRC-3 is grounded in a small set of design principles meant to bring clarity, predictability, and interoperability to how ledgers record transactions.
Canonical Representation of User Intent
Each method that causes a ledger to record a block must specify how to construct a canonical tx object that captures the user’s request. Optional fields not supplied by the user are omitted. This tx becomes the definitive record of intent and the basis for deriving the transaction ID.
Deterministic Transaction Hashing
Transaction IDs are derived from hash(tx) using only the canonical tx field — not the full block. This enables clients and tools to compute transaction IDs independently and reliably.
Typed Blocks for New Semantics Only
The btype field is reserved for new kinds of transactions introduced in future standards. Each btype defines the minimum tx structure required to determine the ledger state effect. Existing ICRC-1 and ICRC-2 methods continue to use the legacy untyped format.
Separation of Semantics and Intent
The structure and semantics of a block (btype) are decoupled from the specific method call that generated it. This separation allows multiple methods or interfaces to share the same btype while still producing unique tx values based on user input.
Standardized Method-to-tx Mappings Going Forward
Standards that define methods which add blocks must specify how to construct the canonical tx from the call’s input. This mapping ensures predictability, avoids guesswork, and enables consistent tooling across the ecosystem.
Reusability via Shared Libraries
Because tx mappings are canonical and deterministic, shared libraries can be developed to construct tx objects uniformly across:
-
Clients, which need to precompute transaction hashes or prepare signed requests,
-
Ledgers, which must log the canonical tx in blocks.
This reduces duplication, improves correctness, and fosters interoperability throughout the stack.
Relationship Between btype and tx: Meaning vs. Intent
To support clarity and extensibility, the revised ICRC-3 architecture establishes a principled separation between the meaning of a block and the intent that produced it.
btype Defines the Block’s Meaning
When present, the btype field identifies the semantic category of the block. Each btype:
-
Is introduced by a standard,
-
Defines the minimum tx structure required to interpret the block and determine its effect on ledger state,
-
Omits user-specific metadata or optional fields not required to define the core semantics.
This minimal structure acts as the target shape that must be populated by any method that emits that btype.
Method-to-tx Mapping Captures User Intent
The standard defining a method (e.g., icrc147_freeze_account) is responsible for specifying:
-
Which btype the method produces (if any),
-
How to populate the required tx fields defined by the btype,
-
Any additional fields in the tx that reflect the original call (e.g., optional parameters, memo, or timestamp).
The resulting tx must unambiguously reflect the user’s request, enabling deterministic hashing and full auditability.
Canonical tx Must Include the User Call
To avoid collisions and ensure transparency, the tx must include the structure of the user call that triggered it — particularly when the call is standardized. This ensures that:
-
The transaction hash is unique per call,
-
The tx captures exactly what the user asked the ledger to do,
-
Different methods producing the same btype do not collide, thanks to namespacing via standard numbers or method identifiers.
This design reinforces the separation of concerns: btype defines what the block means; the tx records how and why it was created.
Proposed Changes
Based on the principles outlined above, we propose a set of changes to the ICRC-3 standard. The changes fall into three categories: clarifications to ICRC-1/2 block formatting, specification of canonical tx mappings, and new editorial rules for future standards that record ledger transactions.
ICRC-1 and ICRC-2 Blocks: Legacy Format with No btype
The revised ICRC-3 will clarify that all blocks resulting from ICRC-1 and ICRC-2 method calls must use the legacy format and must not include a btype field.
-
This removes ambiguity introduced by the coexistence of two block formats.
-
It ensures compatibility with existing tooling and simplifies parsing.
-
It creates a clear boundary between legacy operations and new typed block types introduced by future standards.
Canonical tx Definitions for ICRC-1 and ICRC-2 Methods
The revised ICRC-3 will spell out the precise canonical tx values to be recorded for each supported ICRC-1 and ICRC-2 method:
-
icrc1_transfer
-
icrc1_approve
-
icrc2_transfer_from
Each mapping will define:
-
Which fields appear in the tx (based only on user-supplied input),
-
How optional fields like memo and created_at_time are handled when present or omitted,
-
Examples for various valid input combinations.
This ensures deterministic transaction ID computation and unambiguous indexing of ledger history.
Transaction ID Based on hash(tx)
The revised ICRC-3 will define the canonical transaction ID for a block as the hash of the tx portion of the block. This definition applies to ICRC-1 and ICRC-2 blocks, and provides a stable, portable way to reference transactions.
Canonical Examples
The revised specification will include concrete examples of canonical tx values for each ICRC-1 and ICRC-2 method, covering:
-
Required-only tx cases,
-
Various combinations of optional fields,
-
Edge cases and minimal viable calls.
These examples will support implementers and indexers by clarifying expected behavior and reducing ambiguity.
Guidance for Future Standards
A new section will be added to ICRC-3 to establish best practices (and, in some cases, requirements) for future standards that define either:
-
New btype values, or
-
Methods that produce ledger blocks.
This section will formalize the expectations for consistency, auditability, and compatibility across the ICRC ecosystem.
btype Ownership and Definition
Standards that introduce a new btype must:
-
Assign a unique btype value,
-
Define the minimum required tx structure needed to interpret the block and compute its effect on ledger state,
-
Avoid including fields not essential to the semantics of the block.
This ensures that any block with a given btype is unambiguous in its meaning and function.
Method-to-Block Mapping
Standards that define methods which produce blocks must:
-
Specify which btype the method produces,
-
Define how to populate the tx in a canonical way from the method call,
-
Ensure that the tx includes all fields required by the corresponding btype,
-
Optionally include additional fields reflecting metadata such as timestamp, caller, or memo.
This enables consistent interpretation of blocks and supports correct indexing, verification, and auditing.
Inclusion of the Call in the tx
Rule: Canonical tx Must Include the User Call
To avoid transaction ID collisions and ensure transparency, the tx must include a canonical representation of the user call that triggered the transaction — particularly when the call is standardized.
This ensures that:
-
The tx captures exactly what the user asked the ledger to do,
-
Transactions from different methods producing the same btype do not collide,
-
The inclusion of the standard number or method name in the tx serves as a namespace to guarantee uniqueness.
By establishing this rule, we preserve determinism and clarity in transaction logging, even as the ICRC ledger ecosystem grows in complexity.
Coordination Across Standards
This proposal formalizes a principled division of responsibilities between standards in the ICRC ecosystem:
-
Standards that introduce a btype define what blocks mean. They must:
-
Assign a unique btype number,
-
Define the minimal tx structure required to interpret the block and determine its effect on ledger state,
-
Exclude optional or user-specific metadata not essential to the semantics.
-
-
This tx structure acts as a target shape — the minimal schema that must be populated for the block to be meaningful and valid.
-
Standards that define methods specify how blocks are created. They must:
-
Specify which btype the method produces,
-
Define a canonical way to construct the tx from the method’s input,
-
Ensure the tx includes all required fields from the btype definition,
-
Optionally include additional metadata such as caller, timestamp, or memo.
-
This coordination model enables reuse of block types across different interfaces while ensuring that each recorded tx is both semantically valid and uniquely identifies the user’s original request. It avoids collisions, promotes clarity, and supports consistent tooling across the ICRC ledger ecosystem.
Why This Matters
By clarifying how ledger blocks record transactions — and aligning that structure with user intent — this revision lays a stronger foundation for the ICRC ledger ecosystem:
-
Consistent transaction IDs across ledgers and tools.
-
Simplified parsing of blocks by indexers, explorers, and auditors.
-
Stronger guarantees about what a ledger actually recorded.
-
Cleaner extensibility for future features like fee handling (ICRC-107), RWA controls, or metadata standards.
This revision makes ICRC-3 a more predictable, more interoperable, and ultimately more trustworthy standard for ledger design on the Internet Computer.
Disruption
This proposal suggests replacing the current version of ICRC-3 with a revised version that incorporates the changes described above. As a result, some disruption for early adopters is expected:
-
Block logs may differ from earlier expectations.
-
Transaction hashes may not match prior definitions.
-
Some tooling and indexers may need to adapt to the clarified format.
However, we believe the cost of not fixing this now is greater. Letting ambiguity persist at the foundation of ICRC-3 will make long-term interoperability and reliability far harder to achieve.
Ask
Would you support moving forward with this revision? We welcome feedback on the proposed direction, especially from ledger implementers, dapp developers, and tooling providers.