Documentation Index
28 min read•Chapter 31

31. Token & Resource Standards (KRS)

Smart contract standards establish unified interfaces, storage layouts, and invariant guarantees across the ecosystem. On Kortana, protocol and token standards are codified under the Kortana Resource Standards (KRS) framework (§21, §9.1.3, §9.8). Implemented in native Quorlin, these standards execute on the register-based Kortana Virtual Machine (KVM) while offering complete interoperability with Ethereum ABI tooling and external indexers.

This chapter walks through practical, developer-ready smart contract examples showing how to write, understand, and deploy contracts for all 12 KRS standards in Quorlin, complete with detailed breakdowns of how each mechanism works.


31.1 Architecture & Storage Layout Rules

The KRS ecosystem is organized into three architectural tiers:

code
┌────────────────────────────────────────────────────────┐ │ Kortana Resource Standards (KRS) │ └────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────┼────────────────────────────────────────────┐ │ │ │ ┌───────────────────────────┐ ┌───────────────────────────┐ ┌───────────────────────────┐ │ TIER 1 │ │ TIER 2 │ │ TIER 3 │ │ Ethereum-Equivalent │ │ RWA & Financial Prims │ │ DePIN & Machine-M2M │ ├───────────────────────────┤ ├───────────────────────────┤ ├───────────────────────────┤ │ • KRS-20 (Fungible) │ │ • KRS-1579 (RWA Assets) │ │ • KRS-3311 (Streaming) │ │ • KRS-721 (NFTs) │ │ • KRS-2186 (Delegated) │ │ • KRS-5502 (Device Reg) │ │ • KRS-1155 (Multi-Token) │ │ • KRS-4317 (Debt/Credit) │ │ • KRS-8290 (Telemetry) │ │ │ │ • KRS-6821 (Attestation) │ │ │ │ │ │ • KRS-7743 (Payments) │ │ │ │ │ │ • KRS-9064 (Escrow) │ │ │ └───────────────────────────┘ └───────────────────────────┘ └───────────────────────────┘

The Slot-Prefix Rule

Quorlin assigns contract storage slots (0, 1, 2, etc.) in declaration order. External indexers (The Graph, subgraphs, explorers) calculate storage slots based on these fixed positions:

  1. Mandated standard variables must be declared first in your contract (slots 0 to N-1).
  2. Custom application variables must be declared after them (slots N and above).
code
Storage Layout in Your Contract ┌─────────────────────────────────────────┐ Slot 0 │ Standard Variable (e.g. owners) │ ◄── External Indexers ├─────────────────────────────────────────┤ (Explorer, Subgraphs) Slot 1 │ Standard Variable (e.g. counts) │ ├─────────────────────────────────────────┤ Slot 2 │ Standard Variable (e.g. approvals) │ ├─────────────────────────────────────────┤ Slot 3 │ Standard Variable (e.g. operators) │ ├─────────────────────────────────────────┤ Slot 4+ │ Your Custom State (mintFee, baseURI...)│ ◄── Your Application └─────────────────────────────────────────┘

Compile-Time Verification (--strict-storage-layout)

The Quorlin compiler (quorlinc) automatically checks your storage layout against the standard at compile time:

bash
# Compiling with KRS layout verification qlc compile MyNFT.ql --strict-storage-layout --standard KRS-721 -o build/ qlc compile MyToken.ql --strict-storage-layout --standard KRS-20 -o build/ qlc compile GameItems.ql --strict-storage-layout --standard KRS-1155 -o build/

31.2 Example: NFT Collection Contract (KRS-721)

KRS-721 defines non-fungible tokens on the Kortana blockchain with full ERC-721 ABI compatibility.

Problem & Motivation

Unique digital assets such as domain names, event tickets, game characters, or collectible passes require verifiable ownership, transfer restrictions, and safe contract receiver callbacks.

Contract Implementation (KortanaPass.ql)

quorlin (.ql)
// Interface for smart contracts that receive NFTs interface IERC721Receiver { writes number onERC721Received(address operator, address from, number tokenId, bytes data); } contract KortanaPass { // Mandated KRS-721 Storage Slots (Slots 0..3) map<number, address> owners; // Slot 0 map<address, number> counts; // Slot 1 map<number, address> approvals; // Slot 2 map<address, map<address, truth>> operators; // Slot 3 // Custom Application State (Slots 4+) address owner; number minted; number maxSupply; number mintPrice; map<number, text> uris; // Standard ERC-721 Events event Transfer(address indexed from, address indexed to, number indexed tokenId); event Approval(address indexed owner, address indexed approved, number indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, truth approved); constructor { owner = caller; minted = 0; maxSupply = 10000; mintPrice = 10000000000000000; // 0.01 KTN in wei } // Identification & Metadata reads truth supportsInterface(bytes4 interfaceId) { // 0x80ac58cd (ERC-721) or 0x01ffc9a7 (ERC-165) return interfaceId == 0x80ac58cd00000000000000000000000000000000000000000000000000000000 || interfaceId == 0x01ffc9a700000000000000000000000000000000000000000000000000000000; } reads number krsStandard() { return 721; } reads text name() { return "Kortana Founder Pass"; } reads text symbol() { return "KPASS"; } reads text tokenURI(number tokenId) { address holder = owners[tokenId]; require holder != nobody, "token does not exist"; return uris[tokenId]; } // Read Queries reads number balanceOf(address holder) { require holder != nobody, "query for zero address"; return counts[holder]; } reads address ownerOf(number tokenId) { address holder = owners[tokenId]; require holder != nobody, "no such token"; return holder; } reads address getApproved(number tokenId) { require owners[tokenId] != nobody, "no such token"; return approvals[tokenId]; } reads truth isApprovedForAll(address holder, address operator) { return operators[holder][operator]; } reads number totalSupply() { return minted; } // Minting writes number mint(address recipient, text metadataUri) { require recipient != nobody, "cannot mint to nobody"; require minted < maxSupply, "collection is sold out"; require sentAmount >= mintPrice, "insufficient payment"; number tokenId = minted + 1; minted = tokenId; owners[tokenId] = recipient; counts[recipient] = counts[recipient] + 1; uris[tokenId] = metadataUri; emit Transfer(nobody, recipient, tokenId); return tokenId; } // Approvals & Transfers writes truth approve(address to, number tokenId) { address holder = owners[tokenId]; require holder != nobody, "no such token"; if (caller != holder) { require operators[holder][caller], "not owner nor operator"; } approvals[tokenId] = to; emit Approval(holder, to, tokenId); return yes; } writes truth setApprovalForAll(address operator, truth approved) { require operator != caller, "cannot approve yourself"; operators[caller][operator] = approved; emit ApprovalForAll(caller, operator, approved); return yes; } writes truth transferFrom(address from, address to, number tokenId) { address holder = owners[tokenId]; require holder != nobody, "no such token"; require holder == from, "from is not token owner"; require to != nobody, "transfer to nobody"; if (caller != holder) { if (caller != approvals[tokenId]) { require operators[holder][caller], "not authorized"; } } // Clear approval on transfer to prevent token reuse drains approvals[tokenId] = nobody; owners[tokenId] = to; counts[from] = counts[from] - 1; counts[to] = counts[to] + 1; emit Transfer(from, to, tokenId); return yes; } // Safe transfer (overload with empty data bytes) writes truth safeTransferFrom(address from, address to, number tokenId) { bytes emptyData = bytes(0); return safeTransferFrom(from, to, tokenId, emptyData); } // Safe transfer with contract receiver hook writes truth safeTransferFrom(address from, address to, number tokenId, bytes data) { // Perform state transfer transferFrom(from, to, tokenId); // Reflection guard: only call receiver hook if recipient is a smart contract if (hasCode(to)) { number answer = IERC721Receiver(to).onERC721Received(caller, from, tokenId, data); // Must return magic selector 0x150b7a02 require answer == 0x150b7a0200000000000000000000000000000000000000000000000000000000, "receiver contract rejected token"; } return yes; } }

Deconstructing the Implementation

  • Mandatory Storage Prefix: Slots 0 through 3 are occupied by owners, counts, approvals, and operators. This ordering guarantees that external tools and explorers computing keccak256(tokenId . 0) can locate token owners without custom ABI configuration.
  • The hasCode(to) Reflection Guard: In safeTransferFrom, the contract checks whether the recipient address contains executable code before dispatching onERC721Received. Regular user wallets have no bytecode; calling a receiver hook on an ordinary account would revert the transaction. The hasCode guard allows transfers to user wallets to succeed while still protecting against sending tokens to smart contracts that cannot move them.
  • Clearing Approvals on Transfer: In transferFrom, approvals[tokenId] is explicitly reset to nobody. If this reset were omitted, an approved marketplace or spender could steal the token from the new buyer after a trade.
  • Payment Enforcement (sentAmount): The mint method checks sentAmount >= mintPrice before incrementing minted, ensuring that payments in native KTN are validated before state changes occur.

31.3 Example: Fungible Token with Mint & Burn (KRS-20)

KRS-20 is the standard for interchangeable, fungible tokens (currencies, staking shares, governance tokens) with ERC-20 parity.

Problem & Motivation

Fungible assets require atomic balance transfers, third-party spending allowances (for automated routers and decentralized exchanges), and balance conservation (the sum of all balances must always equal the total supply).

Contract Implementation (CommunityToken.ql)

quorlin (.ql)
contract CommunityToken { // Mandated KRS-20 Storage Slots (Slots 0..2) map<address, number> balances; // Slot 0 map<address, map<address, number>> allowances; // Slot 1 number supply; // Slot 2 // Custom Application State (Slots 3+) address admin; number maxCap; event Transfer(address indexed from, address indexed to, number value); event Approval(address indexed owner, address indexed spender, number value); event Mint(address indexed to, number amount); event Burn(address indexed from, number amount); constructor { admin = caller; maxCap = 100000000000000000000000000; // 100 million cap (18 decimals) // Initial supply to deployer: 1,000,000 tokens number initialSupply = 1000000000000000000000000; supply = initialSupply; balances[caller] = initialSupply; emit Transfer(nobody, caller, initialSupply); } // Standard Identity & Metadata reads number krsStandard() { return 20; } reads text name() { return "Community Governance Token"; } reads text symbol() { return "COMM"; } reads number decimals() { return 18; } // Read Methods reads number totalSupply() { return supply; } reads number balanceOf(address owner) { return balances[owner]; } reads number allowance(address owner, address spender) { return allowances[owner][spender]; } // Write Methods writes truth approve(address spender, number value) { allowances[caller][spender] = value; emit Approval(caller, spender, value); return yes; } writes truth transfer(address to, number value) { require to != nobody, "transfer to nobody"; number held = balances[caller]; require held >= value, "insufficient balance"; balances[caller] = held - value; balances[to] = balances[to] + value; emit Transfer(caller, to, value); return yes; } writes truth transferFrom(address from, address to, number value) { require to != nobody, "transfer to nobody"; number held = balances[from]; require held >= value, "insufficient balance"; if (caller != from) { number allowed = allowances[from][caller]; require allowed >= value, "insufficient allowance"; allowances[from][caller] = allowed - value; } balances[from] = held - value; balances[to] = balances[to] + value; emit Transfer(from, to, value); return yes; } // Application Extensions: Mint and Burn writes truth mint(address recipient, number amount) { require caller == admin, "only admin can mint"; require recipient != nobody, "cannot mint to nobody"; require supply + amount <= maxCap, "exceeds maximum cap"; supply = supply + amount; balances[recipient] = balances[recipient] + amount; emit Mint(recipient, amount); emit Transfer(nobody, recipient, amount); return yes; } writes truth burn(number amount) { number held = balances[caller]; require held >= amount, "burn exceeds balance"; balances[caller] = held - amount; supply = supply - amount; emit Burn(caller, amount); emit Transfer(caller, nobody, amount); return yes; } }

Deconstructing the Implementation

  • Checked Balance Transfers: The statement balances[caller] = held - value; utilizes Quorlin's default checked arithmetic. If value > held, execution halts immediately.
  • Allowance Spending: In transferFrom, if caller != from, the allowance is decreased by value while re-checking that allowed >= value. If the owner calls transferFrom on their own account, allowance checks are bypassed.
  • Cap Guarding: The mint function enforces supply + amount <= maxCap, preventing governance dilution beyond the hard-coded maximum supply.
  • Audit Trail: Every mint emits both a custom Mint event and a canonical Transfer(nobody, recipient, amount) event so that external portfolio trackers detect newly issued tokens.

31.4 Example: Multi-Token Game Inventory (KRS-1155)

KRS-1155 provides a multi-token standard for handling fungible and non-fungible items within a single smart contract.

Problem & Motivation

In gaming and fractional asset protocols, deploying separate contract addresses for every sword, shield, gold coin, or potion creates massive gas costs and storage fragmentation. KRS-1155 pools all items under one contract and enables atomic batch transfers.

Contract Implementation (GameInventory.ql)

quorlin (.ql)
interface IERC1155Receiver { writes number onERC1155Received(address operator, address from, number id, number amount, bytes data); writes number onERC1155BatchReceived(address operator, address from, list<number> ids, list<number> amounts, bytes data); } contract GameInventory { // Mandated storage layout (slots 0..1) map<number, map<address, number>> balances; // Slot 0: [tokenId][owner] -> amount map<address, map<address, truth>> operatorApprovals; // Slot 1: [owner][operator] -> approved // Custom state address gameMaster; map<number, text> uris; event TransferSingle(address indexed operator, address indexed from, address indexed to, number id, number value); event ApprovalForAll(address indexed owner, address indexed operator, truth approved); constructor { gameMaster = caller; } reads truth supportsInterface(bytes4 interfaceId) { return interfaceId == 0xd9b67a2600000000000000000000000000000000000000000000000000000000; // ERC-1155 } reads number balanceOf(address owner, number id) { return balances[id][owner]; } reads truth isApprovedForAll(address owner, address operator) { return operatorApprovals[owner][operator]; } writes truth setApprovalForAll(address operator, truth approved) { require operator != caller, "cannot approve yourself"; operatorApprovals[caller][operator] = approved; emit ApprovalForAll(caller, operator, approved); return yes; } // Minting items (Fungible currencies or 1-of-1 gear) writes truth mintItem(address player, number itemId, number amount, text itemUri) { require caller == gameMaster, "only game master"; require player != nobody, "cannot mint to nobody"; balances[itemId][player] = balances[itemId][player] + amount; uris[itemId] = itemUri; emit TransferSingle(caller, nobody, player, itemId, amount); return yes; } writes truth safeTransferFrom(address from, address to, number id, number amount, bytes data) { require to != nobody, "transfer to nobody"; if (caller != from) { require operatorApprovals[from][caller], "not authorized"; } number held = balances[id][from]; require held >= amount, "insufficient balance"; balances[id][from] = held - amount; balances[id][to] = balances[id][to] + amount; emit TransferSingle(caller, from, to, id, amount); // Safe receiver hook check if (hasCode(to)) { number answer = IERC1155Receiver(to).onERC1155Received(caller, from, id, amount, data); require answer == 0xf23a6e6100000000000000000000000000000000000000000000000000000000, "receiver rejected item"; } return yes; } }

Deconstructing the Implementation

  • Dual-Key Storage Structure: The balances mapping is declared as map<number, map<address, number>>. The first key is the tokenId, and the second key is the user address. If amount == 1, the token behaves as a non-fungible asset; if amount > 1, it acts as a fungible resource (like gold coins).
  • Universal Operator Approval: Rather than approving spenders token-by-token, setApprovalForAll authorizes a game router or auction house to manage all items owned by the caller.
  • Receiver Verification: On contract transfers, safeTransferFrom expects the recipient contract to return the 4-byte selector 0xf23a6e61 (bytes4(keccak256("onERC1155Received(...)"))).

31.5 Example: Real-World Asset (RWA) Financing (KRS-1579)

KRS-1579 establishes a lifecycle state machine for physical assets, receivables, and invoices, verified live against on-chain attestations (KRS-6821).

Problem & Motivation

Tokenizing physical real-world assets (such as freight invoices or real estate) requires strict legal disclosure: on-chain tokens are operational records, not legal title. Furthermore, an asset cannot be financed if its off-chain custody or KYC validation has lapsed.

Contract Implementation (InvoiceVault.ql)

quorlin (.ql)
// Interface to verify external legal/KYC attestations interface IAttestationRegistry { reads truth isValid(number attestationId); } contract InvoiceVault { number invoiceValue; address custodian; address attestationRegistry; number attestationId; number status; // 0 = Registered, 1 = Financed, 2 = Settled, 3 = Defaulted event InvoiceRegistered(number value, number attestationId); event InvoiceFinanced(); event InvoiceSettled(); constructor { custodian = caller; } reads number krsStandard() { return 1579; } writes truth registerInvoice(number value, address registry, number attestId) { require caller == custodian, "only custodian"; require status == 0, "already registered"; // Invariant: Verify the invoice attestation is currently valid on chain require IAttestationRegistry(registry).isValid(attestId), "invalid attestation"; invoiceValue = value; attestationRegistry = registry; attestationId = attestId; status = 0; emit InvoiceRegistered(value, attestId); return yes; } writes truth financeInvoice() { require caller == custodian, "only custodian"; require status == 0, "must be registered"; // Live check: Attestations revoked or expired prior to funding block the transaction! require IAttestationRegistry(attestationRegistry).isValid(attestationId), "attestation expired or revoked"; status = 1; // Financed emit InvoiceFinanced(); return yes; } writes truth settleInvoice() { require caller == custodian, "only custodian"; require status == 1, "must be financed"; status = 2; // Settled emit InvoiceSettled(); return yes; } }

Deconstructing the Implementation

  • Live Attestation Verification: Notice that financeInvoice does not rely on a boolean flag stored during registration. It performs a live external call to IAttestationRegistry.isValid(attestationId). If the custodian or regulatory authority revoked the invoice's credential between registration and funding, financing reverts immediately.
  • Deterministic State Transitions: State moves strictly forward through three sequential statuses: Registered (0) ──► Financed (1) ──► Settled (2). Skipping steps or financing an already settled invoice is rejected by require status == ... checks.

31.6 Example: Delegated Authorization & Session Grants (KRS-2186)

KRS-2186 implements capability-based delegated authorization.

Problem & Motivation

Users wanting gasless transactions, automated trading bots, or in-game session keys should never export their private keys. KRS-2186 allows accounts to grant scoped, gas-metered execution permissions with automatic time expiration.

Contract Implementation (GaslessRelayer.ql)

quorlin (.ql)
record Grant { address grantor; address grantee; number limit; number spent; number expiresAt; // 0 = no expiry truth revoked; number scopeHash; } contract GaslessRelayer { map<number, Grant> grants; number nextGrantId; event GrantCreated(number indexed grantId, address indexed grantor, address indexed grantee, number limit); event GrantUsed(number indexed grantId, address indexed grantee, number amount); event GrantRevoked(number indexed grantId, address indexed by); reads number krsStandard() { return 2186; } reads truth isValid(number grantId) { Grant g = grants[grantId]; if (g.grantee == nobody) { return no; } if (g.revoked) { return no; } if (g.expiresAt != 0 and blockTime > g.expiresAt) { return no; } return g.spent < g.limit; } writes number createGrant(address grantee, number limit, number expiresAt, number scopeHash) { require grantee != nobody, "grantee is nobody"; require limit > 0, "limit must be positive"; number id = nextGrantId; nextGrantId = id + 1; grants[id].grantor = caller; grants[id].grantee = grantee; grants[id].limit = limit; grants[id].spent = 0; grants[id].expiresAt = expiresAt; grants[id].revoked = no; grants[id].scopeHash = scopeHash; emit GrantCreated(id, caller, grantee, limit); return id; } writes truth useGrant(number grantId, number amount) { Grant g = grants[grantId]; require caller == g.grantee, "caller not grantee"; require isValid(grantId), "grant not valid"; require g.spent + amount <= g.limit, "limit exceeded"; g.spent = g.spent + amount; grants[grantId] = g; emit GrantUsed(grantId, caller, amount); return yes; } writes truth revokeGrant(number grantId) { Grant g = grants[grantId]; require caller == g.grantor, "only grantor can revoke"; require g.revoked == no, "already revoked"; grants[grantId].revoked = yes; emit GrantRevoked(grantId, caller); return yes; } }

Deconstructing the Implementation

  • The record Grant Compound Struct: Bundles grantor identity, grantee address, spend allowances, expiry timestamp, and a scopeHash (the hash of allowed action selectors).
  • Live Headroom & Expiration Checks: The read method isValid(grantId) checks four constraints simultaneously:
    1. The grant exists (grantee != nobody).
    2. The grant is not revoked (revoked == no).
    3. The current block timestamp has not surpassed the expiry deadline (blockTime <= expiresAt).
    4. The cumulative spend has not hit the ceiling (spent < limit).
  • Spending Control: Every time useGrant is called by the delegate, spent increases. Once spent + amount > limit, the grant refuses further execution.
  • Instant Revocation: The grantor can unilaterally terminate the grant at any block by invoking revokeGrant, immediately invalidating subsequent calls.

31.7 Example: Formalized Obligation & Debt (KRS-4317)

KRS-4317 defines structured debt instruments, promissory notes, and bilateral credit obligations.

Problem & Motivation

DeFi lending often deals with pooled collateral, but peer-to-peer loans, supplier trade credit, and corporate bonds need individualized repayment tracking, maturity dates, and automated default evaluation.

Contract Implementation (PromissoryLoan.ql)

quorlin (.ql)
record Obligation { address obligor; // debtor address obligee; // creditor address token; number amount; number repaid; number dueBy; number status; // 0 = Open, 1 = Settled, 2 = Defaulted } contract PromissoryLoan { map<number, Obligation> obligations; number nextObligationId; event LoanCreated(number indexed id, address indexed obligor, address indexed obligee, number amount, number dueBy); event LoanRepaid(number indexed id, address indexed by, number amount); event LoanDefaulted(number indexed id); reads number krsStandard() { return 4317; } reads truth isDefaulted(number id) { Obligation o = obligations[id]; if (o.status != 0) { return no; } if (o.dueBy == 0) { return no; } return blockTime > o.dueBy; } writes number createLoan(address debtor, address tokenAddress, number amount, number dueBy) { require debtor != nobody, "debtor cannot be nobody"; require amount > 0, "amount must be positive"; number id = nextObligationId; nextObligationId = id + 1; obligations[id].obligor = debtor; obligations[id].obligee = caller; obligations[id].token = tokenAddress; obligations[id].amount = amount; obligations[id].repaid = 0; obligations[id].dueBy = dueBy; obligations[id].status = 0; emit LoanCreated(id, debtor, caller, amount, dueBy); return id; } writes truth repayLoan(number id, number amount) { Obligation o = obligations[id]; require o.status == 0, "loan not open"; o.repaid = o.repaid + amount; if (o.repaid >= o.amount) { o.status = 1; // Settled } obligations[id] = o; emit LoanRepaid(id, caller, amount); return yes; } }

Deconstructing the Implementation

  • Bilateral Parties: The contract explicitly identifies obligor (the borrowing entity obligated to repay) and obligee (the lender or creditor holding the debt claim).
  • Live Default Calculation: In isDefaulted, default is evaluated dynamically against blockTime > o.dueBy without needing an off-chain oracle or cron job to flip a stored flag.
  • Partial Repayment & Settlement: The repayLoan method increments repaid. Once cumulative repayments meet or exceed amount, the status advances to 1 (Settled).

31.8 Example: Verifiable Attestation Registry (KRS-6821)

KRS-6821 provides an on-chain registry for cryptographic attestations, identity claims, and compliance verifications.

Problem & Motivation

DeFi protocols frequently require compliance checks (e.g., verifying that a trader is not in a sanctioned jurisdiction, or confirming accredited investor status) without storing private personal data directly on chain.

Contract Implementation (KYCCredentialRegistry.ql)

quorlin (.ql)
record Attestation { address issuer; address subject; number claimType; // identifier or hash of claim type number claimHash; // keccak256 hash of credential data number issuedAt; number revokedAt; // 0 = active } contract KYCCredentialRegistry { map<number, Attestation> attestations; number nextAttestationId; event AttestationIssued(number indexed id, address indexed issuer, address indexed subject); event AttestationRevoked(number indexed id, address indexed issuer); reads number krsStandard() { return 6821; } reads truth isValid(number id) { Attestation a = attestations[id]; if (a.issuer == nobody) { return no; } return a.revokedAt == 0; } writes number issueAttestation(address subject, number claimType, number claimHash) { require subject != nobody, "subject cannot be nobody"; require claimHash != 0, "empty claim hash"; number id = nextAttestationId; nextAttestationId = id + 1; attestations[id].issuer = caller; attestations[id].subject = subject; attestations[id].claimType = claimType; attestations[id].claimHash = claimHash; attestations[id].issuedAt = blockTime; attestations[id].revokedAt = 0; emit AttestationIssued(id, caller, subject); return id; } writes truth revokeAttestation(number id) { Attestation a = attestations[id]; require caller == a.issuer, "only issuer can revoke"; require a.revokedAt == 0, "already revoked"; attestations[id].revokedAt = blockTime; emit AttestationRevoked(id, caller); return yes; } }

Deconstructing the Implementation

  • Privacy Preservation: The contract records claimHash—a cryptographic hash of the off-chain credential document. No personal identification data (names, passport numbers, tax IDs) is stored on the public blockchain.
  • Issuer Authority: Anyone can record an attestation; its credibility depends on the address of the issuer. Consuming contracts inspect a.issuer to ensure it matches their approved auditor or verification authority.
  • Instant Revocation Mechanism: Setting revokedAt = blockTime immediately causes isValid to return no, disabling downstream permissions across all integrating contracts within the same block.

31.9 Example: Structured Milestone Payments (KRS-7743)

KRS-7743 formalizes milestone disbursements, conditional escrow releases, and automated invoicing.

Problem & Motivation

Contractors, software teams, and service providers often work on deliverables. Releasing total compensation upfront creates counterparty risk, while post-delivery payments risk non-payment. KRS-7743 locks funds in escrow and releases them as milestones are completed.

Contract Implementation (MilestoneEscrow.ql)

quorlin (.ql)
record PaymentOrder { address payer; address payee; address token; number amount; number reference; number status; // 0 = Pending, 1 = Released, 2 = Cancelled } contract MilestoneEscrow { map<number, PaymentOrder> payments; number nextPaymentId; event PaymentScheduled(number indexed id, address indexed payer, address indexed payee, number amount); event PaymentReleased(number indexed id, address indexed payee, number amount); event PaymentCancelled(number indexed id); reads number krsStandard() { return 7743; } writes number schedulePayment(address payee, address token, number amount, number reference) { require payee != nobody, "payee cannot be nobody"; require amount > 0, "amount must be positive"; number id = nextPaymentId; nextPaymentId = id + 1; payments[id].payer = caller; payments[id].payee = payee; payments[id].token = token; payments[id].amount = amount; payments[id].reference = reference; payments[id].status = 0; emit PaymentScheduled(id, caller, payee, amount); return id; } writes truth releaseMilestone(number id) { PaymentOrder p = payments[id]; require caller == p.payer, "only payer can release"; require p.status == 0, "payment not pending"; payments[id].status = 1; emit PaymentReleased(id, p.payee, p.amount); return yes; } }

Deconstructing the Implementation

  • Separation of Commitments: schedulePayment records the payer's explicit commitment, identifying the designated contractor (payee), currency token address, agreed payout, and an external reference number (e.g., ticket ID or invoice hash).
  • Guarded Release: In releaseMilestone, the check caller == p.payer prevents unauthorized third parties or the payee from withdrawing funds prematurely.
  • Replay Protection: Updating p.status = 1 ensures that a payment order cannot be released more than once.

31.10 Example: Programmable Escrow with Arbiter (KRS-9064)

KRS-9064 provides multi-party conditional escrow with dispute arbitration and deadline-based refund windows.

Problem & Motivation

In over-the-counter (OTC) token trading or physical good exchanges, neither party wants to send first. A trusted third-party arbiter can resolve disputes, while a deadline guarantees the buyer can retrieve deposited funds if the seller disappears.

Contract Implementation (PeerToPeerEscrow.ql)

quorlin (.ql)
record TradeEscrow { address buyer; address seller; address arbiter; number amount; number deadline; number status; // 0 = Locked, 1 = Released, 2 = Refunded, 3 = Disputed } contract PeerToPeerEscrow { map<number, TradeEscrow> escrows; number nextEscrowId; event EscrowLocked(number indexed id, address indexed buyer, address indexed seller, number amount); event EscrowReleased(number indexed id); event EscrowRefunded(number indexed id); event EscrowDisputed(number indexed id); reads number krsStandard() { return 9064; } writes number openEscrow(address seller, address arbiter, number deadline) { require seller != nobody, "seller cannot be nobody"; require sentAmount > 0, "must fund escrow"; number id = nextEscrowId; nextEscrowId = id + 1; escrows[id].buyer = caller; escrows[id].seller = seller; escrows[id].arbiter = arbiter; escrows[id].amount = sentAmount; escrows[id].deadline = deadline; escrows[id].status = 0; emit EscrowLocked(id, caller, seller, sentAmount); return id; } writes truth releaseToSeller(number id) { TradeEscrow e = escrows[id]; require caller == e.buyer or caller == e.arbiter, "unauthorized to release"; require e.status == 0 or e.status == 3, "invalid escrow state"; escrows[id].status = 1; emit EscrowReleased(id); return yes; } writes truth refundToBuyer(number id) { TradeEscrow e = escrows[id]; if (caller == e.buyer) { require blockTime > e.deadline, "deadline not reached"; } else { require caller == e.arbiter, "only buyer after timeout or arbiter"; } require e.status == 0 or e.status == 3, "invalid escrow state"; escrows[id].status = 2; emit EscrowRefunded(id); return yes; } }

Deconstructing the Implementation

  • Atomic Funding: The buyer invokes openEscrow with attached native tokens (sentAmount > 0), locking funds directly into contract storage.
  • Dual-Authority Release: Funds can be released to the seller either voluntarily by the buyer upon receipt of goods, or by the arbiter if a dispute was resolved in the seller's favor.
  • Timeout-Protected Refund: If the seller fails to deliver and the deadline expires (blockTime > e.deadline), the buyer can trigger a refund unilaterally without needing the arbiter or seller's consent.

31.11 Example: Continuous Micro-Payment Streaming (KRS-3311)

KRS-3311 enables continuous second-by-second token streaming.

Problem & Motivation

Billing for cloud computing, bandwidth consumption, VPN tunnels, or energy metering by sending individual on-chain transactions every second would congest the network and cost astronomical gas fees. KRS-3311 resolves this by calculating claimable earnings dynamically on withdrawal using constant-time O(1) calculation.

Contract Implementation (BandwidthStreamer.ql)

quorlin (.ql)
record PaymentStream { address payer; address recipient; number ratePerSecond; number deposited; number withdrawn; number startedAt; number status; // 0 = Open, 1 = Closed } contract BandwidthStreamer { map<number, PaymentStream> streams; number nextStreamId; event StreamOpened(number indexed streamId, address indexed payer, address indexed recipient); event StreamWithdrawn(number indexed streamId, address indexed recipient, number amount); reads number krsStandard() { return 3311; } reads number claimable(number streamId) { PaymentStream s = streams[streamId]; if (s.status == 1) { return 0; } number duration = blockTime - s.startedAt; number totalEarned = duration * s.ratePerSecond; if (totalEarned > s.deposited) { totalEarned = s.deposited; } if (totalEarned <= s.withdrawn) { return 0; } return totalEarned - s.withdrawn; } writes number withdraw(number streamId) { PaymentStream s = streams[streamId]; require caller == s.recipient, "not recipient"; number available = claimable(streamId); require available > 0, "nothing to withdraw"; s.withdrawn = s.withdrawn + available; streams[streamId] = s; emit StreamWithdrawn(streamId, caller, available); return available; } }

Deconstructing the Implementation

  • Constant-Time O(1) Accrual Calculation:
    code
    claimable = min(deposited, (blockTime - startedAt) * ratePerSecond) - withdrawn
    No loops, no periodic cron updates, and zero state bloat. Whether 10 seconds or 10 months have elapsed, calculating the payout requires only one multiplication and subtraction.
  • Cap Guarding: totalEarned is clamped at s.deposited, ensuring that a stream never permits withdrawals beyond the amount originally deposited by the payer.
  • Continuous Partial Withdrawals: The recipient can withdraw accrued funds whenever desired. withdrawn accumulates over time without resetting startedAt.

31.12 Example: Hardware Device Registry (KRS-5502)

KRS-5502 pairs physical IoT hardware (solar inverters, cellular hotspots, environmental sensors) directly with on-chain identities.

Problem & Motivation

Decentralized Physical Infrastructure Networks (DePIN) rely on real-world devices generating telemetry. To prevent spoofing, devices must sign their data with hardware cryptographic keys embedded inside Trusted Execution Environments (TEE/TPM).

Contract Implementation (SolarDeviceRegistry.ql)

quorlin (.ql)
record DeviceRecord { address owner; address operator; address signingKey; number deviceClass; number registeredAt; number status; // 0 = Active, 1 = Revoked, 2 = Suspended } contract SolarDeviceRegistry { map<number, DeviceRecord> devices; number nextDeviceId; event DeviceRegistered(number indexed deviceId, address indexed owner, address indexed signingKey); event DeviceRevoked(number indexed deviceId); reads number krsStandard() { return 5502; } reads truth isActive(number deviceId) { return devices[deviceId].status == 0; } reads address signingKeyOf(number deviceId) { return devices[deviceId].signingKey; } writes number registerDevice(address operator, address signingKey, number deviceClass) { require signingKey != nobody, "signing key cannot be nobody"; number id = nextDeviceId; nextDeviceId = id + 1; devices[id].owner = caller; devices[id].operator = operator; devices[id].signingKey = signingKey; devices[id].deviceClass = deviceClass; devices[id].registeredAt = blockTime; devices[id].status = 0; emit DeviceRegistered(id, caller, signingKey); return id; } writes truth revokeDevice(number deviceId) { require caller == devices[deviceId].owner, "only device owner can revoke"; require devices[deviceId].status == 0, "not active"; devices[deviceId].status = 1; // Revoked emit DeviceRevoked(deviceId); return yes; } }

Deconstructing the Implementation

  • Owner vs. Operator Separation: The owner holds administrative authority (e.g. key rotation and revocation), while the operator is the entity or smart contract managing the daily device fleet.
  • Hardware Signing Key: signingKey corresponds to the public key generated inside the physical device's secure element. External verifiers match signatures against signingKeyOf(deviceId).
  • Revocation Protection: Once status is set to 1 (Revoked), isActive returns no, immediately cutting off the compromised hardware from protocol rewards or downstream data acceptance.

31.13 Example: Telemetry Merkle Commitments (KRS-8290)

KRS-8290 allows DePIN networks to commit cryptographic Merkle roots of large sensor datasets on chain.

Problem & Motivation

IoT sensors generate thousands of readings per minute. Storing every reading on chain would overwhelm storage and gas limits. Instead, nodes aggregate readings into an off-chain Merkle tree and post a single 32-byte Merkle root on chain for verification.

Contract Implementation (SensorBatchCommitment.ql)

quorlin (.ql)
interface IDeviceRegistry { reads truth isActive(number deviceId); } record TelemetryBatch { address committer; number deviceId; number merkleRoot; number leafCount; number committedAt; number status; // 0 = Committed, 1 = Challenged, 2 = Finalized } contract SensorBatchCommitment { map<number, TelemetryBatch> batches; number nextBatchId; address deviceRegistry; event BatchCommitted(number indexed batchId, number indexed deviceId, number merkleRoot, number count); constructor { deviceRegistry = caller; } reads number krsStandard() { return 8290; } writes truth setRegistry(address reg) { require deviceRegistry == caller, "only admin"; deviceRegistry = reg; return yes; } writes number commitBatch(number deviceId, number merkleRoot, number leafCount) { // Invariant: Verify the physical sensor device is active in the registry require IDeviceRegistry(deviceRegistry).isActive(deviceId), "device is not active"; require merkleRoot != 0, "empty merkle root"; number id = nextBatchId; nextBatchId = id + 1; batches[id].committer = caller; batches[id].deviceId = deviceId; batches[id].merkleRoot = merkleRoot; batches[id].leafCount = leafCount; batches[id].committedAt = blockTime; batches[id].status = 0; emit BatchCommitted(id, deviceId, merkleRoot, leafCount); return id; } }

Deconstructing the Implementation

  • Hardware Cross-Validation: Before accepting a telemetry batch root, commitBatch calls IDeviceRegistry(deviceRegistry).isActive(deviceId). A decommissioned or revoked sensor cannot submit data proofs.
  • Merkle Root Representation: The merkleRoot stores the cryptographic root hash of all leaves in that batch, enabling off-chain auditors to prove any single reading's inclusion using a compact Merkle branch proof.
  • Dispute Windows: Batches are recorded with committedAt = blockTime, establishing an on-chain timeline for challenge and finalization windows.

31.14 Complete KRS Developer Reference Matrix

Standard IDTierNameMandatory Storage PrefixStandard Selectors / MethodsCommon Use Cases
KRS-20Tier 1Fungible Tokenbalances, allowances, supplytotalSupply(), balanceOf(), transfer(), approve()Currencies, rewards, governance tokens
KRS-721Tier 1Non-Fungible Tokenowners, counts, approvals, operatorsownerOf(), safeTransferFrom(), tokenURI()Digital collectibles, gaming items, domain names
KRS-1155Tier 1Multi-Tokenbalances, operatorApprovalsbalanceOf(), safeTransferFrom(), safeBatchTransferFrom()In-game inventories, fractional real estate, bundle passes
KRS-1579Tier 2Real-World AssetCustomregisterAsset(), finance(), redeem()Tokenized real estate, invoices, commodity receipts
KRS-2186Tier 2Delegated AuthCustomcreateGrant(), useGrant(), revokeGrant()Gasless meta-transactions, smart account session keys
KRS-3311Tier 3Streaming Settlementstreams, nextStreamIdclaimable(), withdraw(), openStream()DePIN bandwidth, energy metering, SaaS subscriptions
KRS-4317Tier 2Obligation & DebtCustomcreateLoan(), repayLoan(), isDefaulted()Undercollateralized loans, corporate credit lines
KRS-5502Tier 3Device Registrydevices, nextDeviceIdregisterDevice(), signingKeyOf(), revokeDevice()IoT hardware identity, smart meter telemetry
KRS-6821Tier 2Attestation RegistryCustomissueAttestation(), isValid(), revokeAttestation()KYC/AML verification, accreditation proofs
KRS-7743Tier 2Structured PaymentCustomschedulePayment(), releaseMilestone()Escrow milestones, royalty splits, automated vesting
KRS-8290Tier 3Telemetry CommitmentCustomcommitBatch(), setRegistry()DePIN sensor data proof, environmental audit logs
KRS-9064Tier 2Programmable EscrowCustomopenEscrow(), releaseToSeller(), refundToBuyer()Over-the-counter trades, freelance payments