Iroha v2 Data Model and ISI
May 5, 2026 · View on GitHub
This specification is reverse‑engineered from the current implementation across iroha_data_model and iroha_core to aid design review. Paths in backticks point to the authoritative code.
Scope
- Defines canonical entities (domains, accounts, assets, NFTs, roles, permissions, peers, triggers) and their identifiers.
- Describes state‑changing instructions (ISI): types, parameters, preconditions, state transitions, emitted events, and error conditions.
- Summarizes parameter management, transactions, and instruction serialization.
Determinism: All instruction semantics are pure state transitions without hardware‑dependent behavior. Serialization uses Norito; VM bytecode uses the IVM and is validated host‑side before on‑chain execution.
Entities and Identifiers
IDs have stable string forms with Display/FromStr round‑trip. Name rules forbid whitespace and the reserved @ # $ characters.
Name— validated textual identifier. Rules:crates/iroha_data_model/src/name.rs.DomainId—name. Domain:{ id, logo, metadata, owned_by }. Builders:NewDomain. Code:crates/iroha_data_model/src/domain.rs.AccountId— canonical addresses are produced viaAccountAddressas I105 and Torii normalises inputs throughAccountAddress::parse_encoded. Strict runtime parsing accepts only canonical I105. On-chain account aliases usename@domain.dataspaceorname@dataspaceand resolve to canonicalAccountIdvalues; they are not accepted by strictAccountIdparsers. Account:{ id, metadata }. Code:crates/iroha_data_model/src/account.rs.- Account admission policy — domains control implicit account creation by storing a Norito-JSON
AccountAdmissionPolicyunder metadata keyiroha:account_admission_policy. When the key is absent, the chain-level custom parameteriroha:default_account_admission_policyprovides the default; when that is also absent, the hard default isImplicitReceive(first release). The policy tagsmode(ExplicitOnlyorImplicitReceive) plus optional per-transaction (default16) and per-block creation caps, an optionalimplicit_creation_fee(burn or sink account),min_initial_amountsper asset definition, and an optionaldefault_role_on_create(granted afterAccountCreated, rejects withDefaultRoleErrorif missing). Genesis cannot opt in; disabled/invalid policies reject receipt-style instructions for unknown accounts withInstructionExecutionError::AccountAdmission. Implicit accounts stamp metadatairoha:created_via="implicit"beforeAccountCreated; default roles emit a follow-upAccountRoleGranted, and executor owner-baseline rules let the new account spend its own assets/NFTs without extra roles. Code:crates/iroha_data_model/src/account/admission.rs,crates/iroha_core/src/smartcontracts/isi/account_admission.rs. AssetDefinitionId— canonical unprefixed Base58 address over the canonical asset-definition bytes. This is the public asset ID. Definition:{ id, name, description?, alias?, spec: NumericSpec, mintable: Mintable, logo, metadata, owned_by, total_quantity }.aliasliterals must be<name>#<domain>.<dataspace>or<name>#<dataspace>, with<name>equal to the asset definition name, and they resolve only to the canonical Base58 asset ID. Code:crates/iroha_data_model/src/asset/definition.rs.- Alias lease metadata is persisted separately from the stored asset-definition row. Core/Torii materialize
aliasfrom the binding record when definitions are read. - Torii asset-definition responses expose
alias_binding { alias, status, lease_expiry_ms, grace_until_ms, bound_at_ms }, wherestatusispermanent,leased_active,leased_grace, orexpired_pending_cleanup. - Alias selectors resolve against the latest committed block creation time. After
grace_until_ms, alias selectors stop resolving even if background sweep has not yet removed the stale binding; direct definition reads may still report the stale binding asexpired_pending_cleanup.
- Alias lease metadata is persisted separately from the stored asset-definition row. Core/Torii materialize
AssetId: public asset identifier in canonical bare Base58 form. Asset aliases likename#dataspaceorname#domain.dataspaceresolve toAssetId. Internal ledger holdings may additionally expose splitasset + account + optional dataspacefields where needed, but that composite shape is not the publicAssetId.NftId—nft$domain. NFT:{ id, content: Metadata, owned_by }. Code:crates/iroha_data_model/src/nft.rs.RoleId—name. Role:{ id, permissions: BTreeSet<Permission> }with builderNewRole { inner: Role, grant_to }. Code:crates/iroha_data_model/src/role.rs.Permission—{ name: Ident, payload: Json }. Code:crates/iroha_data_model/src/permission.rs.PeerId/Peer— peer identity (public key) and address. Code:crates/iroha_data_model/src/peer.rs.TriggerId—name. Trigger:{ id, action }. Action:{ executable, repeats, authority, filter, metadata }. Code:crates/iroha_data_model/src/trigger/.Metadata—BTreeMap<Name, Json>with checked insert/remove. Code:crates/iroha_data_model/src/metadata.rs.- Subscription pattern (application layer): plans are
AssetDefinitionentries withsubscription_planmetadata; subscriptions areNftrecords withsubscriptionmetadata; billing is executed by time triggers referencing subscription NFTs. Seedocs/source/subscriptions_api.mdandcrates/iroha_data_model/src/subscription.rs. - Cryptographic primitives (feature
sm):Sm2PublicKey/Sm2Signaturemirror the canonical SEC1 point + fixed-widthr∥sencoding for SM2. Constructors enforce curve membership and distinguishing ID semantics (DEFAULT_DISTID), while verification rejects malformed or high-range scalars. Code:crates/iroha_crypto/src/sm.rsandcrates/iroha_data_model/src/crypto/mod.rs.Sm3Hashexposes the GM/T 0004 digest as a Norito-serialisable[u8; 32]newtype used wherever hashes appear in manifests or telemetry. Code:crates/iroha_data_model/src/crypto/hash.rs.Sm4Keyrepresents 128-bit SM4 keys and is shared between host syscalls and data-model fixtures. Code:crates/iroha_data_model/src/crypto/symmetric.rs. These types sit alongside the existing Ed25519/BLS/ML-DSA primitives and are available to data-model consumers (Torii, SDKs, genesis tooling) once thesmfeature is enabled.
- Dataspace-derived relation stores (
space_directory_manifests,uaid_dataspaces,axt_policies,axt_replay_ledger, lane-relay emergency override registry) and dataspace-target permissions (CanPublishSpaceDirectoryManifest{dataspace: ...}in account/role permission stores) are pruned onState::set_nexus(...)when dataspaces disappear from the activedataspace_catalog, preventing stale dataspace references after runtime catalog updates. Lane-scoped DA/relay caches (lane_relays,da_commitments,da_confidential_compute,da_pin_intents) are also pruned when a lane is retired or reassigned to a different dataspace so lane-local state cannot leak across dataspace migrations. Space Directory ISIs (PublishSpaceDirectoryManifest,RevokeSpaceDirectoryManifest,ExpireSpaceDirectoryManifest) also validatedataspaceagainst the active catalog and reject unknown IDs withInvalidParameter.
Important traits: Identifiable, Registered/Registrable (builder pattern), HasMetadata, IntoKeyValue. Code: crates/iroha_data_model/src/lib.rs.
Events: Every entity has events emitted on mutations (create/delete/owner changed/metadata changed, etc.). Code: crates/iroha_data_model/src/events/.
Parameters (Chain Configuration)
- Families:
SumeragiParameters { block_time_ms, commit_time_ms, min_finality_ms, pacing_factor_bps, max_clock_drift_ms, collectors_k, collectors_redundant_send_r },BlockParameters { max_transactions },TransactionParameters { max_signatures, max_instructions, ivm_bytecode_size, max_tx_bytes, max_decompressed_bytes },SmartContractParameters { fuel, memory, execution_depth }, pluscustom: BTreeMap. - Single enums for diffs:
SumeragiParameter,BlockParameter,TransactionParameter,SmartContractParameter. Aggregator:Parameters. Code:crates/iroha_data_model/src/parameter/system.rs.
Setting parameters (ISI): SetParameter(Parameter) updates the corresponding field and emits ConfigurationEvent::Changed. Code: crates/iroha_data_model/src/isi/transparent.rs, executor in crates/iroha_core/src/smartcontracts/isi/world.rs.
Instruction Serialization and Registry
- Core trait:
Instruction: Send + Sync + 'staticwithdyn_encode(),as_any(), stableid()(defaults to concrete type name). InstructionBox:Box<dyn Instruction>wrapper. Clone/Eq/Ord operate on(type_id, encoded_bytes)so equality is by value.- Norito serde for
InstructionBoxserializes as(String wire_id, Vec<u8> payload)(falls back totype_nameif no wire ID). Deserialization uses a globalInstructionRegistrymapping identifiers to constructors. Default registry includes all built‑in ISI. Code:crates/iroha_data_model/src/isi/{mod.rs,registry.rs}.
ISI: Types, Semantics, Errors
Execution is implemented via Execute for <Instruction> in iroha_core::smartcontracts::isi. Below lists the public effects, preconditions, emitted events, and errors.
Register / Unregister
Types: Register<T: Registered> and Unregister<T: Identifiable>, with sum types RegisterBox/UnregisterBox covering concrete targets.
-
Register Peer: inserts into world peers set.
- Preconditions: must not already exist.
- Events:
PeerEvent::Added. - Errors:
Repetition(Register, PeerId)if duplicate;FindErroron lookups. Code:core/.../isi/world.rs.
-
Register Domain: builds from
NewDomainwithowned_by = authority. Disallowed:genesisdomain.- Preconditions: domain non‑existence; not
genesis. - Events:
DomainEvent::Created. - Errors:
Repetition(Register, DomainId),InvariantViolation("Not allowed to register genesis domain"). Code:core/.../isi/world.rs.
- Preconditions: domain non‑existence; not
-
Register Account: builds from
NewAccount, disallowed ingenesisdomain;genesisaccount cannot be registered.- Preconditions: domain must exist; account non‑existence; not in genesis domain.
- Events:
DomainEvent::Account(AccountEvent::Created). - Errors:
Repetition(Register, AccountId),InvariantViolation("Not allowed to register account in genesis domain"). Code:core/.../isi/domain.rs.
-
Register AssetDefinition: builds from builder; sets
owned_by = authority.- Preconditions: definition non‑existence; domain exists;
nameis required, must be non-empty after trim, and must not contain#/@. - Events:
DomainEvent::AssetDefinition(AssetDefinitionEvent::Created). - Errors:
Repetition(Register, AssetDefinitionId). Code:core/.../isi/domain.rs.
- Preconditions: definition non‑existence; domain exists;
-
Register NFT: builds from builder; sets
owned_by = authority.- Preconditions: NFT non‑existence; domain exists.
- Events:
DomainEvent::Nft(NftEvent::Created). - Errors:
Repetition(Register, NftId). Code:core/.../isi/nft.rs.
-
Register Role: builds from
NewRole { inner, grant_to }(first owner recorded via account‑role mapping), storesinner: Role.- Preconditions: role non‑existence.
- Events:
RoleEvent::Created. - Errors:
Repetition(Register, RoleId). Code:core/.../isi/world.rs.
-
Register Trigger: stores the trigger in the appropriate trigger set by filter kind.
- Preconditions: If filter is not mintable,
action.repeatsmust beExactly(1)(otherwiseMathError::Overflow). Duplicate IDs prohibited. - Events:
TriggerEvent::Created(TriggerId). - Errors:
Repetition(Register, TriggerId),InvalidParameterError::SmartContract(..)on conversion/validation failures. Code:core/.../isi/triggers/mod.rs.
- Preconditions: If filter is not mintable,
-
Unregister Peer/Domain/Account/AssetDefinition/NFT/Role/Trigger: removes the target; emits deletion events. Additional cascading removals:
- Unregister Domain: removes the domain entity plus its selector/endorsement-policy state; deletes asset definitions in the domain (and confidential
zk_assetsside-state keyed by those definitions), assets of those definitions (and per-asset metadata), NFTs in the domain, and account-alias projections rooted in the removed domain. It also prunes account-/role-scoped permission entries that reference the removed domain or resources deleted with it (domain permissions, asset-definition/asset permissions for removed definitions, and NFT permissions for removed NFT IDs). Domain removal does not delete or rewrite the globalAccountId, its tx-sequence/UAID state, foreign asset or NFT ownership, trigger authority, or other external audit/config references that point to the surviving account. Guard rails: rejects when any asset definition in the domain is still referenced by repo-agreement, settlement-ledger, public-lane reward/claim, Offline V2 note state, settlement repo defaults (settlement.repo.eligible_collateral,settlement.repo.collateral_substitution_matrix), governance-configured voting/citizenship/parliament-eligibility/viral-reward asset-definition references, oracle-economics configured reward/slash/dispute-bond asset-definition references, or Nexus fee/staking asset-definition references (nexus.fees.fee_asset_id,nexus.staking.stake_asset_id). Events:DomainEvent::Deleted, plus per-item deletion events for removed domain resources. Errors:FindError::Domainif missing;InvariantViolationon retained asset-definition reference conflicts. Code:core/.../isi/world.rs. - Unregister Account: removes account’s permissions, roles, tx-sequence counter, account label mapping, and UAID bindings; deletes assets owned by the account (and per-asset metadata); deletes NFTs owned by the account; removes triggers whose authority is that account; prunes account-/role-scoped permission entries that reference the removed account, account-/role-scoped NFT-target permissions for removed owned NFT IDs, and account-/role-scoped trigger-target permissions for removed triggers. Guard rails: rejects if the account still owns a domain, asset definition, SoraFS provider binding, active citizenship record, public-lane staking/reward state (including reward-claim keys where the account appears as claimant or reward-asset owner), active oracle state (including oracle feed-history provider entries, twitter-binding provider records, or oracle-economics configured reward/slash account references), active Nexus fee/staking account references (
nexus.fees.fee_sink_account_id,nexus.staking.stake_escrow_account_id,nexus.staking.slash_sink_account_id; parsed as canonical domainless account identifiers and rejected fail-closed on invalid literals), active repo-agreement state, active settlement-ledger state, active Offline V2 note issue/redeem/audit state, active offline escrow-account config references for active asset definitions (Offline V2 escrow bindings), active governance state (proposal/stage approvals/locks/slashes/council/parliament rosters, proposal parliament snapshots, runtime-upgrade proposer records, governance-configured escrow/slash-receiver/viral-pool account references, governance SoraFS telemetry submitter references viagov.sorafs_telemetry.submitters/gov.sorafs_telemetry.per_provider_submitters, or governance-configured SoraFS provider-owner references viagov.sorafs_provider_owners), configured content publish allow-list account references (content.publish_allow_accounts), active social escrow sender state, active content-bundle creator state, active DA pin-intent owner state, active lane-relay emergency validator override state, or active SoraFS pin-registry issuer/binder records (pin manifests, manifest aliases, replication orders). Events:AccountEvent::Deleted, plusNftEvent::Deletedper removed NFT. Errors:FindError::Accountif missing;InvariantViolationon ownership orphans. Code:core/.../isi/domain.rs. - Unregister AssetDefinition: deletes all assets of that definition and their per-asset metadata, and removes confidential
zk_assetsside-state keyed by that definition; also prunes the matchingOffline V2 escrow bindingsentry and account-/role-scoped permission entries that reference the removed asset definition or its asset instances. Guard rails: rejects when the definition is still referenced by repo-agreement, settlement-ledger, public-lane reward/claim, Offline V2 note state, settlement repo defaults (settlement.repo.eligible_collateral,settlement.repo.collateral_substitution_matrix), governance-configured voting/citizenship/parliament-eligibility/viral-reward asset-definition references, oracle-economics configured reward/slash/dispute-bond asset-definition references, or Nexus fee/staking asset-definition references (nexus.fees.fee_asset_id,nexus.staking.stake_asset_id). Events:AssetDefinitionEvent::DeletedandAssetEvent::Deletedper asset. Errors:FindError::AssetDefinition,InvariantViolationon reference conflicts. Code:core/.../isi/domain.rs. - Unregister NFT: removes NFT and prunes account-/role-scoped permission entries that reference the removed NFT. Events:
NftEvent::Deleted. Errors:FindError::Nft. Code:core/.../isi/nft.rs. - Unregister Role: revokes the role from all accounts first; then removes the role. Events:
RoleEvent::Deleted. Errors:FindError::Role. Code:core/.../isi/world.rs. - Unregister Trigger: removes trigger if present and prunes account-/role-scoped permission entries that reference the removed trigger; duplicate unregister yields
Repetition(Unregister, TriggerId). Events:TriggerEvent::Deleted. Code:core/.../isi/triggers/mod.rs.
- Unregister Domain: removes the domain entity plus its selector/endorsement-policy state; deletes asset definitions in the domain (and confidential
Mint / Burn
Types: Mint<O, D: Identifiable> and Burn<O, D: Identifiable>, boxed as MintBox/BurnBox.
-
Asset (Numeric) mint/burn: adjusts balances and definition’s
total_quantity.- Preconditions:
Numericvalue must satisfyAssetDefinition.spec(); mint allowed bymintable:Infinitely: always allowed.Once: allowed exactly once; the first mint flipsmintabletoNotand emitsAssetDefinitionEvent::MintabilityChanged, plus a detailedAssetDefinitionEvent::MintabilityChangedDetailed { asset_definition, minted_amount, authority }for auditability.Limited(n): allowsnadditional mint operations. Each successful mint decrements the counter; when it reaches zero the definition flips toNotand emits the sameMintabilityChangedevents as above.Not: errorMintabilityError::MintUnmintable.
- State changes: creates asset if missing on mint; removes asset entry if balance becomes zero on burn.
- Events:
AssetEvent::Added/AssetEvent::Removed,AssetDefinitionEvent::MintabilityChanged(whenOnceorLimited(n)exhausts its allowance). - Errors:
TypeError::AssetNumericSpec(Mismatch),MathError::Overflow/NotEnoughQuantity. Code:core/.../isi/asset.rs.
- Preconditions:
-
Trigger repetitions mint/burn: changes
action.repeatscount for a trigger.- Preconditions: on mint, filter must be mintable; arithmetic must not overflow/underflow.
- Events:
TriggerEvent::Extended/TriggerEvent::Shortened. - Errors:
MathError::Overflowon invalid mint;FindError::Triggerif missing. Code:core/.../isi/triggers/mod.rs.
Transfer
Types: Transfer<S: Identifiable, O, D: Identifiable>, boxed as TransferBox.
-
Asset (Numeric): subtract from source
AssetId, add to destinationAssetId(same definition, different account). Delete zeroed source asset.- Preconditions: source asset exists; value satisfies
spec. - Events:
AssetEvent::Removed(source),AssetEvent::Added(destination). - Errors:
FindError::Asset,TypeError::AssetNumericSpec,MathError::NotEnoughQuantity/Overflow. Code:core/.../isi/asset.rs.
- Preconditions: source asset exists; value satisfies
-
Domain ownership: changes
Domain.owned_byto destination account.- Preconditions: both accounts exist; domain exists.
- Events:
DomainEvent::OwnerChanged. - Errors:
FindError::Account/Domain. Code:core/.../isi/domain.rs.
-
AssetDefinition ownership: changes
AssetDefinition.owned_byto destination account.- Preconditions: both accounts exist; definition exists; source must currently own it; authority must be source account, source-domain owner, or asset-definition-domain owner.
- Events:
AssetDefinitionEvent::OwnerChanged. - Errors:
FindError::Account/AssetDefinition. Code:core/.../isi/account.rs.
-
NFT ownership: changes
Nft.owned_byto destination account.- Preconditions: both accounts exist; NFT exists; source must currently own it; authority must be source account, source-domain owner, NFT-domain owner, or hold
CanTransferNftfor that NFT. - Events:
NftEvent::OwnerChanged. - Errors:
FindError::Account/Nft,InvariantViolationif source doesn’t own the NFT. Code:core/.../isi/nft.rs.
- Preconditions: both accounts exist; NFT exists; source must currently own it; authority must be source account, source-domain owner, NFT-domain owner, or hold
Metadata: Set/Remove Key‑Value
Types: SetKeyValue<T> and RemoveKeyValue<T> with T ∈ { Domain, Account, AssetDefinition, Nft, Trigger }. Boxed enums provided.
- Set: inserts or replaces
Metadata[key] = Json(value). - Remove: removes the key; error if missing.
- Events:
<Target>Event::MetadataInserted/MetadataRemovedwith the old/new values. - Errors:
FindError::<Target>if the target doesn’t exist;FindError::MetadataKeyon missing key for removal. Code:crates/iroha_data_model/src/isi/transparent.rsand executor impls per target.
Permissions and Roles: Grant / Revoke
Types: Grant<O, D> and Revoke<O, D>, with boxed enums for Permission/Role to/from Account, and Permission to/from Role.
- Grant Permission to Account: adds
Permissionunless already inherent. Events:AccountEvent::PermissionAdded. Errors:Repetition(Grant, Permission)if duplicate. Code:core/.../isi/account.rs. - Revoke Permission from Account: removes if present. Events:
AccountEvent::PermissionRemoved. Errors:FindError::Permissionif absent. Code:core/.../isi/account.rs. - Grant Role to Account: inserts
(account, role)mapping if absent. Events:AccountEvent::RoleGranted. Errors:Repetition(Grant, RoleId). Code:core/.../isi/account.rs. - Revoke Role from Account: removes mapping if present. Events:
AccountEvent::RoleRevoked. Errors:FindError::Roleif absent. Code:core/.../isi/account.rs. - Grant Permission to Role: rebuilds role with permission added. Events:
RoleEvent::PermissionAdded. Errors:Repetition(Grant, Permission). Code:core/.../isi/world.rs. - Revoke Permission from Role: rebuilds role without that permission. Events:
RoleEvent::PermissionRemoved. Errors:FindError::Permissionif absent. Code:core/.../isi/world.rs.
Triggers: Execute
Type: ExecuteTrigger { trigger: TriggerId, args: Json }.
- Behavior: enqueues an
ExecuteTriggerEvent { trigger_id, authority, args }for the trigger subsystem. Manual execution is allowed only for by-call triggers (ExecuteTriggerfilter); the filter must match and the caller must be the trigger action authority or holdCanExecuteTriggerfor that authority. When a user-provided executor is active, trigger execution is validated by the runtime executor and consumes the transaction’s executor fuel budget (baseexecutor.fuelplus optional metadataadditional_fuel). - Errors:
FindError::Triggerif not registered;InvariantViolationif called by non‑authority. Code:core/.../isi/triggers/mod.rs(and tests incore/.../smartcontracts/isi/mod.rs).
Upgrade and Log
Upgrade { executor }: migrates the executor using providedExecutorbytecode, updates executor and its data model, emitsExecutorEvent::Upgraded. Errors: wrapped asInvalidParameterError::SmartContracton migration failure. Code:core/.../isi/world.rs.Log { level, msg }: emits a node log with the given level; no state changes. Code:core/.../isi/world.rs.
Error Model
Common envelope: InstructionExecutionError with variants for evaluation errors, query failures, conversions, entity not found, repetition, mintability, math, invalid parameter, and invariant violation. Enumerations and helpers are in crates/iroha_data_model/src/isi/mod.rs under pub mod error.
Transactions and Executables
Executable: eitherInstructions(ConstVec<InstructionBox>)orIvm(IvmBytecode); bytecode serializes as base64. Code:crates/iroha_data_model/src/transaction/executable.rs.TransactionBuilder/SignedTransaction: constructs, signs, and packages an executable with metadata,chain_id,authority,creation_time_ms, optionalttl_ms, andnonce. Code:crates/iroha_data_model/src/transaction/.- At runtime,
iroha_coreexecutesInstructionBoxbatches viaExecute for InstructionBox, downcasting to the appropriate*Boxor concrete instruction. Code:crates/iroha_core/src/smartcontracts/isi/mod.rs. - Runtime executor validation budget (user-provided executor): base
executor.fuelfrom parameters plus optional transaction metadataadditional_fuel(u64), shared across instruction/trigger validations within the transaction.
Invariants and Notes (from tests and guards)
- Genesis protections: cannot register the
genesisdomain or accounts ingenesisdomain;genesisaccount cannot be registered. Code/tests:core/.../isi/world.rs,core/.../smartcontracts/isi/mod.rs. - Numeric assets must satisfy their
NumericSpecon mint/transfer/burn; spec mismatch yieldsTypeError::AssetNumericSpec. - Mintability:
Onceallows a single mint and then flips toNot;Limited(n)allows exactlynmints before flipping toNot. Attempts to forbid minting onInfinitelycauseMintabilityError::ForbidMintOnMintable, and configuringLimited(0)yieldsMintabilityError::InvalidMintabilityTokens. - Metadata operations are key‑exact; removing a non‑existent key is an error.
- Trigger filters can be non‑mintable; then
Register<Trigger>only permitsExactly(1)repeats. - Trigger metadata key
__enabled(bool) gates execution; missing defaults to enabled, and disabled triggers are skipped across data/time/by-call paths. - Determinism: all arithmetic uses checked operations; under/overflow returns typed math errors; zero balances drop asset entries (no hidden state).
Practical Examples
- Minting and transfer:
Mint::asset_numeric(10, asset_id)→ adds 10 if allowed by spec/mintability; events:AssetEvent::Added.Transfer::asset_numeric(asset_id, 5, to_account)→ moves 5; events for removal/addition.
- Metadata updates:
SetKeyValue::account(account_id, "avatar".parse()?, json)→ upsert; removal viaRemoveKeyValue::account(...).
- Role/permission management:
Grant::account_role(role_id, account),Grant::role_permission(perm, role), and theirRevokecounterparts.
- Trigger lifecycle:
Register::trigger(Trigger::new(id, Action::new(exec, repeats, authority, filter)))with mintability check implied by filter;ExecuteTrigger::new(id).with_args(&args)must match configured authority.- Triggers can be disabled by setting metadata key
__enabledtofalse(missing defaults to enabled); toggle viaSetKeyValue::triggeror the IVMset_trigger_enabledsyscall. - Trigger storage is repaired on load: duplicate ids, mismatched ids, and triggers referencing missing bytecode are dropped; bytecode reference counts are recomputed.
- If a trigger's IVM bytecode is missing at execution time, the trigger is removed and the execution is treated as a no-op with a failure outcome.
- Depleted triggers are removed immediately; if a depleted entry is encountered during execution it is pruned and treated as missing.
- Parameter update:
SetParameter(SumeragiParameter::BlockTimeMs(2500).into())updates and emitsConfigurationEvent::Changed.
CLI / Torii asset-definition id + alias examples:
- Register with canonical Base58 id + explicit name + long alias:
iroha ledger asset definition register --id 66owaQmAQMuHxPzxUN3bqZ6FJfDa --name pkr --alias pkr#bankb.paynet
- Register with canonical Base58 id + explicit name + short alias:
iroha ledger asset definition register --id 66owaQmAQMuHxPzxUN3bqZ6FJfDa --name pkr --alias pkr#paynet
- Mint by alias + account components:
iroha ledger asset mint --definition-alias pkr#bankb.paynet --account <i105> --quantity 500
- Resolve alias to canonical Base58 id:
POST /v1/assets/aliases/resolvewith JSON{ "alias": "pkr#bankb.paynet" }
Migration note:
name#domaintextual asset-definition IDs remain intentionally unsupported in the first release; use canonical Base58 IDs or resolve a dotted alias.- Public asset selectors use canonical Base58 asset-definition ids plus split ownership fields (
account, optionalscope). Raw encodedAssetIdliterals remain internal helpers and are not part of the Torii/CLI selector surface. - Asset-definition list/query filters and sorts additionally accept
alias_binding.status,alias_binding.lease_expiry_ms,alias_binding.grace_until_ms, andalias_binding.bound_at_ms.
Traceability (selected sources)
- Data model core:
crates/iroha_data_model/src/{account.rs,domain.rs,asset/**,nft.rs,role.rs,permission.rs,metadata.rs,trigger/**,parameter/**}. - ISI definitions and registry:
crates/iroha_data_model/src/isi/{mod.rs,register.rs,transfer.rs,mint_burn.rs,transparent.rs,registry.rs}. - ISI execution:
crates/iroha_core/src/smartcontracts/isi/{mod.rs,world.rs,domain.rs,account.rs,asset.rs,nft.rs,triggers/**}. - Events:
crates/iroha_data_model/src/events/**. - Transactions:
crates/iroha_data_model/src/transaction/**.
If you want this spec expanded into a rendered API/behavior table or cross‑linked to every concrete event/error, say the word and I’ll extend it.