The SQRL token standard

Every SQRL asset, from a regulated stablecoin to a tokenised fund share, is an SCL contract that implements the SQRL token standard: UTXO-bound balances, quorum administration, separated asset roles, a hard supply cap, a whitelist, and reason-coded freeze, clawback and pause.

Updated 08 Nov 20265 min read

The standard builds on the utxo_token_v1 interface. Balances are bound to Bitcoin outpoints rather than to address-keyed maps, so tokens inherit Bitcoin's double-spend safety and compose with Lightning channels, which are outpoints too.

#Ownership is an outpoint

A token balance lives on a Bitcoin output. Each transfer or mint creates a 550-satoshi output for the recipient, and the balance binds to whatever outpoint that output becomes. Owning the outpoint is owning the tokens. Spending it in a transfer moves them on.

warning:

Spend token-bound coins only through token calls

A token-bound output must be spent by a transfer, mint or burn call. Spending it in a plain Bitcoin transaction gives up the balance it carries. SQRL Enterprise and SQRL Pay protect token-bound outputs automatically; take the same care with any other wallet software.

#Administration and roles

RoleHoldsMay
AdminA vault, under its t-of-n quorumInitialise the token, assign and revoke asset roles, transfer ownership
MinterAssigned by the adminCreate new tokens up to the supply cap
BurnerAssigned by the adminDestroy tokens, and execute clawbacks
PauserAssigned by the adminHalt and resume all transfers
Compliance officerAssigned by the adminManage the whitelist, freeze and unfreeze holders, and request clawbacks of frozen balances

Every administrative call is authorised by the Bitcoin spend itself: the contract checks the address of the coin the call spends, and only the vault's quorum can spend it. Roles are assigned on-chain with setRole, and each action type is maker-checker: the operator who proposes an action cannot be the one who approves it.

#Supply

  • Hard cap. max_supply is fixed when the token is initialised and can never change. A mint that would exceed it is refused.
  • Initial supply. Credited to an output of the initialisation transaction, owned by the issuing vault.
  • Decimals. Set at initialisation. SQRL Enterprise issues assets with 0 to 8 decimal places, so raw supplies always fit comfortably in 64-bit integers.
  • Burns reduce total supply, which frees headroom under the cap.

#Whitelist

An asset can enforce a whitelist of approved holders. While it is enforced, the contract refuses any movement by a holder who is not on the list, and SQRL Enterprise refuses to build a transfer or mint to a recipient who is not on it, before any transaction exists. Tokens sent to a non-listed address from outside SQRL Enterprise cannot move again until that address is approved. Every addition and removal is itself an anchored, auditable event. A compliance officer can stop enforcing the whitelist for an asset that should circulate freely, and enforce it again later.

#Enforcement

Freeze, unfreeze, clawback and pause are contract functions. They run through the same quorum signing as any other call, carry a reason code, and emit a public on-chain event. The issuer's case reference for each action is recorded with it in SQRL Enterprise and its audit log, and deliberately kept off-chain: the chain shows that a balance was frozen and why, by code, without naming the case.

FunctionPurposeArguments
freezeImmobilise a holder's balance on lawful ordertarget, reason code
unfreezeLift a freezetarget, reason code
clawbackForced transfer of a frozen balance to a recovery vault, optionally followed by a burnfrom, to, amount, reason code
pause / unpauseHalt or resume every transfer of the assetreason code
setRoleAssign or revoke a minter, burner, pauser or compliance keykey, role

A freeze target is either an outpoint or an address. Freezing an outpoint pins that balance whoever tries to spend it. Freezing an address blocks it as a sender and follows its value into any balance the contract holds back for it. Freezes stay in force while an asset is paused. Clawbacks use the freeze reason codes; pauses carry a reason code from the issuer's own code book.

#Functions

FunctionWhoNotes
init(owner, name, symbol, decimals, initial_supply, max_supply, whitelist_on, dest_vout)AdminOne-time. Must spend an output of the deployment transaction, so only the deployer can initialise
transfer(amounts: List<u64>)HolderPer-output amounts; outputs of the anchoring transaction do the addressing
mint(amount, dest_vout)MinterWithin the cap; the output of the anchoring transaction receives the tokens. Authorised-participant mints carry their redemption reference
burn(amount)Burner, or any holder for their own balanceDestroys tokens from the caller's own balance
freeze, unfreezeCompliance officerReason code required on chain; case reference required in SQRL Enterprise
clawbackBurner, on a compliance officer's requestReason code and case reference, as for a freeze
pause, unpausePauserReason code required
setRole, transfer_ownershipAdminQuorum signed
add_to_whitelist, remove_from_whitelist, enable_whitelist, disable_whitelistCompliance officerWhitelist management
balance_of, get_all_balances, get_owner, is_paused, is_frozen, get_frozen, is_whitelisted, may_moveAnyoneRead-only views

#Events

Initialized, Minted, Burned, Transferred, Held, Released, OwnershipTransferred, RoleSet, Frozen, Unfrozen, ClawedBack, Paused and Unpaused. Enforcement events carry their reason code, so an asset's full control history can be read from any node's events API.

Key takeaway

The issuer's powers over an asset are written into the contract and exercised only through quorum-signed Bitcoin transactions. Holders and auditors can see every one of them on-chain.

Was this page helpful?