1<!doctype html> 2<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-spec/chip" data-has-hydrated="false"> 3<head> 4<meta charset="UTF-8"> 5<meta name="generator" content="Docusaurus v3.9.1"> 6<title data-rh="true">Specification | CashTokens</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://cashtokens.org/img/cashtokens-social-card.png"><meta data-rh="true" name="twitter:image" content="https://cashtokens.org/img/cashtokens-social-card.png"><meta data-rh="true" property="og:url" content="https://cashtokens.org/docs/spec/chip"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Specification | CashTokens"><meta data-rh="true" name="description" content="Title: Token Primitives for Bitcoin Cash"><meta data-rh="true" property="og:description" content="Title: Token Primitives for Bitcoin Cash"><link data-rh="true" rel="icon" href="/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://cashtokens.org/docs/spec/chip"><link data-rh="true" rel="alternate" href="https://cashtokens.org/docs/spec/chip" hreflang="en"><link data-rh="true" rel="alternate" href="https://cashtokens.org/docs/spec/chip" hreflang="x-default">
6<script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"CashTokens CHIP","item":"https://cashtokens.org/docs/category/cashtokens-chip"},{"@type":"ListItem","position":2,"name":"Specification","item":"https://cashtokens.org/docs/spec/chip"}]}</script>
6<link rel="preconnect" href="https://www.google-analytics.com"> 7<link rel="preconnect" href="https://www.googletagmanager.com">
vendor: 64 bytes, lines 7-8
7 8<script async src="https://www.googletagmanager.com/gtag/js?id=
8G-NCE7PCHMTK
vendor: 12 bytes, line 8
8"></script>
9<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-NCE7PCHMTK",{anonymize_ip:!0})</script>
9<link rel="stylesheet" href="/assets/css/styles.eee73118.css">
10<script src="/assets/js/runtime~main.547dac0f.js" defer="defer"></script>
vendor: 1 bytes, line 10
10
11<script src="/assets/js/main.fe465a96.js" defer="defer"></script>
11 12</head> 13<body class="navigation-with-keyboard"> 14<svg style="display: none;"><defs> 15<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol> 16</defs></svg>
17<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script>
17<div id="__docusaurus"><link rel="preload" as="image" href="/img/cashtokens-logo.svg"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top navbar--dark"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/cashtokens-logo.svg" alt="CashTokens" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/img/cashtokens-logo.svg" alt="CashTokens" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate"></b></a><a class="navbar__item navbar__link" href="/docs/intro">Intro</a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/docs/spec/chip">Specification</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://github.com/cashtokens/cashtokens.org" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS darkNavbarColorModeToggle_X3D1" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div><div class="navbarSearchContainer_Bca1"><div class="navbar__search searchBarContainer_NW3z" dir="ltr"><input placeholder="Search" aria-label="Search" class="navbar__search-input searchInput_YFbd" value=""><div class="loadingRing_RJI3 searchBarLoadingRing_YnHq"><div></div><div></div><div></div><div></div></div></div></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_z2l0"><div class="docsWrapper_hBAB"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docRoot_UBD9"><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class="sidebarViewport_aRkj"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/intro"><span title="Introduction" class="linkLabel_WmDU">Introduction</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--active" href="/docs/category/cashtokens-chip"><span title="CashTokens CHIP" class="categoryLinkLabel_W154">CashTokens CHIP</span></a><button aria-label="Collapse sidebar category 'CashTokens CHIP'" aria-expanded="true" type="button" class="clean-btn menu__caret"></button></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/docs/spec/chip"><span title="Specification" class="linkLabel_WmDU">Specification</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/spec/examples"><span title="Usage Examples" class="linkLabel_WmDU">Usage Examples</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/spec/rationale"><span title="Rationale" class="linkLabel_WmDU">Rationale</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/spec/alternatives"><span title="Prior Art & Alternatives" class="linkLabel_WmDU">Prior Art & Alternatives</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/spec/stakeholders"><span title="Stakeholder Responses" class="linkLabel_WmDU">Stakeholder Responses</span></a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist" href="/docs/category/metadata-registries-chip"><span title="Metadata Registries CHIP" class="categoryLinkLabel_W154">Metadata Registries CHIP</span></a><button aria-label="Expand sidebar category 'Metadata Registries CHIP'" aria-expanded="false" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item hidden"><a class="menu__link" href="/docs/bcmr"><span title="bcmr" class="linkLabel_WmDU">bcmr</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item hidden"><a class="menu__link" href="/docs/spec"><span title="spec" class="linkLabel_WmDU">spec</span></a></li></ul></nav></div></div></aside><main class="docMainContainer_TBSr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><a class="breadcrumbs__link" href="/docs/category/cashtokens-chip"><span>CashTokens CHIP</span></a></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Specification</span></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Specification</h1></header> 18<p>Title: Token Primitives for Bitcoin Cash 19Type: Standards 20Layer: Consensus 21Maintainer: Jason Dreyzehner 22Status: Final 23Initial Publication Date: 2022-02-22 24Final Revision Date: 2023-5-20 25Version: 2.2.2</p> 26<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><strong>Table of Contents</strong></summary><div><div class="collapsibleContent_i85q"><ul> 27<li><a href="#summary">Summary</a></li> 28<li><a href="#deployment">Deployment</a></li> 29<li><a href="#motivation">Motivation</a></li> 30<li><a href="#benefits">Benefits</a></li> 31<li><a href="#technical-summary">Technical Summary</a></li> 32<li><a href="#technical-specification">Technical Specification</a></li> 33<li><a href="#usage-examples">Usage Examples</a></li> 34<li><a href="#rationale">Rationale</a></li> 35<li><a href="#prior-art--alternatives">Prior Art & Alternatives</a></li> 36<li><a href="#stakeholder-responses--statements">Stakeholder Responses & Statements</a></li> 37<li><a href="#test-vectors">Test Vectors</a></li> 38<li><a href="#implementations">Implementations</a></li> 39<li><a href="#feedback--reviews">Feedback & Reviews</a></li> 40<li><a href="#acknowledgements">Acknowledgements</a></li> 41<li><a href="#changelog">Changelog</a></li> 42<li><a href="#copyright">Copyright</a></li> 43</ul></div></div></details> 44<h2 class="anchor anchorWithStickyNavbar_LWe7" id="summary">
44Summary<a href="#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">â</a></h2> 45<p>This proposal enables two new primitives on Bitcoin Cash: <strong>fungible tokens</strong> and <strong>non-fungible tokens</strong>.</p> 46<h3 class="anchor anchorWithStickyNavbar_LWe7" id="terms">Terms<a href="#terms" class="hash-link" aria-label="Direct link to Terms" title="Direct link to Terms" translate="no">â</a></h3> 47<p>A <strong>token</strong> is an asset â distinct from the Bitcoin Cash currency â that can be created and transferred on the Bitcoin Cash network.</p> 48<p><strong>Non-Fungible tokens (NFTs)</strong> are a token type in which individual units cannot be merged or divided â each NFT contains a <strong>commitment</strong>, a short byte string attested to by the issuer of the NFT.</p> 49<p><strong>Fungible tokens</strong> are a token type in which individual units are undifferentiated â groups of fungible tokens can be freely divided and merged without tracking the identity of individual tokens (much like the Bitcoin Cash currency).</p> 50<h2 class="anchor anchorWithStickyNavbar_LWe7" id="deployment">Deployment<a href="#deployment" class="hash-link" aria-label="Direct link to Deployment" title="Direct link to Deployment" translate="no">â</a></h2> 51<p>Deployment of this specification is proposed for the May 2023 upgrade.</p> 52<ul> 53<li>Activation is proposed for <code>1668513600</code> <a href="https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki" target="_blank" rel="noopener noreferrer">MTP</a>, (<code>2022-11-15T12:00:00.000Z</code>) on <a href="https://bitcoincashresearch.org/t/staging-chips-on-testnet/573/10" target="_blank" rel="noopener noreferrer"><code>chipnet</code></a>.</li> 54<li>Activation is proposed for <code>1684152000</code> <a href="https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki" target="_blank" rel="noopener noreferrer">MTP</a>, (<code>2023-05-15T12:00:00.000Z</code>) on the BCH network (<code>mainnet</code>), <code>testnet3</code>, <code>testnet4</code>, and <code>scalenet</code>.</li> 55</ul> 56<h2 class="anchor anchorWithStickyNavbar_LWe7" id="motivation">Motivation<a href="#motivation" class="hash-link" aria-label="Direct link to Motivation" title="Direct link to Motivation" translate="no">â</a></h2> 57<p>Bitcoin Cash contracts lack primitives for issuing messages that can be verified by other contracts, preventing the development of decentralized application ecosystems on Bitcoin Cash.</p> 58<h3 class="anchor anchorWithStickyNavbar_LWe7" id="contract-issued-commitments">Contract-Issued Commitments<a href="#contract-issued-commitments" class="hash-link" aria-label="Direct link to Contract-Issued Commitments" title="Direct link to Contract-Issued Commitments" translate="no">â</a></h3> 59<p>In the context of the Bitcoin Cash virtual machine (VM), a <strong>commitment</strong> can be defined as an irrevocable message that was provably issued by a particular entity. Two forms of commitments are currently available to Bitcoin Cash contracts:</p> 60<ul> 61<li><strong>Transaction signatures</strong> â a commitment made by a private key attesting to the signing serialization of a transaction.</li> 62<li><strong>Data signatures</strong> â a commitment made by a private key attesting to the hash of an arbitrary message (introduced in 2018 by <a href="https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/op_checkdatasig.md" target="_blank" rel="noopener noreferrer"><code>OP_CHECKDATASIG</code></a>).</li> 63</ul> 64<p>Each of these commitment types require the presence of a <em>trusted private key</em>. Because contracts cannot themselves hold a private key, any use case that requires a contract to issue a verifiable message must necessarily rely on trusted entities to provide signatures<sup>1</sup>. This limitation prevents Bitcoin Cash contracts from offering or using <strong>decentralized oracles</strong> â multiparty consensus systems that produce verifiable messages upon which other contracts can act.</p> 65<p>By providing a commitment primitive that can be used directly by contracts, the Bitcoin Cash contract system can support advanced, decentralized applications without increasing transaction or block validation costs.</p> 66<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Notes</summary><div><div class="collapsibleContent_i85q"><ol> 67<li>Signature aggregation schemes can enable contracts to issue some commitments with reduced trust (e.g. by requiring a quorum of always-online entities to join a multiparty signing process), but these schemes typically require active coordination, carefully-designed participation incentives, fallback strategies, and other significant fixed costs (e.g. always-online servers). In practice, few such systems are able to maintain sufficient traction to continue functioning, and notably, forcing a contract to rely on these systems is arbitrary and wasteful (in terms of network bandwidth and validation costs) when their purpose is simply to attest to a result already produced by that contract.</li> 68</ol></div></div></details> 69<h4 class="anchor anchorWithStickyNavbar_LWe7" id="byte-string-commitments">Byte-String Commitments<a href="#byte-string-commitments" class="hash-l
69ink" aria-label="Direct link to Byte-String Commitments" title="Direct link to Byte-String Commitments" translate="no">â</a></h4> 70<p>The most general type of contract-issued commitment is a simple string of bytes. This type can be used to commit to any type of contract state: certifications of ownership, authorizations, credit, debt, contract-internal time or epoch, vote counts, receipts (e.g. to support refunds or future redemption), etc. Identities may commit to state within a hash structure (e.g. a merkle tree), or â to reduce transaction sizes â as a raw byte string (e.g. public keys, static numbers, boolean values).</p> 71<p>In this proposal, byte-string commitments are called <strong>non-fungible tokens</strong>.</p> 72<h4 class="anchor anchorWithStickyNavbar_LWe7" id="numeric-commitments">Numeric Commitments<a href="#numeric-commitments" class="hash-link" aria-label="Direct link to Numeric Commitments" title="Direct link to Numeric Commitments" translate="no">â</a></h4> 73<p><strong>The Bitcoin Cash virtual machine (VM) supports two primary data types in VM bytecode evaluation: byte strings and numbers</strong>. Given the existence of a primitive allowing contracts to commit to byte strings, another commitment primitive can be inferred: <strong>numeric commitments</strong>.</p> 74<p>Numeric commitments are a specialization of byte-string commitments â they are commitments with numeric values which can be divided and merged in the same way as the Bitcoin Cash currency. With numeric commitments, contracts can efficiently represent fractional parts of abstract concepts â shares, pegged assets, bonds, loans, options, tickets, loyalty points, voting outcomes, etc.</p> 75<p>While many use cases for numeric commitments can be emulated with only byte-string commitments, a numeric primitive enables many contracts to reduce or offload state management altogether (e.g. <a href="/docs/spec/examples#voting-with-fungible-tokens">shareholder voting</a>), simplifying contract audits and reducing transaction sizes.</p> 76<p>In this proposal, numeric commitments are called <strong>fungible tokens</strong>.</p>
77<h2 class="anchor anchorWithStickyNavbar_LWe7" id="benefits">Benefits<a href="#benefits" class="hash-link" aria-label="Direct link to Benefits" title="Direct link to Benefits" translate="no">â</a></h2> 78<p>By enabling token primitives on Bitcoin Cash, this proposal offers several benefits.</p> 79<h3 class="anchor anchorWithStickyNavbar_LWe7" id="cross-contract-interfaces">Cross-Contract Interfaces<a href="#cross-contract-interfaces" class="hash-link" aria-label="Direct link to Cross-Contract Interfaces" title="Direct link to Cross-Contract Interfaces" translate="no">â</a></h3> 80<p>Using <strong>non-fungible tokens</strong> (NFTs), contracts can <strong>create messages that can be read by other contracts</strong>. These messages are impersonation-proof: other contracts can safely read and act on the commitment, certain that it was produced by the claimed contract.</p> 81<p>With contract interoperability, behavior can be broken into clusters of smaller, coordinating contracts, <strong>reducing transaction sizes</strong>. This interoperability further enables <a href="/docs/spec/examples#usage-examples">covenants</a> to communicate over <strong>public interfaces</strong>, allowing diverse ecosystems of compatible covenants to work together, even when developed and deployed separately.</p> 82<p>Critically, this cross-contract interaction can be achieved within the "stateless" transaction model employed by Bitcoin Cash, rather than coordinating via shared global state. This allows Bitcoin Cash to support comparable contract functionality while retaining its <a href="https://blog.bitjson.com/pmv3-build-decentralized-applications-on-bitcoin-cash/#stateless-network-stateful-covenants" target="_blank" rel="noopener noreferrer">>1000x efficiency advantage</a> in transaction and block validation.</p> 83<h3 class="anchor anchorWithStickyNavbar_LWe7" id="decentralized-applications">Decentralized Applications<a href="#decentralized-applications" class="hash-link" aria-label="Direct link to Decentralized Applications" title="Direct link to Decentralized Applications" translate="no">â</a></h3> 84<p>Beyond enabling covenants to interoperate with other covenants, these token primitives allow for byte-efficient representations of complex internal state â supporting <a href="https://github.com/bitjson/jedex" target="_blank" rel="noopener noreferrer">advanced, decentralized applications</a> on Bitcoin Cash.</p> 85<p><strong>Non-fungible tokens</strong> are critical for coordinating activity trustlessly between multiple covenants, enabling <a href="/docs/spec/examples#covenant-tracking-identity-tokens">covenant-tracking tokens</a>, <a href="/docs/spec/examples#depository-child-covenants">depository child covenants</a>, <a href="/docs/spec/examples#multithreaded-covenants">multithreaded covenants</a>, and other constructions in which a particular covenant instance must be authenticated.</p> 86<p><strong>Fungible tokens</strong> are valuable for covenants to represent on-chain assets â e.g. voting shares, utility tokens, collateralized loans, prediction market options, etc. â and implement <a href="/docs/spec/examples#voting-with-fungible-tokens">complex coordination tasks</a> â e.g. liquidity-pooling, auctions, voting, sidechain withdrawals, spin-offs, mergers, and more.</p> 87<h3 class="anchor anchorWithStickyNavbar_LWe7" id="universal-token-primitives">Universal Token Primitives<a href="#universal-token-primitives" class="hash-link" aria-label="Direct link to Universal Token Primitives" title="Direct link to Universal Token Primitives" translate="no">â</a></h3> 88<p>By exposing basic, consensus-validated token primitives, this proposal supports the development of higher-level, interoperable token standards (e.g. <a href="https://slp.dev/" target="_blank" rel="noopener noreferrer">SLP</a>). Token primitives can be held by any contract, wallets can easily verify the authenticity of a token or group of tokens, and tokens cannot be inadvertently destroyed by wallet software that does not support tokens.</p> 89<h2 class="anchor anchorWithStickyNavbar_LWe7" id="technical-summary">
89Technical Summary<a href="#technical-summary" class="hash-link" aria-label="Direct link to Technical Summary" title="Direct link to Technical Summary" translate="no">â</a></h2> 90<ol> 91<li>A token <strong>category</strong> can include both non-fungible and fungible tokens, and every category is represented by a 32-byte category identifier â the transaction ID of the outpoint spent to create the category.<!-- --> 92<ol> 93<li>All fungible tokens for a category must be created when the token category is created, ensuring the total supply within a category remains below the maximum VM number.</li> 94<li>Non-fungible tokens may be created either at category creation or in later transactions that spend tokens with <code>minting</code> or <code>mutable</code> capabilities for that category.</li> 95</ol> 96</li> 97<li>Transaction outputs are extended to support four new <code>token</code> fields; every output can include one <strong>non-fungible token</strong> and any amount of <strong>fungible tokens</strong> from a single token category.</li> 98<li><a href="#token-inspection-operations">Token inspection opcodes</a> allow contracts to operate on tokens, enabling <a href="/docs/spec/examples#usage-examples">cross-contract interfaces and decentralized applications</a>.</li> 99</ol> 100<h3 class="anchor anchorWithStickyNavbar_LWe7" id="transaction-output-data-model">Transaction Output Data Model<a href="#transaction-output-data-model" class="hash-link" aria-label="Direct link to Transaction Output Data Model" title="Direct link to Transaction Output Data Model" translate="no">â</a></h3> 101<p>This proposal extends the data model of transaction outputs to add four new <code>token</code> fields: token <code>category</code>, non-fungible token <code>capability</code>, non-fungible token <code>commitment</code>, and fungible token <code>amount</code>.</p> 102<table><thead><tr><th>Existing Fields</th><th>Description</th></tr></thead><tbody><tr><td>Value</td><td>The value of the output in satoshis, the smallest unit of bitcoin cash. (A.K.A. <code>vout</code>)</td></tr><tr><td>Locking Bytecode</td><td>The VM bytecode used to encumber this transaction output. (A.K.A. <code>scriptPubKey</code>)</td></tr><tr><td><strong>Token Fields</strong></td><td>(New, optional fields added by this proposal:)</td></tr><tr><td>Category ID</td><td>The 32-byte ID of the token category to which the token(s) in this output belong. This field is omitted if no tokens are present.</td></tr><tr><td>Capability</td><td>The capability of the NFT held in this output: <code>none</code>, <code>mutable</code>, or <code>minting</code>. This field is omitted if no NFT is present.</td></tr><tr><td>Commitment</td><td>The commitment contents of the NFT held in this output (<code>0</code> to <code>40</code> bytes). This field is omitted if no NFT is present.</td></tr><tr><td>Amount</td><td>The number of fungible tokens held in this output (an integer between <code>1</code> and <code>9223372036854775807</code>). This field is omitted if no fungible tokens are present.</td></tr></tbody></table> 103<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><strong>Transaction Output JSON Format</strong></summary><div><div class="collapsibleContent_i85q"><p>The following snippet demonstrates a JSON representation of a transaction output using TypeScript types.</p><p>A new, optional <code>token</code> property is added, and the existing <code>lockingBytecode</code> and <code>valueSatoshis</code> properties are unmodified.</p><p>Note, this type is used by the <a href="#test-vectors">test vectors</a>.</p><div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * Data type representing a Transaction Output.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">Output</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">
103{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The bytecode used to encumber this transaction output. To spend the output,</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * unlocking bytecode must be included in a transaction input that â when</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * evaluated before the locking bytecode â completes in a valid state.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * A.K.A. `scriptPubKey` or "locking script"</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> lockingBytecode</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Uint8Array</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The CashToken contents of this output. This property is only defined if the</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * output contains one or more tokens.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> token</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The number of fungible tokens held in this output.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * Because `Number.MAX_SAFE_INTEGER` (`9007199254740991`) is less than the</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * maximum token amount (`9223372036854775807`), this value is encoded as</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * a `bigint`. (Note, because standard JSON does not support `bigint`, this</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * value must be converted to and from a `string` to pass over the network.)</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> amount</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The 32-byte token category ID to which the token(s) in this output belong</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * in big-endian byte order. This is the byte order typically seen in block</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * explorers and user interfaces (as opposed to little-endian byte order,</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * which is used in standard P2P network messages).</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> category</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Uint8Array</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * If present, the non-fungible token (NFT) held by this output. If the</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * output does not include a non-fungible token, `undefined`.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nft</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">
103{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The capability of this non-fungible token.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> capability</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'none'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'mutable'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'minting'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The commitment contents included in the non-fungible token held in</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * this output.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> commitment</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> Uint8Array</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * The value of the output in satoshis, the smallest unit of bitcoin cash.</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> valueSatoshis</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div></div></div></details> 104<h2 class="anchor anchorWithStickyNavbar_LWe7" id="technical-specification">Technical Specification<a href="#technical-specification" class="hash-l
104ink" aria-label="Direct link to Technical Specification" title="Direct link to Technical Specification" translate="no">â</a></h2> 105<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><strong>Subsections</strong></summary><div><div class="collapsibleContent_i85q"><ul> 106<li><a href="#token-categories">Token Categories</a></li> 107<li><a href="#token-types">Token Types</a></li> 108<li><a href="#token-behavior">Token Behavior</a> 109<ul> 110<li><a href="#universal-token-behavior">Universal Token Behavior</a></li> 111<li><a href="#non-fungible-token-behavior">Non-Fungible Token Behavior</a></li> 112<li><a href="#fungible-token-behavior">Fungible Token Behavior</a></li> 113</ul> 114</li> 115<li><a href="#token-encoding">Token Encoding</a> 116<ul> 117<li><a href="#token-prefix">Token Prefix</a></li> 118<li><a href="#token-prefix-validation">Token Prefix Validation</a></li> 119<li><a href="#token-prefix-standardness">Token Prefix Standardness</a></li> 120</ul> 121</li> 122<li><a href="#token-encoding-activation">Token Encoding Activation</a></li> 123<li><a href="#token-aware-transaction-validation">Token-Aware Transaction Validation</a> 124<ul> 125<li><a href="#token-validation-algorithm">Token Validation Algorithm</a></li> 126</ul> 127</li> 128<li><a href="#token-inspection-operations">Token Inspection Operations</a> 129<ul> 130<li><a href="#existing-introspection-operations">Existing Introspection Operations</a></li> 131<li><a href="#interpretation-of-signature-preimage-inspection">Interpretation of Signature Preimage Inspection</a></li> 132</ul> 133</li> 134<li><a href="#signing-serialization-of-tokens">
134Signing Serialization of Tokens</a></li> 135<li><a href="#sighash_utxos"><code>SIGHASH_UTXOS</code></a></li> 136<li><a href="#double-spend-proof-support">Double Spend Proof Support</a></li> 137<li><a href="#cashaddress-token-support">CashAddress Token Support</a></li> 138<li><a href="#token-aware-bip69-sorting-algorithm">Token-Aware BIP69 Sorting Algorithm</a></li> 139<li><a href="#fungible-token-supply-definitions">Fungible Token Supply Definitions</a> 140<ul> 141<li><a href="#genesis-supply">Genesis Supply</a></li> 142<li><a href="#total-supply">Total Supply</a></li> 143<li><a href="#reserved-supply">Reserved Supply</a></li> 144<li><a href="#circulating-supply">Circulating Supply</a></li> 145</ul> 146</li> 147</ul></div></div></details> 148<p>Token primitives are defined, token encoding and activation are specified, and six new token inspection opcodes are introduced. Transaction validation and transaction signing serialization is modified to support tokens, <code>SIGHASH_UTXOS</code> is specified, BIP69 sorting is extended to support tokens, and CashAddress <code>types</code> with token support are defined.</p> 149<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-categories">Token Categories<a href="#token-categories" class="hash-link" aria-label="Direct link to Token Categories" title="Direct link to Token Categories" translate="no">â</a></h3> 150<p>Every token belongs to a <strong>token category</strong> specified via an immutable, 32-byte <strong>Token Category ID</strong> assigned in the category's <strong>genesis transaction</strong> â the transaction in which the token category is initially created.</p> 151<p>Every token category ID is a transaction ID: the ID must be selected from the inputs of its genesis transaction, and only <strong>token genesis inputs</strong> â inputs which spend output <code>0</code> of their parent transaction â are eligible (i.e. outpoint transaction hashes of inputs with an outpoint index of <code>0</code>). As such, implementations can locate the genesis transaction of any category by identifying the transaction that spent the <code>0</code>th output of the transaction referenced by the category ID. (See <a href="/docs/spec/rationale#use-of-transaction-ids-as-token-category-ids">Use of Transaction IDs as Token Category IDs</a>.)</p> 152<p>Note that because every transaction has at least one output, every transaction ID can later become a token category ID.</p> 153<p><img decoding="async" loading="lazy" alt="CashToken Creation" src="/assets/images/cashtoken-creation-7803f82e5815936ec7c7aa57eac4f366.svg" width="1440" height="1080" class="img_ev3q"> 154<em>Figure 1. Two new token categories are created by transaction <code>c3a601...</code>. The first category (<span style="color:#8a11b2">â </span><code>b201a0...</code>) is created by spending the 0th output of transaction <code>b201a0...</code>; for this category, a supply of <code>150</code> fungible tokens are created across two outputs (<code>100</code> and <code>50</code>). The second category (<span style="color:#3ab211">â²</span><code>a1efcd...</code>) is created by spending the 0th output of transaction <code>a1efcd...</code>; for this category, a supply of <code>100</code> fungible tokens are created across two outputs (<code>20</code> and <code>80</code>), and two NFTs are created (each with a commitment of <code>0x010203</code>).</em></p> 155<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-types">Token Types<a href="#token-types" class="hash-link" aria-label="Direct link to Token Types" title="Direct link to Token Types" translate="no">â</a></h3> 156<p>Two token types are introduced: <strong>fungible tokens</strong> and <strong>non-fungible tokens</strong>. Fungible tokens have only one property: a 32-byte <code>category</code>. Non-fungible tokens have three properties: a 32-byte <code>category</code>, a <code>0</code> to <code>40</code> byte <code>commitment</code>, and a <code>capability</code> of <code>minting</code>, <code>mutable</code>, or <code>none</code>.</p> 157<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-behavior">
157Token Behavior<a href="#token-behavior" class="hash-link" aria-label="Direct link to Token Behavior" title="Direct link to Token Behavior" translate="no">â</a></h3> 158<p>Token behavior is enforced by the <a href="#token-validation-algorithm"><strong>token validation algorithm</strong></a>. This algorithm has the following effects:</p> 159<h4 class="anchor anchorWithStickyNavbar_LWe7" id="universal-token-behavior">Universal Token Behavior<a href="#universal-token-behavior" class="hash-link" aria-label="Direct link to Universal Token Behavior" title="Direct link to Universal Token Behavior" translate="no">â</a></h4> 160<ol> 161<li>A single transaction can create multiple new token categories, and each category can contain both fungible and non-fungible tokens.</li> 162<li>Tokens can be implicitly destroyed by omission from a transaction's outputs.</li> 163<li>Each transaction output can contain zero or one non-fungible token and any <code>amount</code> of fungible tokens, but all tokens in an output must share the same token category.</li> 164</ol> 165<h4 class="anchor anchorWithStickyNavbar_LWe7" id="non-fungible-token-behavior">Non-Fungible Token Behavior<a href="#non-fungible-token-behavior" class="hash-link" aria-label="Direct link to Non-Fungible Token Behavior" title="Direct link to Non-Fungible Token Behavior" translate="no">â</a></h4> 166<ol> 167<li>A transaction output can contain zero or one <strong>non-fungible token</strong>.</li> 168<li>Non-fungible tokens (NFTs) of a particular category are created either in the category's genesis transaction or by later transactions that spend <code>minting</code> or <code>mutable</code> tokens of the same category.</li> 169<li>It is possible for multiple NFTs of the same category to carry the same commitment. (Though uniqueness can be enforced by covenants.)</li> 170<li><strong>Minting tokens</strong> (NFTs with the <code>minting</code> capability) allow the spending transaction to create any number of new NFTs of the same category, each with any commitment and (optionally) the <code>minting</code> or <code>mutable</code> capability.</li> 171<li>Each <strong>Mutable token</strong> (NFTs with the <code>mutable</code> capability) allows the spending transaction to create one NFT of the same category, with any commitment and (optionally) the <code>mutable</code> capability.</li> 172<li><strong>Immutable tokens</strong> (NFTs without a capability) cannot have their commitment modified when spent.</li> 173</ol> 174<h4 class="anchor anchorWithStickyNavbar_LWe7" id="fungible-token-behavior">Fungible Token Behavior<a href="#fungible-token-behavior" class="hash-link" aria-label="Direct link to Fungible Token Behavior" title="Direct link to Fungible Token Behavior" translate="no">â</a></h4> 175<ol> 176<li>A transaction output can contain any <code>amount</code> of fungible tokens from a single category.</li> 177<li>All fungible tokens of a category are created in that category's genesis transaction; their combined <code>amount</code> may not exceed <code>9223372036854775807</code>.</li> 178<li>A transaction can spend fungible tokens from any number of UTXOs to any number of outputs, so long as the sum of output <code>amount</code>s do not exceed the sum of input <code>amount</code>s (for each token category).</li> 179</ol> 180<p>Note that fungible tokens behave independently from non-fungible tokens: non-fungible tokens are never counted in the <code>amount</code>, and the existence of <code>minting</code> or <code>mutable</code> NFTs in a transaction's inputs do not allow for new fungible tokens to be created.</p> 181<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-encoding">Token Encoding<a href="#token-encoding" class="hash-link" aria-label="Direct link to Token Encoding" title="Direct link to Token Encoding" translate="no">â</a></h3> 182<p>Tokens are encoded in outputs using a <strong>token prefix</strong>, a data structure that can encode a token category, zero or one non-fungible token (NFT), and an amount of fungible tokens (FTs).</p> 183<p>For backwards-compatibility with existing transaction decoding implementations, a transaction output's token prefix (if present) is encoded before index <code>0</code> of its locking bytecode, and the <code>CompactSize</code> length preceding the two fields is increased to cover both fields (such that the length could be renamed <code>token_prefix_and_locking_bytecode_length</code>). The token prefix is not part of the locking bytecode and must not be included in bytecode evaluation. To illustrate, after deployment, the serialized output format becomes:</p> 184<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain"><satoshi_value> <token_prefix_and_locking_bytecode_length> [PREFIX_TOKEN <token_data>] <locking_bytecode></span><br></span></code></pre></div></div> 185<h4 class="anchor anchorWithStickyNavbar_LWe7" id="token-prefix">
185Token Prefix<a href="#token-prefix" class="hash-link" aria-label="Direct link to Token Prefix" title="Direct link to Token Prefix" translate="no">â</a></h4> 186<p><code>PREFIX_TOKEN</code> is defined at codepoint <code>0xef</code> (<code>239</code>) and indicates the presence of a token prefix:</p> 187<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">PREFIX_TOKEN <category_id> <token_bitfield> [nft_commitment_length nft_commitment] [ft_amount]</span><br></span></code></pre></div></div> 188<ol> 189<li><code><category_id></code> â After the <code>PREFIX_TOKEN</code> byte, a 32-byte <strong>Token Category ID</strong> is required, encoded in <code>OP_HASH256</code> byte order<sup>1</sup>.</li> 190<li><code><token_bitfield></code> - A bitfield encoding two 4-bit fields is required:<!-- --> 191<ol> 192<li><code>prefix_structure</code> (<code>token_bitfield & 0xf0</code>) - 4 bitflags, defined at the higher half of the bitfield, indicating the structure of the token prefix:<!-- --> 193<ol> 194<li><code>0x80</code> (<code>0b10000000</code>) - <code>RESERVED_BIT</code>, must be unset.</li> 195<li><code>0x40</code> (<code>0b01000000</code>) - <code>HAS_COMMITMENT_LENGTH</code>, the prefix encodes a commitment length and commitment.</li> 196<li><code>0x20</code> (<code>0b00100000</code>) - <code>HAS_NFT</code>, the prefix encodes a non-fungible token.</li> 197<li><code>0x10</code> (<code>0b00010000</code>) - <code>HAS_AMOUNT</code>, the prefix encodes an amount of fungible tokens.</li> 198</ol> 199</li> 200<li><code>nft_capability</code> (<code>token_bitfield & 0x0f</code>) â A 4-bit value, defined at the lower half of the bitfield, indicating the non-fungible token capability, if present.<!-- --> 201<ol> 202<li>If not <code>HAS_NFT</code>: must be <code>0x00</code>.</li> 203<li>If <code>HAS_NFT</code>:<!-- --> 204<ol> 205<li><code>0x00</code> â No capability â the encoded non-fungible token is an <strong>immutable token</strong>.</li> 206<li><code>0x01</code> â The <strong><code>mutable</code> capability</strong> â the encoded non-fungible token is a <strong>mutable token</strong>.</li> 207<li><code>0x02</code> â The <strong><code>minting</code> capability</strong> â the encoded non-fungible token is a <strong>minting token</strong>.</li> 208<li>Values greater than <code>0x02</code> are reserved and must not be used.</li> 209</ol> 210</li> 211</ol> 212</li> 213</ol> 214</li> 215<li>If <code>HAS_COMMITMENT_LENGTH</code>:<!-- --> 216<ol> 217<li><code>commitment_length</code> â A <strong>commitment length</strong> is required (minimally-encoded in <code>CompactSize</code> format<sup>2</sup>) with a minimum value of <code>1</code> (<code>0x01</code>).</li> 218<li><code>commitment</code> â The non-fungible token's <strong>commitment</strong> byte string of <code>commitment_length</code> is required.</li> 219</ol> 220</li> 221<li>If <code>HAS_AMOUNT</code>:<!-- --> 222<ol> 223<li><code>ft_amount</code> â An amount of <strong>fungible tokens</strong> is required (minimally-encoded in <code>CompactSize</code> format<sup>2</sup>) with a minimum value of <code>1</code> (<code>0x01</code>) and a maximum value equal to the maximum VM number, <code>9223372036854775807</code> (<code>0xffffffffffffff7f</code>).</li> 224</ol> 225</li> 226</ol> 227<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Notes</summary><div><div class="collapsibleContent_i85q"><ol> 228<li>This is the byte order produced/required by all BCH VM operations which employ SHA-256 (including <code>OP_SHA256</code> and <code>OP_HASH256</code>), the byte order used for outpoint transaction hashes in the P2P transaction format, and the byte order produced by most SHA-256 libraries. For reference, the genesis block header in this byte order is little-endian â <code>6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000</code>
228 â and can be produced by this script: <code><0x0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c> OP_HASH256</code>. (Note, this is the opposite byte order as is commonly used in user interfaces like block explorers.)</li> 229<li>The <strong><code>CompactSize</code> Format</strong> is a variable-length, little-endian, positive integer format used to indicate the length of the following byte array in Bitcoin Cash P2P protocol message formats (present since the protocol's publication in 2008). The format historically allowed some values to be encoded in multiple ways; token prefixes must always use minimally-encoded/canonically-encoded <code>CompactSize</code>s, e.g. the value <code>1</code> must be encoded as <code>0x01</code> rather than <code>0xfd0100</code>, <code>0xfe0100000</code>, or <code>0xff010000000000000</code>.</li> 230</ol></div></div></details> 231<h4 class="anchor anchorWithStickyNavbar_LWe7" id="token-prefix-validation">Token Prefix Validation<a href="#token-prefix-validation" class="hash-link" aria-label="Direct link to Token Prefix Validation" title="Direct link to Token Prefix Validation" translate="no">â</a></h4> 232<ol> 233<li>By consensus, <code>commitment_length</code> is limited to <code>40</code> (<code>0x28</code>), but future upgrades may increase this limit. Implementers are advised to ensure that values between <code>253</code> (<code>0xfdfd00</code>) and <code>65535</code> (<code>0xfdffff</code>) can be parsed. (See <a href="/docs/spec/rationale#non-fungible-token-commitment-length">Non-Fungible Token Commitment Length</a>.)</li> 234<li>A token prefix encoding no tokens (both <code>HAS_NFT</code> and <code>HAS_AMOUNT</code> are unset) is invalid.</li> 235<li>A token prefix encoding <code>HAS_COMMITMENT_LENGTH</code> without <code>HAS_NFT</code> is invalid.</li> 236<li>A token prefix where <code>HAS_NFT</code> is unset must encode <code>nft_capability</code> of <code>0x00</code>.</li> 237</ol> 238<h4 class="anchor anchorWithStickyNavbar_LWe7" id="token-prefix-standardness">Token Prefix Standardness<a href="#token-prefix-standardness" class="hash-link" aria-label="Direct link to Token Prefix Standardness" title="Direct link to Token Prefix Standardness" translate="no">â</a></h4> 239<p>Implementations must recognize otherwise-standard outputs with token prefixes as <strong>standard</strong>.</p> 240<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><strong>Token Prefix Encoding Test Vectors</strong></summary><div><div class="collapsibleContent_i85q"><p>The following test vectors demonstrate valid, reserved, and invalid token prefix encodings. The token category ID is <code>0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code> and commitments use repetitions of <code>0xcc</code>.</p><p>For the complete set of test vectors, see <a href="#test-vectors">Test Vectors</a>.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="valid-token-prefix-encodings">Valid Token Prefix Encodings<a href="#valid-token-prefix-encodings" class="hash-link" aria-label="Direct link to Valid Token Prefix Encodings" title="Direct link to Valid Token Prefix Encodings" translate="no">â</a></h4><table><thead><tr><th>Description</th><th>Encoded (Hex)</th></tr></thead><tbody><tr><td>no NFT; 1 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb1001</code></td></tr><tr><td>no NFT; 252 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10fc</code></td></tr><tr><td>no NFT; 253 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10fdfd00</code></td></tr><tr><td>no NFT; 9223372036854775807 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10ffffffffffffffff7f</code></td></tr><tr><td>0-byte immutable NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb20</code></td></tr><tr><td>0-byte immutable NFT; 1 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb3001</code></td></tr><tr><td>0-byte immutable NFT; 253 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb30fdfd00</code></td></tr><tr><td>0-byte immutable NFT; 9223372036854775807 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb30ffffffffffffffff7f</code></td></tr><tr><td>1-byte immutable NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6001cc</code></td></tr><tr><td>1-byte immutable NFT; 252 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7001ccfc</code></td></tr><tr><td>2-byte immutable NFT; 253 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7002ccccfdfd00</code></td></tr><tr><td>10-byte immutable NFT; 65535 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb700accccccccccccccccccccfdffff</code></td></tr><tr><td>40-byte immutable NFT; 65536 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7028ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccfe00000100</code></td></tr><tr><td>0-byte, mutable NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb21</code></td></tr><tr><td>0-byte, mutable NFT; 4294967295 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb31feffffffff</code></td></tr><tr><td>1-byte, mutable NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6101cc</code></td></tr><tr><td>1-byte, mutable NFT; 4294967296 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7101ccff0000000001000000</code></td></tr><tr><td>2-byte, mutable NFT; 9223372036854775807 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7102ccccffffffffffffffff7f</code></td></tr><tr><td>10-byte, mutable NFT; 1 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb710acccccccccccccccccccc01</code></td></tr><tr><td>40-byte, mutable NFT; 252 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7128ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccfc</code></td></tr><tr><td>0-byte, minting NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb22</code></td></tr><tr><td>0-byte, minting NFT; 253 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb32fdfd00</code></td></tr><tr><td>1-byte, minting NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6201cc</code></td></tr><tr><td>1-byte, minting NFT; 65535 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7201ccfdffff</code></td></tr><tr><td>2-byte, minting NFT; 65536 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7202ccccfe00000100</code></td></tr><tr><td>10-byte, minting NFT; 4294967297 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb720accccccccccccccccccccff0100000001000000</code></td></tr><tr><td>40-byte, minting NFT; 9223372036854775807 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7228ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccffffffffffffffff7f</code></td></tr></tbody></table><h5 class="anchor anchorWithStickyNavbar_LWe7" id="reserved-token-prefix-encodings">Reserved Token Prefix Encodings<a href="#reserved-token-prefix-encodings" class="hash-l
240ink" aria-label="Direct link to Reserved Token Prefix Encodings" title="Direct link to Reserved Token Prefix Encodings" translate="no">â</a></h5><p>These encodings are valid but disabled due to excessive <code>commitment_length</code>s. Transactions attempting to create outputs with these token prefixes are currently rejected by consensus, but future upgrades may increase the maximum valid <code>commitment_length</code>.</p><table><thead><tr><th>Description</th><th>Encoded (Hex)</th></tr></thead><tbody><tr><td>41-byte immutable NFT; 65536 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7029ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccfe00000100</code></td></tr><tr><td>41-byte, mutable NFT; 252 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7129ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccfc</code></td></tr><tr><td>41-byte, minting NFT; 9223372036854775807 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7229ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccffffffffffffffff7f</code></td></tr><tr><td>253-byte, immutable NFT; 0 fungible</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60fdfd00cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</code></td></tr></tbody></table><h4 class="anchor anchorWithStickyNavbar_LWe7" id="invalid-token-prefix-encodings">Invalid Token Prefix Encodings<a href="#invalid-token-prefix-encodings" class="hash-link" aria-label="Direct link to Invalid Token Prefix Encodings" title="Direct link to Invalid Token Prefix Encodings" translate="no">â</a></h4><table><thead><tr><th>Reason</th><th>Encoded (Hex)</th></tr></thead><tbody><tr><td>Token prefix must encode at least one token</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb00</code></td></tr><tr><td>Token prefix must encode at least one token (0 fungible)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb1000</code></td></tr><tr><td>Token prefix requires a token category ID</td><td><code>ef</code></td></tr><tr><td>Token category IDs must be 32 bytes</td><td><code>efbbbbbbbb1001</code></td></tr><tr><td>Missing token bitfield</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td></tr><tr><td>Token bitfield sets reserved bit</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb9001</code></td></tr><tr><td>Unknown capability (0-byte NFT, capability 3)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb23</code></td></tr><tr><td>Has commitment length without NFT (1 fungible)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb5001</code></td></tr><tr><td>Prefix encodes a capability without an NFT</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb1101</code></td></tr><tr><td>Commitment length must be specified (immutable token)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60</code></td></tr><tr><td>Commitment length must be specified (mutable token)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb61</code></td></tr><tr><td>Commitment length must be specified (minting token)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb62</code></td></tr><tr><td>Commitment length must be minimally-encoded</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb60fd0100cc</code></td></tr><tr><td>If specified, commitment length must be greater than 0</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6000</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy commitment length (0/1 bytes)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6001</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy commitment length (mutable token, 0/1 bytes)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6101</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy commitment length (mutable token, 1/2 bytes)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6102cc</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy commitment length (minting token, 1/2 bytes)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb6202cc</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (no NFT, 1-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (no NFT, 2-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10fd00</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (no NFT, 4-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10fe000000</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (no NFT, 8-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10ff00000000000000</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (immutable NFT, 1-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7001cc</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (immutable NFT, 2-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7001ccfd00</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (immutable NFT, 4-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7001ccfe000000</code></td></tr><tr><td>Not enough bytes remaining in locking bytecode to satisfy token amount (immutable NFT, 8-byte amount)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb7001ccff00000000000000</code></td></tr><tr><td>Token amount must be specified</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb30</code></td></tr><tr><td>If specified, token amount must be greater than 0 (no NFT)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb1000</code></td></tr><tr><td>If specified, token amount must be greater than 0 (0-byte NFT)</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb3000</code></td></tr><tr><td>Token amount must be minimally-encoded</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb10fd0100</code></td></tr><tr><td>Token amount (9223372036854775808) may not exceed 9223372036854775807</td><td><code>efbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb30ff0000000000000080</code></td></tr></tbody></table></div></div></details> 241<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-encoding-activation">Token Encoding Activation<a href="#token-encoding-activation" class="hash-l
241ink" aria-label="Direct link to Token Encoding Activation" title="Direct link to Token Encoding Activation" translate="no">â</a></h3> 242<p><strong>Pre-activation token-forgery outputs (PATFOs)</strong> are transaction outputs mined in blocks prior to activation of this specification where locking bytecode index <code>0</code> is set to the <code>PREFIX_TOKEN</code> codepoint.</p> 243<p>Prior to activation, PATFOs remain <strong>nonstandard</strong> but do not invalidate the transaction by consensus. Because they can still be mined in valid blocks, PATFOs can be used to prepare outputs that, after activation of this specification, could encode tokens for which <a href="#token-aware-transaction-validation">Token-Aware Transaction Validation</a> was not enforced (producing token categories that do not map to a confirmed transaction hash or have a fungible token supply exceeding the maximum amount).</p> 244<p>Note, even properly-encoded token outputs included in transactions mined prior to activation are considered PATFOs, regardless of whether or not the transaction would pass token-aware transaction validation after activation. Due to the possibility of a chain re-organization impacting the precise activation time, token issuers are advised to wait until activation is confirmed to a depth of at least 11 blocks before broadcasting critical transactions involving tokens.</p> 245<p>PATFOs are provably unspendable<sup>1</sup>; all software implementing this specification should immediately mark PATFOs as unspendable and/or logically treat them as such for the purposes of spending.</p> 246<p><strong>By consensus, PATFOs mined in blocks prior to the activation of <a href="#token-aware-transaction-validation">Token-Aware Transaction Validation</a> must remain unspendable after activation</strong>. (Please note: the presence of PATFOs does not render a transaction invali
246d; until activation, valid blocks may contain PATFOs.)</p> 247<p>After activation, any transaction creating an invalid token prefix<sup>2</sup> is itself invalid, and all transactions must pass <a href="#token-aware-transaction-validation">Token-Aware Transaction Validation</a>.</p> 248<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Notes</summary><div><div class="collapsibleContent_i85q"><ol> 249<li>For pre-activation token-forgery outputs (PATFOs), this has been the case for even longer than <code>OP_RETURN</code> outputs: PATFOs have been provably unspendable since the Bitcoin Cash protocol's publication in 2008.</li> 250<li>That is, any transaction output where locking bytecode index <code>0</code> is set to the <code>PREFIX_TOKEN</code> codepoint, but a valid token prefix cannot be parsed.</li> 251</ol></div></div></details> 252<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-aware-transaction-validation">Token-Aware Transaction Validation<a href="#token-aware-transaction-validation" class="hash-link" aria-label="Direct link to Token-Aware Transaction Validation" title="Direct link to Token-Aware Transaction Validation" translate="no">â</a></h3> 253<p>For any transaction to be valid, the <a href="#token-validation-algorithm"><strong>token validation algorithm</strong></a> must succeed.</p> 254<h4 class="anchor anchorWithStickyNavbar_LWe7" id="token-validation-algorithm">Token Validation Algorithm<a href="#token-validation-algorithm" class="hash-link" aria-label="Direct link to Token Validation Algorithm" title="Direct link to Token Validation Algorithm" translate="no">â</a></h4> 255<p>Given the following <strong>definitions</strong>:</p> 256<ol> 257<li>Reducing the set of UTXOs spent by the transaction:<!-- --> 258<ol> 259<li>A key-value map of <strong><code>Available_Sums_By_Category</code></strong> (mapping category IDs to positive, 64-bit integers) is created by summing the input <code>amount</code> of each token category.</li> 260<li>A key-value map of <strong><code>Available_Mutable_Tokens_By_Category</code></strong> (mapping category IDs to positive integers) is created by summing the count of input mutable tokens for each category.</li> 261<li>A list of <strong><code>Genesis_Categories</code></strong> is created including the outpoint transaction hash of each input with an outpoint index of <code>0</code> (i.e. the spent UTXO was the 0th output in its transaction).</li> 262<li>A de-duplicated list of <strong><code>Input_Minting_Categories</code></strong> is created including the category ID of each input minting token.</li> 263<li>A list of <strong><code>Available_Minting_Categories</code></strong> is the combination of <code>Genesis_Categories</code> and <code>Input_Minting_Categories</code>.</li> 264<li>A list of all <strong><code>Available_Immutable_Tokens</code></strong> (including duplicates) is created including each NFT which <strong>does not</strong> have a <code>minting</code> or <code>mutable</code> capability.</li> 265</ol> 266</li> 267<li>Reducing the set of outputs created by the transaction:<!-- --> 268<ol> 269<li>A key-value map of <strong><code>Output_Sums_By_Category</code></strong> (mapping category IDs to positive, 64-bit integers) is created by summing the output <code>amount</code> of each token category.</li> 270<li>A key-value map of <strong><code>Output_Mutable_Tokens_By_Category</code></strong> (mapping category IDs to positive integers) is created by summing the count of output mutable tokens for each category.</li> 271<li>A de-duplicated list of <strong><code>Output_Minting_Categories</code></strong> is created including the category ID of each output minting token.</li> 272<li>A list of all <strong><code>Output_Immutable_Tokens</code></strong> (including duplicates) is created including each NFT which <strong>does not</strong> have a <code>minting</code> or <code>mutable</code> capability.</li> 273</ol> 274</li> 275</ol> 276<p>Perform the following <strong>validations</strong>:</p> 277<ol> 278<li>Each category in <code>Output_Minting_Categories</code> must exist in <code>Available_Minting_Categories</code>.</li> 279<li>Each category in <code>Output_Sums_By_Category</code> must either:<!-- --> 280<ol> 281<li>Have an equal or greater sum in <code>Available_Sums_By_Category</code>, or</li> 282<li>Exist in <code>Genesis_Categories</code> and have an output sum no greater than <code>9223372036854775807</code> (the maximum VM number).</li> 283</ol> 284</li> 285<li>For each category in <code>Output_Mutable_Tokens_By_Category</code>, if the token's category ID exists in <code>Available_Minting_Categories</code>, skip this (valid) category. Else:<!-- --> 286<ol> 287<li>Deduct the sum in <code>Output_Mutable_Tokens_By_Category</code> from the sum available in <code>Available_Mutable_Tokens_By_Category</code>. If the value falls below <code>0</code>, <strong>fail validation</strong>.</li> 288</ol> 289</li> 290<li>For each token in <code>Output_Immutable_Tokens</code>, if the token's category ID exists in <code>Available_Minting_Categories</code>, skip this (valid) token. Else:<!-- --> 291<ol> 292<li>If an equivalent token exists in <code>Available_Immutable_Tokens</code> (comparing both category ID and commitment), remove it and continue to the next token. Else:<!-- --> 293<ol> 294<li>Deduct <code>1</code> from the sum available for the token's category in <code>Available_Mutable_Tokens_By_Category</code>. If no mutable tokens are available to downgrade, <strong>fail validation</strong>.</li> 295</ol> 296</li> 297</ol> 298</li> 299</ol> 300<p>Note: because coinbase transactions have only one input with an outpoint index of <code>4294967295</code>, coinbase transactions can never include a token prefix in any output.</p> 301<p>See <a href="#implementations">Implementations</a> for examples of this algorithm in multiple programming languages.</p> 302<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-inspection-operations">Token Inspection Operations<a href="#token-inspection-operations" class="hash-l
302ink" aria-label="Direct link to Token Inspection Operations" title="Direct link to Token Inspection Operations" translate="no">â</a></h3> 303<p>The following 6 operations pop the top item from the stack as an index (VM Number) and push a single result to the stack. If the consumed value is not a valid, minimally-encoded index for the operation, an error is produced.</p> 304<table><thead><tr><th>Name</th><th>Codepoint</th><th>Description</th></tr></thead><tbody><tr><td><code>OP_UTXOTOKENCATEGORY</code></td><td><code>0xce</code> (<code>206</code>)</td><td>Pop the top item from the stack as an input index (VM Number). If the Unspent Transaction Output (UTXO) spent by that input includes no tokens, push a 0 (VM Number) to the stack. If the UTXO does not include a non-fungible token with a capability, push the UTXO's token category, otherwise, push the concatenation of the token category and capability, where the mutable capability is represented by 1 (VM Number) and the minting capability is represented by 2 (VM Number).</td></tr><tr><td><code>OP_UTXOTOKENCOMMITMENT</code></td><td><code>0xcf</code> (<code>207</code>)</td><td>Pop the top item from the stack as an input index (VM Number). Push the token commitment of the Unspent Transaction Output (UTXO) spent by that input to the stack. If the UTXO does not include a non-fungible token, or if it includes a non-fungible token with a zero-length commitment, push a 0 (VM Number).</td></tr><tr><td><code>OP_UTXOTOKENAMOUNT</code></td><td><code>0xd0</code> (<code>208</code>)</td><td>Pop the top item from the stack as an input index (VM Number). Push the fungible token amount of the Unspent Transaction Output (UTXO) spent by that input to the stack as a VM Number. If the UTXO includes no fungible tokens, push a 0 (VM Number).</td></tr><tr><td><code>OP_OUTPUTTOKENCATEGORY</code></td><td><code>0xd1</code> (<code>209</code>)</td><td>Pop the top item from the stack as an output index (VM Number). If the output at that index includes no tokens, push a 0 (VM Number) to the stack. If the output does not include a non-fungible token with a capability, push the output's token category, otherwise, push the concatenation of the token category and capability, where the mutable capability is represented by 1 (VM Number) and the minting capability is represented by 2 (VM Number).</td></tr><tr><td><code>OP_OUTPUTTOKENCOMMITMENT</code></td><td><code>0xd2</code> (<code>210</code>)</td><td>Pop the top item from the stack as an output index (VM Number). Push the token commitment of the output at that index to the stack. If the output does not include a non-fungible token, or if it includes a non-fungible token with a zero-length commitment, push a 0 (VM Number).</td></tr><tr><td><code>OP_OUTPUTTOKENAMOUNT</code></td><td><code>0xd3</code> (<code>211</code>)</td><td>Pop the top item from the stack as an output index (VM Number). Push the fungible token amount of the output at that index to the stack as a VM Number. If the output includes no fungible tokens, push a 0 (VM Number).</td></tr></tbody></table> 305<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><strong>Token Inspection Operation Test Vectors</strong></summary><div><div class="collapsibleContent_i85q"><p>The following test vectors demonstrate the expected result of each token inspection operation for a particular output. The token category ID is <code>0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code> and commitments use repetitions of <code>0xcc</code>.</p><p>For the complete set of test vectors, see <a href="#test-vectors">Test Vectors</a>.</p><table><thead><tr><th>Description</th><th><code>OP_UTXOTOKENCATEGORY</code>/<code>OP_OUTPUTTOKENCATEGORY</code> (Hex)</th><th><code>OP_UTXOTOKENCOMMITMENT</code>/<code>OP_OUTPUTTOKENCOMMITMENT</code> (Hex)</th><th><code>OP_UTXOTOKENAMOUNT</code>/<code>OP_OUTPUTTOKENAMOUNT</code> (Hex)</th></tr></thead><tbody><tr><td>no NFT; 0 fungible</td><td>(empty item)</td><td>(empty item)</td><td>(empty item)</td></tr><tr><td>no NFT; 1 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>01</code></td></tr><tr><td>no NFT; 252 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>fc</code></td></tr><tr><td>no NFT; 253 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>fd00</code></td></tr><tr><td>no NFT; 9223372036854775807 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>ffffffffffffff7f</code></td></tr><tr><td>0-byte immutable NFT; 0 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td>(empty item)</td></tr><tr><td>0-byte immutable NFT; 1 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>01</code></td></tr><tr><td>0-byte immutable NFT; 253 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>fd00</code></td></tr><tr><td>0-byte immutable NFT; 9223372036854775807 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td>(empty item)</td><td><code>ffffffffffffff7f</code></td></tr><tr><td>1-byte immutable NFT; 252 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td><code>cc</code></td><td><code>fc</code></td></tr><tr><td>2-byte immutable NFT; 253 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td><code>cccc</code></td><td><code>fd00</code></td></tr><tr><td>10-byte immutable NFT; 65535 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td><code>cccccccccccccccccccc</code></td><td><code>ffff</code></td></tr><tr><td>40-byte immutable NFT; 65536 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</code></td><td><code>cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</code></td><td><code>00000100</code></td></tr><tr><td>0-byte, mutable NFT; 0 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01</code></td><td>(empty item)</td><td>(empty item)</td></tr><tr><td>0-byte, mutable NFT; 4294967295 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01</code></td><td>(empty item)</td><td><code>ffffffff</code></td></tr><tr><td>1-byte, mutable NFT; 4294967296 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01</code></td><td><code>cc</code></td><td><code>0000000001000000</code></td></tr><tr><td>2-byte, mutable NFT; 9223372036854775807 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01</code></td><td><code>cccc</code></td><td><code>ffffffffffffff7f</code></td></tr><tr><td>10-byte, mutable NFT; 1 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01</code></td><td><code>cccccccccccccccccccc</code></td><td><code>01</code></td></tr><tr><td>40-byte, mutable NFT; 252 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb01</code></td><td><code>cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</code></td><td><code>fc</code></td></tr><tr><td>0-byte, minting NFT; 0 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb02</code></td><td>(empty item)</td><td>(empty item)</td></tr><tr><td>0-byte, minting NFT; 253 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb02</code></td><td>(empty item)</td><td><code>fd00</code></td></tr><tr><td>1-byte, minting NFT; 65535 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb02</code></td><td><code>cc</code></td><td><code>ffff</code></td></tr><tr><td>2-byte, minting NFT; 65536 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb02</code></td><td><code>cccc</code></td><td><code>00000100</code></td></tr><tr><td>10-byte, minting NFT; 4294967297 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb02</code></td><td><code>cccccccccccccccccccc</code></td><td><code>0100000001000000</code></td></tr><tr><td>40-byte, minting NFT; 9223372036854775807 fungible</td><td><code>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb02</code></td><td><code>cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</code></td><td><code>ffffffffffffff7f</code></td></tr></tbody></table></div></div></details> 306<h4 class="anchor anchorWithStickyNavbar_LWe7" id="existing-introspection-operations">Existing Introspection Operations<a href="#existing-introspection-operations" class="hash-l
306ink" aria-label="Direct link to Existing Introspection Operations" title="Direct link to Existing Introspection Operations" translate="no">â</a></h4> 307<p>Note, this specification has <strong>no impact on the behavior of <a href="https://gitlab.com/GeneralProtocols/research/chips/-/blob/master/CHIP-2021-02-Add-Native-Introspection-Opcodes.md" target="_blank" rel="noopener noreferrer"><code>OP_UTXOBYTECODE</code>, <code>OP_ACTIVEBYTECODE</code>, or <code>OP_OUTPUTBYTECODE</code></a></strong>. Each operation continues to return only the contents of the respective bytecode, excluding both the <code>CompactSize</code>-encoded "<code>token_prefix_and_locking_bytecode_length</code>" and the token prefix (if present).</p> 308<h4 class="anchor anchorWithStickyNavbar_LWe7" id="interpretation-of-signature-preimage-inspection">Interpretation of Signature Preimage Inspection<a href="#interpretation-of-signature-preimage-inspection" class="hash-link" aria-label="Direct link to Interpretation of Signature Preimage Inspection" title="Direct link to Interpretation of Signature Preimage Inspection" translate="no">â</a></h4> 309<p>It is possible to design contracts which inefficiently inspect the encoding of tokens using <strong>signature preimage inspection</strong> â inspecting the contents of a preimage for which a signature passes both <code>OP_CHECKSIG(VERIFY)</code> and <code>OP_CHECKDATASIG(VERIFY)</code>.</p> 310<p>This specification interprets all signature preimage inspection of tokens as <strong>intentional</strong>: these constructions are designed to succeed or fail based on the encoding of the signature preimage, and they can be used (by design) to test for 1) the availability of some types of proposed-but-not-activated upgrades, and/or 2) a contracts' presence on a fork of Bitcoin Cash. This notice codifies a network policy: the possible existence of these contracts will not preclude future upgrades from adding additional output prefix or transaction formats. (The security of a contract is the responsibility of the entity locking funds in that contract; funds can always be locked in insecure contracts, e.g. <code>OP_DROP OP_1</code>.)</p> 311<p>Contract authors are advised to use <a href="#token-inspection-operations">Token Inspection Operations</a>
311 for all constructions intended to inspect the actual properties of tokens within a transaction.</p> 312<h3 class="anchor anchorWithStickyNavbar_LWe7" id="signing-serialization-of-tokens">Signing Serialization of Tokens<a href="#signing-serialization-of-tokens" class="hash-link" aria-label="Direct link to Signing Serialization of Tokens" title="Direct link to Signing Serialization of Tokens" translate="no">â</a></h3> 313<p>The <a href="https://github.com/bitcoincashorg/bitcoincash.org/blob/3e2e6da8c38dab7ba12149d327bc4b259aaad684/spec/replay-protected-sighash.md" target="_blank" rel="noopener noreferrer">signing serialization algorithm</a> (A.K.A <code>SIGHASH</code> algorithm) is enhanced to support tokens: when evaluating a UTXO that includes tokens, the full, <a href="#token-encoding">encoded token prefix</a> (including <code>PREFIX_TOKEN</code>) must be included immediately before the <code>coveredBytecode</code> (A.K.A. <code>scriptCode</code>). Note: this behavior applies for all signing serialization types in the evaluation; it does not require a signing serialization type/flag.</p> 314<h3 class="anchor anchorWithStickyNavbar_LWe7" id="sighash_utxos"><code>SIGHASH_UTXOS</code><a href="#sighash_utxos" class="hash-link" aria-label="Direct link to sighash_utxos" title="Direct link to sighash_utxos" translate="no">â</a></h3> 315<p>A new signing serialization type, <code>SIGHASH_UTXOS</code>, is defined at <code>0x20</code> (<code>32</code>/<code>0b100000</code>). When <code>SIGHASH_UTXOS</code> is enabled, <code>hashUtxos</code> is inserted in the <a href="https://github.com/bitcoincashorg/bitcoincash.org/blob/3e2e6da8c38dab7ba12149d327bc4b259aaad684/spec/replay-protected-sighash.md" target="_blank" rel="noopener noreferrer">signing serialization algorithm</a> immediately following <code>hashPrevouts</code>. <code>hashUtxos</code> is a 32-byte double SHA256 of the serialization of all UTXOs spent by the transaction's inputs, concatenated in input order, excluding output count. (Note: this serialization is equivalent to the segment of a P2P transaction message beginning after <code>output count</code> and ending before <code>locktime</code> if the UTXOs were serialized in order as the transaction's outputs.)</p> 316<p>The <code>SIGHASH_UTXOS</code> and <code>SIGHASH_ANYONECANPAY</code> types must not be used together; if a signature in which both flags are enabled is encountered during VM evaluation, an error is emitted (evaluation fails).</p> 317<p>The <code>SIGHASH_UTXOS</code> type must be used with the <code>SIGHASH_FORKID</code> type; if a signature is encountered during VM evaluation with the <code>SIGHASH_UTXOS</code> flag and without the <code>SIGHASH_FORKID</code> flag, an error is emitted (evaluation fails).</p> 318<p><strong>For security, wallets should enable <code>SIGHASH_UTXOS</code> when participating in multi-entity transactions</strong>. This includes both 1) transactions where signatures are collected from multiple keys and assembled into a single transaction, and 2) transactions involving contracts that can be influenced by multiple entities (e.g. covenants). (See <a href="/docs/spec/rationale#recommendation-of-sighashutxos-for-multi-entity-transactions">Recommendation of <code>SIGHASH_UTXOS</code> for Multi-Entity Transactions</a>.)</p> 319<h3 class="anchor anchorWithStickyNavbar_LWe7" id="double-spend-proof-support">Double Spend Proof Support<a href="#double-spend-proof-support" class="hash-link" aria-label="Direct link to Double Spend Proof Support" title="Direct link to Double Spend Proof Support" translate="no">â</a></h3> 320<p>Transactions employing <code>SIGHASH_UTXOS</code> and transactions spending outputs containing tokens are not protected by either of the <a href="https://documentation.cash/protocol/network/messages/dsproof-beta" target="_blank" rel="noopener noreferrer">beta specifications for Double Spend Proofs (DSP)</a>. Support for these features are left to future proposals.</p> 321<h3 class="anchor anchorWithStickyNavbar_LWe7" id="cashaddress-token-support">CashAddress Token Support<a href="#cashaddress-token-support" class="hash-l
321ink" aria-label="Direct link to CashAddress Token Support" title="Direct link to CashAddress Token Support" translate="no">â</a></h3> 322<p>Two new <a href="https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md#version-byte" target="_blank" rel="noopener noreferrer"><code>CashAddress</code> types</a> are specified to indicate support for accepting tokens:</p> 323<table><thead><tr><th>Type Bits</th><th>Meaning</th></tr></thead><tbody><tr><td><code>2</code> (<code>0b0010</code>)</td><td>Token-Aware P2PKH</td></tr><tr><td><code>3</code> (<code>0b0011</code>)</td><td>Token-Aware P2SH</td></tr></tbody></table> 324<p><strong>Token-aware wallet software</strong> â wallet software which supports management of tokens â may use these CashAddress version byte values to signal token support.</p> 325<p>Token-aware wallet software <strong>must refuse to send tokens to addresses without explicit token support</strong> i.e. <code>P2PKH</code> CashAddresses (type bits: <code>0b0000</code>), <code>P2SH</code> CashAddresses (type bits: <code>0b0001</code>), and legacy Base58 addresses.</p> 326<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary><strong>Token-Aware CashAddress Test Vectors</strong></summary><div><div class="collapsibleContent_i85q"><p>Test vectors for the CashAddress format have been <a href="https://github.com/bitcoincashorg/bitcoincash.org/blob/3e2e6da8c38dab7ba12149d327bc4b259aaad684/spec/cashaddr.md" target="_blank" rel="noopener noreferrer">standardized and widely used since 2017</a>, including test vectors for not-yet-defined <code>type</code> values.</p><p>While this specification simply uses the available <code>type</code> values, to assist implementers, the below test vectors have been added to the existing CashAddress test vectors in <a href="/assets/files/cashaddr-d8176be1cb96aeb1b7734d18b362df44.json" target="_blank"><code>test-vectors/cashaddr.json</code></a>. (For details, see <a href="#test-vectors">Test Vectors</a>.)</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="token-aware-cashaddresses">Token-Aware CashAddresses<a href="#token-aware-cashaddresses" class="hash-link" aria-label="Direct link to Token-Aware CashAddresses" title="Direct link to Token-Aware CashAddresses" translate="no">â</a></h4><table><thead><tr><th>CashAddress</th><th>Type Bits</th><th>Size Bits</th><th>Payload (Hex)</th></tr></thead><tbody><tr><td><code>bitcoincash:qr7fzmep8g7h7ymfxy74lgc0v950j3r2959lhtxxsl</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>bitcoincash:zr7fzmep8g7h7ymfxy74lgc0v950j3r295z4y4gq0v</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>bchtest:qr7fzmep8g7h7ymfxy74lgc0v950j3r295pdnvy3hr</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>bchtest:zr7fzmep8g7h7ymfxy74lgc0v950j3r295x8qj2hgs</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>bchreg:qr7fzmep8g7h7ymfxy74lgc0v950j3r295m39d8z59</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>bchreg:zr7fzmep8g7h7ymfxy74lgc0v950j3r295umknfytk</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>prefix:qr7fzmep8g7h7ymfxy74lgc0v950j3r295fu6e430r</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>prefix:zr7fzmep8g7h7ymfxy74lgc0v950j3r295wkf8mhss</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>fc916f213a3d7f1369313d5fa30f6168f9446a2d</code></td></tr><tr><td><code>bitcoincash:qpagr634w55t4wp56ftxx53xukhqgl24yse53qxdge</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>7a81ea357528bab834d256635226e5ae047d5524</code></td></tr><tr><td><code>bitcoincash:zpagr634w55t4wp56ftxx53xukhqgl24ys77z7gth2</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>7a81ea357528bab834d256635226e5ae047d5524</code></td></tr><tr><td><code>bitcoincash:qq9l9e2dgkx0hp43qm3c3h252e9euugrfc6vlt3r9e</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>0bf2e54d458cfb86b106e388dd54564b9e71034e</code></td></tr><tr><td><code>bitcoincash:zq9l9e2dgkx0hp43qm3c3h252e9euugrfcaxv4l962</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>0bf2e54d458cfb86b106e388dd54564b9e71034e</code></td></tr><tr><td><code>bitcoincash:qre24q38ghy6k3pegpyvtxahu8q8hqmxmqqn28z85p</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>f2aa822745c9ab44394048c59bb7e1c07b8366d8</code></td></tr><tr><td><code>bitcoincash:zre24q38ghy6k3pegpyvtxahu8q8hqmxmq8eeevptj</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>f2aa822745c9ab44394048c59bb7e1c07b8366d8</code></td></tr><tr><td><code>bitcoincash:qz7xc0vl85nck65ffrsx5wvewjznp9lflgktxc5878</code></td><td><code>0</code> (P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>bc6c3d9f3d278b6a8948e06a399974853097e9fa</code></td></tr><tr><td><code>bitcoincash:zz7xc0vl85nck65ffrsx5wvewjznp9lflg3p4x6pp5</code></td><td><code>2</code> (Token-Aware P2PKH)</td><td><code>0</code> (20 bytes)</td><td><code>bc6c3d9f3d278b6a8948e06a399974853097e9fa</code></td></tr><tr><td><code>
326bitcoincash:ppawqn2h74a4t50phuza84kdp3794pq3ccvm92p8sh</code></td><td><code>1</code> (P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>7ae04d57f57b55d1e1bf05d3d6cd0c7c5a8411c6</code></td></tr><tr><td><code>bitcoincash:rpawqn2h74a4t50phuza84kdp3794pq3cct3k50p0y</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>7ae04d57f57b55d1e1bf05d3d6cd0c7c5a8411c6</code></td></tr><tr><td><code>bitcoincash:pqv53dwyatxse2xh7nnlqhyr6ryjgfdtagkd4vc388</code></td><td><code>1</code> (P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>1948b5c4eacd0ca8d7f4e7f05c83d0c92425abea</code></td></tr><tr><td><code>bitcoincash:rqv53dwyatxse2xh7nnlqhyr6ryjgfdtag38xjkhc5</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>1948b5c4eacd0ca8d7f4e7f05c83d0c92425abea</code></td></tr><tr><td><code>bitcoincash:prseh0a4aejjcewhc665wjqhppgwrz2lw5txgn666a</code></td><td><code>1</code> (P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>e19bbfb5ee652c65d7c6b54748170850e1895f75</code></td></tr><tr><td><code>bitcoincash:rrseh0a4aejjcewhc665wjqhppgwrz2lw5vvmd5u9w</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>e19bbfb5ee652c65d7c6b54748170850e1895f75</code></td></tr><tr><td><code>bitcoincash:pzltaslh7xnrsxeqm7qtvh0v53n3gfk0v5wwf6d7j4</code></td><td><code>1</code> (P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>bebec3f7f1a6381b20df80b65deca4671426cf65</code></td></tr><tr><td><code>bitcoincash:rzltaslh7xnrsxeqm7qtvh0v53n3gfk0v5fy6yrcdx</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>0</code> (20 bytes)</td><td><code>bebec3f7f1a6381b20df80b65deca4671426cf65</code></td></tr><tr><td><code>bitcoincash:pvqqqqqqqqqqqqqqqqqqqqqqzg69v7ysqqqqqqqqqqqqqqqqqqqqqpkp7fqn0</code></td><td><code>1</code> (P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>0000000000000000000000000000123456789000000000000000000000000000</code></td></tr><tr><td><code>bitcoincash:rvqqqqqqqqqqqqqqqqqqqqqqzg69v7ysqqqqqqqqqqqqqqqqqqqqqn9alsp2y</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>0000000000000000000000000000123456789000000000000000000000000000</code></td></tr><tr><td><code>bitcoincash:pdzyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3jh2p5nn</code></td><td><code>1</code> (P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>4444444444444444444444444444444444444444444444444444444444444444</code></td></tr><tr><td><code>bitcoincash:rdzyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygrpttc42c</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>4444444444444444444444444444444444444444444444444444444444444444</code></td></tr><tr><td><code>bitcoincash:pwyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsh3sujgcr</code></td><td><code>1</code> (P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>8888888888888888888888888888888888888888888888888888888888888888</code></td></tr><tr><td><code>bitcoincash:rwyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9zvatfpg</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>8888888888888888888888888888888888888888888888888888888888888888</code></td></tr><tr><td><code>bitcoincash:p0xvenxvenxvenxvenxvenxvenxvenxvenxvenxvenxvenxvenxvcm6gz4t77</code></td><td><code>1</code> (P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</code></td></tr><tr><td><code>bitcoincash:r0xvenxvenxvenxvenxvenxvenxvenxvenxvenxvenxvenxvenxvcff5rv284</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</code></td></tr><tr><td><code>bitcoincash:p0llllllllllllllllllllllllllllllllllllllllllllllllll7x3vthu35</code></td><td><code>1</code> (P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</code></td></tr><tr><td><code>bitcoincash:r0llllllllllllllllllllllllllllllllllllllllllllllllll75zs2wagl</code></td><td><code>3</code> (Token-Aware P2SH)</td><td><code>3</code> (32 bytes)</td><td><code>ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</code></td></tr></tbody></table></div></div></details> 327<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-aware-bip69-sorting-algorithm">Token-Aware BIP69 Sorting Algorithm<a href="#token-aware-bip69-sorting-algorithm" class="hash-l
327ink" aria-label="Direct link to Token-Aware BIP69 Sorting Algorithm" title="Direct link to Token-Aware BIP69 Sorting Algorithm" translate="no">â</a></h3> 328<p>The <a href="https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki#transaction-outputs" target="_blank" rel="noopener noreferrer">BIP69 transaction output sorting algorithm</a> is extended to support the sorting of outputs by token information.</p> 329<p>As with the existing algorithm, the additional fields are ordered for sorting efficiency:</p> 330<ol> 331<li>Output value â ascending</li> 332<li>locking bytecode â sorted lexicographically<sup>1</sup>, ascending (e.g. <code>0x51</code> < <code>0x5161</code>)</li> 333<li>token information: (no tokens < has tokens)<!-- --> 334<ol> 335<li>amount â ascending (e.g. <code>0</code> < <code>1</code>)</li> 336<li><code>HAS_NFT</code> â <code>false</code> < <code>true</code> 337<ol> 338<li>capability â ascending; <code>none</code> < <code>mutable</code> < <code>minting</code></li> 339<li>commitment â sorted lexicographically, ascending, short-to-long; e.g. zero-length < <code>0x00</code> < <code>0x01</code> < <code>0x0100</code>)</li> 340</ol> 341</li> 342<li>category â sorted lexicographically, ascending, where bytes are in little-endian order (matching the order used in encoded transactions)</li> 343</ol> 344</li> 345</ol> 346<p><strong>Notes</strong></p> 347<ol> 348<li>For clarity, lexicographically-sorted fields must be compared byte-by-byte from start to end. Where one item is a prefix of another item, the shorter item is considered the "lower" value. E.g. the following values are sorted lexicographically in ascending order: <code>0x00</code>, <code>0x0011</code>, <code>0x11</code>, <code>0x1100</code>.</li> 349</ol> 350<h3 class="anchor anchorWithStickyNavbar_LWe7" id="fungible-token-supply-definitions">Fungible Token Supply Definitions<a href="#fungible-token-supply-definitions" class="hash-link" aria-label="Direct link to Fungible Token Supply Definitions" title="Direct link to Fungible Token Supply Definitions" translate="no">â</a></h3> 351<p>Several measurements of fungible token supply are standardized for wider ecosystem compatibility. (See <a href="/docs/spec/rationale#specification-of-token-supply-definitions">Specification of Token Supply Definitions</a>.)</p> 352<p>By design, <a href="#genesis-supply">Genesis Supply</a>, <a href="#reserved-supply">Reserved Supply</a>, <a href="#circulating-supply">Circulating Supply</a>, and <a href="#total-supply">Total Supply</a> of any fungible token category will not exceed <code>9223372036854775807</code> (the maximum VM number).</p> 353<h4 class="anchor anchorWithStickyNavbar_LWe7" id="genesis-supply">Genesis Supply<a href="#genesis-supply" class="hash-link" aria-label="Direct link to Genesis Supply" title="Direct link to Genesis Supply" translate="no">â</a></h4> 354<p>A token category's <strong>genesis supply</strong> is an <strong>immutable, easily-computed, maximum possible supply</strong>, known since the token category's genesis transaction. It overestimates total supply if any amount of tokens have been destroyed since the genesis transaction.</p> 355<p>The genesis supply of a fungible token category can be computed by parsing the outputs of the category's genesis transaction and summing the <code>amount</code> of fungible tokens matching the category's ID.</p> 356<h4 class="anchor anchorWithStickyNavbar_LWe7" id="total-supply">Total Supply<a href="#total-supply" class="hash-link" aria-label="Direct link to Total Supply" title="Direct link to Total Supply" translate="no">â</a></h4> 357<p>A token category's <strong>total supply</strong> is the sum â at a particular moment in time â of <strong>tokens which are either in circulation or may enter circulation in the future</strong>. A token category's total supply is always less than or equal to its genesis supply.</p> 358<p>The total supply of a fungible token category can be computed by retrieving all UTXOs which contain token prefixes matching the category ID, removing provably-destroyed outputs (spent to <code>OP_RETURN</code> outputs), and summing the remaining <code>amount</code>s.</p> 359<p>Software implementations should emphasize total supply in user interfaces for token categories which do not meet the requirements for emphasizing <a href="#circulating-supply">circulating supply</a>.</p> 360<h4 class="anchor anchorWithStickyNavbar_LWe7" id="reserved-supply">
360Reserved Supply<a href="#reserved-supply" class="hash-link" aria-label="Direct link to Reserved Supply" title="Direct link to Reserved Supply" translate="no">â</a></h4> 361<p>A token category's <strong>reserved supply</strong> or <strong>unissued supply</strong> is the sum â at a particular moment in time â of tokens held in reserve by the issuing entity. <strong>This is the portion of the supply which the issuer represents as "not in circulation".</strong></p> 362<p>The reserved supply of a fungible token category can be computed by retrieving all UTXOs which contain token prefixes matching the category ID, removing provably-destroyed outputs (spent to <code>OP_RETURN</code> outputs), and summing the <code>amount</code>s held in prefixes which have either the <code>minting</code> or <code>mutable</code> capability.</p> 363<h4 class="anchor anchorWithStickyNavbar_LWe7" id="circulating-supply">Circulating Supply<a href="#circulating-supply" class="hash-link" aria-label="Direct link to Circulating Supply" title="Direct link to Circulating Supply" translate="no">â</a></h4> 364<p>A token category's <strong>circulating supply</strong> is the sum â at a particular moment in time â of tokens not held in reserve by the issuing entity. <strong>This is the portion of the supply which the issuer represents as "in circulation".</strong></p> 365<p>The <strong>circulating supply</strong> of a fungible token category can be computed by subtracting the <a href="#reserved-supply">reserved supply</a> from the <a href="#total-supply">total supply</a>.</p> 366<p>Software implementations might choose to emphasize circulating supply (rather than total supply) in user interfaces for token categories which:</p> 367<ul> 368<li>are issued by an entity trusted by the user, or</li> 369<li>are issued by a covenant (of a construction known to the verifier) for which token issuance is limited (via a strategy trusted by the user).</li> 370</ul> 371<h2 class="anchor anchorWithStickyNavbar_LWe7" id="usage-examples">Usage Examples<a href="#usage-examples" class="hash-link" aria-label="Direct link to Usage Examples" title="Direct link to Usage Examples" translate="no">â</a></h2> 372<ul> 373<li><a href="/docs/spec/examples#usage-examples">Appendix: Usage Examples â</a> 374<ul> 375<li><a href="/docs/spec/examples#identity-tokens">Identity Tokens</a></li> 376<li><a href="/docs/spec/examples#covenant-tracking-identity-tokens">Covenant-Tracking Identity Tokens</a></li> 377<li><a href="/docs/spec/examples#depository-child-covenants">Depository Child Covenants</a></li> 378<li><a href="/docs/spec/examples#voting-with-fungible-tokens">Voting with Fungible Tokens</a> 379<ul> 380<li><a href="/docs/spec/examples#sealed-voting">Sealed Voting</a></li> 381</ul> 382</li> 383<li><a href="/docs/spec/examples#multithreaded-covenants">Multithreaded Covenants</a></li> 384<li><a href="/docs/spec/examples#multi-covenant-decentralized-applications">Multi-Covenant, Decentralized Applications</a></li> 385</ul> 386</li> 387</ul> 388<h2 class="anchor anchorWithStickyNavbar_LWe7" id="rationale">Rationale<a href="#rationale" class="hash-link" aria-label="Direct link to Rationale" title="Direct link to Rationale" translate="no">â</a></h2> 389<ul> 390<li><a href="/docs/spec/rationale#rationale">Appendix: Rationale â</a> 391<ul> 392<li><a href="/docs/spec/rationale#incompatibility-of-token-fungibility-and-token-commitments">Incompatibility of Token Fungibility and Token Commitments</a></li> 393<li><a href="/docs/spec/rationale#selection-of-commitment-types">Selection of Commitment Types</a> 394<ul> 395<li><a href="/docs/spec/rationale#boolean-commitment-type">Boolean Commitment Type</a></li> 396<li><a href="/docs/spec/rationale#bitfield-commitment-type">Bitfield Commitment Type</a></li> 397<li><a href="/docs/spec/rationale#hash-commitment-types">Hash Commitment Types</a> 398<ul> 399<li><a href="/docs/spec/rationale#secret-hash-commitment-type">Secret Hash Commitment Type</a></li> 400<li><a href="/docs/spec/rationale#nonsecret-hash-commitment-type">Nonsecret Hash Commitment Type</a></li> 401</ul> 402</li> 403<li><a href="/docs/spec/rationale#public-key-commitment-type">Public Key Commitment Type</a></li> 404<li><a href="/docs/spec/rationale#signature-commitment-type">Signature Commitment Type</a></li> 405</ul> 406</li> 407<li><a href="/docs/spec/rationale#shared-codepoint-for-all-tokens">Shared Codepoint for All Tokens</a></li> 408<li><a href="/docs/spec/rationale#behavior-of-minting-and-mutable-tokens">Behavior of Minting and Mutable Tokens</a></li> 409<li><a href="/docs/spec/rationale#exclusion-of-cloneable-capability">Exclusion of Cloneable Capability</a></li> 410<li><a href="/docs/spec/rationale#avoiding-proof-of-work-for-token-data-compression">Avoiding Proof-of-Work for Token Data Compression</a></li> 411<li><a href="/docs/spec/rationale#use-of-transaction-ids-as-token-category-ids">Use of Transaction IDs as Token Category IDs</a></li> 412<li><a href="/docs/spec/rationale#one-token-prefix-per-output">One Token Prefix Per Output</a></li> 413<li><a href="/docs/spec/rationale#including-capabilities-in-token-category-inspection-operations">Including Capabilities in Token Category Inspection Operations</a></li> 414<li><a href="/docs/spec/rationale#support-for-zero-length-commitments">Support for Zero-Length Commitments</a></li> 415<li><a href="/docs/spec/rationale#limitation-of-non-fungible-token-commitment-length">Limitation of Non-Fungible Token Commitment Length</a></li> 416<li><a href="/docs/spec/rationale#inclusion-of-token-aware-cashaddresses">Inclusion of Token-Aware CashAddresses</a></li> 417<li><a href="/docs/spec/rationale#recommendation-of-sighash_utxos-for-multi-entity-transactions">Recommendation of <code>SIGHASH_UTXOS</code> for Multi-Entity Transactions</a></li> 418<li><a href="/docs/spec/rationale#limitation-of-fungible-token-supply">Limitation of Fungible Token Supply</a></li> 419<li><a href="/docs/spec/rationale#specification-of-token-supply-definitions">Specification of Token Supply Definitions</a></li> 420</ul> 421</li> 422</ul> 423<h2 class="anchor anchorWithStickyNavbar_LWe7" id="prior-art--alternatives">Prior Art &
423 Alternatives<a href="#prior-art--alternatives" class="hash-link" aria-label="Direct link to Prior Art & Alternatives" title="Direct link to Prior Art & Alternatives" translate="no">â</a></h2> 424<ul> 425<li><a href="/docs/spec/alternatives#prior-art--alternatives">Appendix: Prior Art & Alternatives â</a> 426<ul> 427<li><a href="/docs/spec/alternatives#pmv3">PMv3</a></li> 428<li><a href="/docs/spec/alternatives#bitauth">Bitauth</a></li> 429<li><a href="/docs/spec/alternatives#colored-coins">Colored Coins</a> 430<ul> 431<li><a href="/docs/spec/alternatives#op_checkcolorverify">OP_CHECKCOLORVERIFY</a></li> 432<li><a href="/docs/spec/alternatives#freimarkets">Freimarkets</a></li> 433<li><a href="/docs/spec/alternatives#confidential-assets">Confidential Assets</a></li> 434<li><a href="/docs/spec/alternatives#op_group">OP_GROUP</a></li> 435<li><a href="/docs/spec/alternatives#group-tokenization">Group Tokenization</a></li> 436<li><a href="/docs/spec/alternatives#simple-ledger-protocol-v1">Simple Ledger Protocol (v1)</a></li> 437<li><a href="/docs/spec/alternatives#unforgeable-groups">Unforgeable Groups</a></li> 438</ul> 439</li> 440</ul> 441</li> 442</ul> 443<h2 class="anchor anchorWithStickyNavbar_LWe7" id="test-vectors">Test Vectors<a href="#test-vectors" class="hash-link" aria-label="Direct link to Test Vectors" title="Direct link to Test Vectors" translate="no">â</a></h2> 444<p>Sets of cross-implementation test vectors are provided in the <a href="https://github.com/bitjson/cashtokens/tree/master/test-vectors" target="_blank" rel="noopener noreferrer"><code>test-vectors</code></a> directory. Each set is described below.</p> 445<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-aware-cashaddress-test-vectors">Token-Aware CashAddress Test Vectors<a href="#token-aware-cashaddress-test-vectors" class="hash-link" aria-label="Direct link to Token-Aware CashAddress Test Vectors" title="Direct link to Token-Aware CashAddress Test Vectors" translate="no">â</a></h3> 446<p><a href="/assets/files/cashaddr-d8176be1cb96aeb1b7734d18b362df44.json" target="_blank"><code>cashaddr.json</code></a> includes an updated set of test vectors including tests for <a href="#cashaddress-token-support">token-aware CashAddresses</a>.</p> 447<p>Test vectors for the CashAddress format have been <a href="https://github.com/bitcoincashorg/bitcoincash.org/blob/3e2e6da8c38dab7ba12149d327bc4b259aaad684/spec/cashaddr.md" target="_blank" rel="noopener noreferrer">standardized and widely used since 2017</a>, including test vectors for not-yet-defined <code>type</code> values.</p> 448<p>While this specification simply uses the available <code>type</code> values, to assist implementers, several additional test vectors have been added to the existing CashAddress test vectors in <a href="/assets/files/cashaddr-d8176be1cb96aeb1b7734d18b362df44.json" target="_blank"><code>test-vectors/cashaddr.json</code></a>.</p> 449<h3 class="anchor anchorWithStickyNavbar_LWe7" id="token-encoding-test-vectors">Token Encoding Test Vectors<a href="#token-encoding-test-vectors" class="hash-link" aria-label="Direct link to Token Encoding Test Vectors" title="Direct link to Token Encoding Test Vectors" translate="no">â</a></h3> 450<p>A complete set of test vectors that validate token encoding can be found in <a href="/assets/files/token-prefix-valid-0455bb83322bf6335b6c9d821aaca8f4.json" target="_blank"><code>test-vectors/token-prefix-valid.json</code></a> and <a href="/assets/files/token-prefix-invalid-7b86758f56a4a1c4fb0fb2296a6bd2f1.json" target="_blank"><code>test-vectors/token-prefix-invalid.json</code></a>, respectively.</p> 451<h3 class="anchor anchorWithStickyNavbar_LWe7" id="transaction-validation-test-vectors">Transaction Validation Test Vectors<a href="#transaction-validation-test-vectors" class="hash-link" aria-label="Direct link to Transaction Validation Test Vectors" title="Direct link to Transaction Validation Test Vectors" translate="no">â</a></h3> 452<p>The <a href="https://github.com/bitjson/cashtokens/tree/master/test-vectors/vmb_tests/" target="_blank" rel="noopener noreferrer"><code>test-vectors/vmb_tests</code></a> directory contains sets of transaction test vectors that validate all technical elements of this proposal.</p> 453<p>To maximize portability between implementations, these test vectors use Libauth'
453s <a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/vmb-tests/readme.md" target="_blank" rel="noopener noreferrer">full-transaction testing strategy</a>. Test vectors are sorted into files based on their expected behavior:</p> 454<ul> 455<li><strong>Pre-activation test vectors</strong> â these vectors test transaction validation prior to the activation of this proposal.<!-- --> 456<ul> 457<li><a href="/assets/files/bch_vmb_tests_before_chip_cashtokens_invalid-4f75acb0cf9e5829284c49b3936c9ec4.json" target="_blank"><code>bch_vmb_tests_before_chip_cashtokens_invalid.json</code></a> - test vectors that must fail validation in both nonstandard and standard mode (see <a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/vmb-tests/readme.md#standard-vs-non-standard-vms" target="_blank" rel="noopener noreferrer">Standard Vs. Non-Standard VMs</a>). To assist implementers, a companion <a href="/assets/files/bch_vmb_tests_before_chip_cashtokens_invali
457d_reasons-0d18f6d9ba3845477b6676c98e980804.json" target="_blank"><code>reasons</code> file</a> describes the reason each test vector is expected to fail.</li> 458<li><a href="/assets/files/bch_vmb_tests_before_chip_cashtokens_nonstandard-bc2aa227f6cb85094cd4378609d3e650.json" target="_blank"><code>bch_vmb_tests_before_chip_cashtokens_nonstandard.json</code></a> - test vectors that must fail validation in standard mode but pass validation in nonstandard mode. A companion <a href="/assets/files/bch_vmb_tests_before_chip_cashtokens_nonstandard_reasons-db6b02513d991573c4009ca62fc3e361.json" target="_blank"><code>reasons</code> file</a> describes the reason each test vector is expected to fail in standard mode.</li> 459<li><a href="/assets/files/bch_vmb_tests_before_chip_cashtokens_standard-18b5d69dbc2c69a2753807a2fe6bdf56.json" target="_blank"><code>bch_vmb_tests_before_chip_cashtokens_standard.json</code></a> - test vectors that must pass validation in both standard and nonstandard mode.</li> 460</ul> 461</li> 462<li><strong>Post-activation test vectors</strong> â these vectors test transaction validation as it must behave after activation of this proposal.<!-- --> 463<ul> 464<li><a href="/assets/files/bch_vmb_tests_chip_cashtokens_invalid-6dca3c2761a1618660daf9dc94f7e7e0.json" target="_blank"><code>bch_vmb_tests_chip_cashtokens_invalid.json</code></a> - test vectors that must fail validation in both nonstandard and standard mode. To assist implementers, a companion <a href="/assets/files/bch_vmb_tests_chip_cashtokens_invalid_reasons-202173bc07b4ae4530790e42f3b90db6.json" target="_blank"><code>reasons</code> file</a> describes the reason each test vector is expected to fail.</li> 465<li><a href="/assets/files/bch_vmb_tests_chip_cashtokens_nonstandard-ed657f324b420a9ee88b7de78e8df8c2.json" target="_blank"><code>bch_vmb_tests_chip_cashtokens_nonstandard.json</code></a> - test vectors that must fail validation in standard mode but pass validation in nonstandard mode. A companion <a href="/assets/files/bch_vmb_tests_chip_cashtokens_nonstandard_reasons-9e8132e288fb8eb05eea2faa20dd4d41.json" target="_blank"><code>reasons</code> file</a> describes the reason each test vector is expected to fail in standard mode.</li> 466<li><a href="/assets/files/bch_vmb_tests_chip_cashtokens_standard-0568bbfa2c48319df68ea21
466a45963df9.json" target="_blank"><code>bch_vmb_tests_chip_cashtokens_standard.json</code></a> - test vectors that must pass validation in both standard and nonstandard mode.</li> 467</ul> 468</li> 469</ul> 470<p>Each test vector is an array including:</p> 471<ol> 472<li>A short, unique identifier for the test (based on the hash of the test contents)</li> 473<li>A string describing the purpose/behavior of the test</li> 474<li>The unlocking script under test (disassembled, i.e. human-readable)</li> 475<li>The locking script under test (disassembled)</li> 476<li>The full, encoded test transaction</li> 477<li>An encoded list of unspent transaction outputs (UTXOs) with which to verify the test transaction (ordered to match the input order of the test transaction)</li> 478</ol> 479<p><strong>Only array items 5 and 6 are strictly necessary</strong>; items 1 through 4 are purely informational, and may be useful in debugging and cross-implementation communication.</p> 480<p>To use these test vectors, implementations should decode the transaction under test (5) and its UTXOs (6), then validate the transaction using all of the implementation's transaction validation infrastructure initialized in the expected standard/nonstandard mode(s). See <a href="#implementations">Implementations</a> for examples.</p> 481<h2 class="anchor anchorWithStickyNavbar_LWe7" id="implementations">Implementations<a href="#implementations" class="hash-link" aria-label="Direct link to Implementations" title="Direct link to Implementations" translate="no">â</a></h2> 482<p>Please see the following implementations for additional examples and test vectors:</p> 483<ul> 484<li>C++<!-- --> 485<ul> 486<li><a href="https://bitcoincashnode.org/" target="_blank" rel="noopener noreferrer">Bitcoin Cash Node (BCHN)</a> â A professional, miner-friendly node that solves practical problems for Bitcoin Cash.<!-- --> 487<ul> 488<li>CashTokens support: <a href="https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1580" target="_blank" rel="noopener noreferrer">Merge Request !1580</a></li> 489<li>Token-aware CashAddresses: <a href="https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1596" target="_blank" rel="noopener noreferrer">Merge Request !1596</a></li> 490<li>This CHIP also includes CashToken integration test vectors for other proposals:<!-- --> 491<ul> 492<li>P2SH32: <a href="https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1556" target="_blank" rel="noopener noreferrer">Merge Request !1556</a></li> 493<li>65-byte TXs: <a href="https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1598" target="_blank" rel="noopener noreferrer">Merge Request !1598</a></li> 494</ul> 495</li> 496</ul> 497</li> 498</ul> 499</li> 500<li>JavaScript/TypeScript<!-- --> 501<ul> 502<li><a href="https://github.com/bitauth/libauth" target="_blank" rel="noopener noreferrer">Libauth</a> â An ultra-lightweight, zero-dependency JavaScript library for Bitcoin Cash.<!-- --> 503<ul> 504<li><a href="https://github.com/bitauth/libauth/pull/98" target="_blank" rel="noopener noreferrer">Pull Request #98</a> 505<ul> 506<li><a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/message/transaction-encoding.ts#L395-L435" target="_blank" rel="noopener noreferrer">Token encoding</a></li> 507<li><a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/message/transaction-encoding.ts#L209-L324" target="_blank" rel="noopener noreferrer">Token decoding</a></li> 508<li><a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/vm/instruction-sets/bch/2023/bch-2023-tokens.ts#L163-L297" target="_blank" rel="noopener noreferrer">Token-aware validation</a></li> 509<li><a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/vm/instruction-sets/bch/2023/bch-2023-tokens.ts#L355-L389" target="_blank" rel="noopener noreferrer">Token inspection operations</a></li> 510<li><a href="https://github.com/bitauth/libauth/blob/9dfa6cc0b8710dedfe007b47bd018f5a47079df5/src/lib/vm/instruction-sets/common/signing-serialization.ts#L456-L474" target="_blank" rel="noopener noreferrer">Token-aware signing serialization</a></li> 511<li><a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/address/cash-address.ts#L61-L82" target="_blank" rel="noopener noreferrer">Token-aware CashAddresses</a></li> 512<li><a href="https://github.com/bitauth/libauth/blob/43914ca973e90dfc84b6173dcace7233f8c2e05c/src/lib/vmb-tests/bch-vmb-tests.spec.ts#L122-L152" target="_blank" rel="noopener noreferrer">Verifying vmb_tests</a></li> 513</ul> 514</li> 515</ul> 516</li> 517</ul> 518</li> 519</ul> 520<h2 class="anchor anchorWithStickyNavbar_LWe7" id="stakeholder-responses--statements">Stakeholder Responses & Statements<a href="#stakeholder-responses--statements" class="hash-l
520ink" aria-label="Direct link to Stakeholder Responses & Statements" title="Direct link to Stakeholder Responses & Statements" translate="no">â</a></h2> 521<p><a href="/docs/spec/stakeholders">Stakeholder Responses & Statements â</a></p> 522<h2 class="anchor anchorWithStickyNavbar_LWe7" id="feedback--reviews">Feedback & Reviews<a href="#feedback--reviews" class="hash-link" aria-label="Direct link to Feedback & Reviews" title="Direct link to Feedback & Reviews" translate="no">â</a></h2> 523<ul> 524<li><a href="https://github.com/bitjson/cashtokens/issues" target="_blank" rel="noopener noreferrer">CashTokens CHIP Issues</a></li> 525<li><a href="https://bitcoincashresearch.org/t/chip-2022-02-cashtokens-token-primitives-for-bitcoin-cash/725" target="_blank" rel="noopener noreferrer"><code>CHIP 2022-02 CashTokens</code> - Bitcoin Cash Research</a></li> 526</ul> 527<h2 class="anchor anchorWithStickyNavbar_LWe7" id="acknowledgements">Acknowledgements<a href="#acknowledgements" class="hash-link" aria-label="Direct link to Acknowledgements" title="Direct link to Acknowledgements" translate="no">â</a></h2> 528<p>Thank you to the following contributors for reviewing and contributing improvements to this proposal, providing feedback, and promoting consensus among stakeholders: 529<a href="https://github.com/cculianu" target="_blank" rel="noopener noreferrer">Calin Culianu</a>, <a href="https://github.com/A60AB5450353F40E" target="_blank" rel="noopener noreferrer">bitcoincashautist</a>, <a href="https://gitlab.com/im_uname" target="_blank" rel="noopener noreferrer">imaginary_username</a>, <a href="https://github.com/joshmg" target="_blank" rel="noopener noreferrer">Joshua Green</a>, <a href="https://github.com/thesquaregroot" target="_blank" rel="noopener noreferrer">Andrew Groot</a>, <a href="https://github.com/zander" target="_blank" rel="noopener noreferrer">Tom Zander</a>, <a href="https://gitlab.com/andrew-128" target="_blank" rel="noopener noreferrer">Andrew #128</a>, <a href="https://github.com/mr-zwets" target="_blank" rel="noopener noreferrer">Mathieu Geukens</a>, <a href="https://github.com/rnbrady" target="_blank" rel="noopener noreferrer">Richard Brady</a>, <a href="https://github.com/msalcala11" target="_blank" rel="noopener noreferrer">Marty Alcala</a>, <a href="https://gitlab.com/emergent-reasons" target="_blank" rel="noopener noreferrer">John Nieri</a>, <a href="https://gitlab.com/monsterbitar" target="_blank" rel="noopener noreferrer">Jonathan Silverblood</a>, <a href="https://github.com/scherrey" target="_blank" rel="noopener noreferrer">Benjamin Scherrey</a>, <a href="https://github.com/rkalis" target="_blank" rel="noopener noreferrer">Rosco Kalis</a>, <a href="https://github.com/dikel" target="_blank" rel="noopener noreferrer">Deyan Dimitrov</a>, <a href="https://github.com/jonas-lundqvist" target="_blank" rel="noopener noreferrer">Jonas Lundqvist</a>, <a href="https://github.com/joemarct" target="_blank" rel="noopener noreferrer">Joemar Taganna</a>, <a href="https://github.com/Rucknium" target="_blank" rel="noopener noreferrer">Rucknium</a>.</p> 530<h2 class="anchor anchorWithStickyNavbar_LWe7" id="changelog">Changelog<a href="#changelog" class="hash-link" aria-label="Direct link to Changelog" title="Direct link to Changelog" translate="no">â</a></h2> 531<p>This section summarizes the evolution of this document.</p> 532<ul> 533<li><strong>v2.2.2 â 2022-5-20</strong> 534<ul> 535<li>Mention unissued supply as an alternative term for reserved supply</li> 536<li>Mark CHIP as final</li> 537</ul> 538</li> 539<li><strong>v2.2.1 â 2022-11-15</strong> (<a href="https://github.com/bitjson/cashtokens/blob/7552da2dfad217aa5f4130f52d7d6cbbfeef7a23/readme.md" target="_blank" rel="noopener noreferrer"><code>7552da2d</code></a>)<!-- --> 540<ul> 541<li>Remove confusing recommendation about token-aware CashAddress usage (<a href="https://github.com/bitjson/cashtokens/issues/82" target="_blank" rel="noopener noreferrer">#82</a>)</li> 542<li>Extract <a href="/docs/spec/examples"><code>examples.md</code></a>, <a href="/docs/spec/rationale"><code>rationale.md</code></a>, and <a href="/docs/spec/alternatives"><code>alternatives.md</code></a> for approachability</li> 543<li>Add <a href="/docs/spec/stakeholders"><code>stakeholders.md</code></a> to collect final approvals</li> 544<li>Expand test vectors (<a href="https://github.com/bitjson/cashtokens/pull/90" target="_blank" rel="noopener noreferrer">#90</a>)</li> 545</ul> 546</li> 547<li><strong>v2.2.0 â 2022-9-30</strong> (<a href="https://github.com/bitjson/cashtokens/blob/e02012a219a0fb2abef02aa3e08ad326774bd3f3/readme.md" target="_blank" rel="noopener noreferrer"><code>e02012a2</code></a>)<!-- --> 548<ul> 549<li>Compress token encoding using bitfield (<a href="https://github.com/bitjson/cashtokens/pull/33" target="_blank" rel="noopener noreferrer">#33</a>)</li> 550<li>Encode mutable capability as <code>0x01</code> and minting capability as <code>0x02</code></li> 551<li>Revert to limiting <code>commitment_length</code> to <code>40</code> bytes by consensus (<a href="https://github.com/bitjson/cashtokens/issues/23" target="_blank" rel="noopener noreferrer">#23</a>)</li> 552<li>Revert <code>PREFIX_TOKEN</code> to a unique codepoint (<code>0xef</code>) (<a href="https://github.com/bitjson/cashtokens/issues/41" target="_blank" rel="noopener noreferrer">#41</a>)</li> 553<li>Modify <code>OP_*TOKENCOMMITMENT</code> to push <code>0</code> for zero-length commitments (<a href="https://github.com/bitjson/cashtokens/issues/25" target="_blank" rel="noopener noreferrer">#25</a>)</li> 554<li>
554Extend BIP69 sorting algorithm to support tokens (<a href="https://github.com/bitjson/cashtokens/pull/60" target="_blank" rel="noopener noreferrer">#60</a>)</li> 555<li>Specify activation times</li> 556<li>Expand test vectors</li> 557<li>Note non-support of beta specs for double spend proofs</li> 558<li>Improve rationale</li> 559</ul> 560</li> 561<li><strong>v2.1.0 â 2022-6-30</strong> (<a href="https://github.com/bitjson/cashtokens/blob/f8b500a051f82d42dbf9e9e890bc6cdc14592307/readme.md" target="_blank" rel="noopener noreferrer"><code>f8b500a0</code></a>)<!-- --> 562<ul> 563<li>Expand motivation, benefits, rationale, prior art & alternatives</li> 564<li>Simplify token encoding, update test vectors</li> 565<li>Set <code>PREFIX_TOKEN</code> to <code>0xd0</code> and limit <code>commitment_length</code> using standardness</li> 566<li>Specify handling of pre-activation token-forgery outputs</li> 567<li>Specify token-aware signing serialization algorithm and <code>SIGHASH_UTXOS</code> (<a href="https://github.com/bitjson/cashtokens/issues/22" target="_blank" rel="noopener noreferrer">#22</a>)</li> 568</ul> 569</li> 570<li><strong>v2.0.1 â 2022-2-25</strong> (<a href="https://github.com/bitjson/cashtokens/blob/fcb110c3309901886b2c7d3417568d8b13fb01b5/readme.md" target="_blank" rel="noopener noreferrer"><code>fcb110c3</code></a>)<!-- --> 571<ul> 572<li>Expand rationale</li> 573<li>Note impossibility of valid token outputs in coinbase transactions</li> 574</ul> 575</li> 576<li><strong>v2.0.0 â 2022-2-22</strong> (<a href="https://github.com/bitjson/cashtokens/blob/879c55edd7e9cd6a2c2d50990d89e5cc7cb07394/readme.md" target="_blank" rel="noopener noreferrer"><code>879c55ed</code></a>)<!-- --> 577<ul> 578<li>Initial publication (versioning begins at v2 to differentiate from <a href="https://blog.bitjson.com/cashtokens-contract-validated-tokens-for-bitcoin-cash/" target="_blank" rel="noopener noreferrer">CashTokens v1</a>)</li> 579</ul> 580</li> 581</ul> 582<h2 class="anchor anchorWithStickyNavbar_LWe7" id="copyright">Copyright<a href="#copyright" class="hash-link" aria-label="Direct link to Copyright" title="Direct link to Copyright" translate="no">â</a></h2> 583<p>This document is placed in the public domain.</p></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col"><a href="https://github.com/cashtokens/cashtokens.org/tree/master/docs/spec/chip.md" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_Z9Sw" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_JAkA"></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/category/cashtokens-chip"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">CashTokens CHIP</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/spec/examples"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Usage Examples</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#summary" class="table-of-contents__link toc-highlight">Summary</a><ul><li><a href="#terms" class="table-of-contents__link toc-highlight">Terms</a></li></ul></li><li><a href="#deployment" class="table-of-contents__link toc-highlight">Deployment</a></li><li><a href="#motivation" class="table-of-contents__link toc-highlight">Motivation</a><ul><li><a href="#contract-issued-commitments" class="table-of-contents__link toc-highlight">Contract-Issued Commitments</a></li></ul></li><li><a href="#benefits" class="table-of-contents__link toc-highlight">Benefits</a><ul><li><a href="#cross-contract-interfaces" class="table-of-contents__link toc-highlight">Cross-Contract Interfaces</a></li><li><a href="#decentralized-applications" class="table-of-contents__link toc-highlight">Decentralized Applications</a></li><li><a href="#universal-token-primitives" class="table-of-contents__link toc-highlight">Universal Token Primitives</a></li></ul></li><li><a href="#technical-summary" class="table-of-contents__link toc-highlight">Technical Summary</a><ul><li><a href="#transaction-output-data-model" class="table-of-contents__link toc-highlight">Transaction Output Data Model</a></li></ul></li><li><a href="#technical-specification" class="table-of-contents__link toc-highlight">Technical Specification</a><ul><li><a href="#token-categories" class="table-of-contents__link toc-highlight">Token Categories</a></li><li><a href="#token-types" class="table-of-contents__link toc-highlight">Token Types</a></li><li><a href="#token-behavior" class="table-of-contents__link toc-highlight">Token Behavior</a></li><li><a href="#token-encoding" class="table-of-contents__link toc-highlight">Token Encoding</a></li><li><a href="#token-encoding-activation" class="table-of-contents__link toc-highlight">Token Encoding Activation</a></li><li><a href="#token-aware-transaction-validation" class="table-of-contents__link toc-highlight">Token-Aware Transaction Validation</a></li><li><a href="#token-inspection-operations" class="table-of-contents__link toc-highlight">Token Inspection Operations</a></li><li><a href="#signing-serialization-of-tokens" class="table-of-contents__link toc-highlight">
583Signing Serialization of Tokens</a></li><li><a href="#sighash_utxos" class="table-of-contents__link toc-highlight"><code>SIGHASH_UTXOS</code></a></li><li><a href="#double-spend-proof-support" class="table-of-contents__link toc-highlight">Double Spend Proof Support</a></li><li><a href="#cashaddress-token-support" class="table-of-contents__link toc-highlight">CashAddress Token Support</a></li><li><a href="#token-aware-bip69-sorting-algorithm" class="table-of-contents__link toc-highlight">Token-Aware BIP69 Sorting Algorithm</a></li><li><a href="#fungible-token-supply-definitions" class="table-of-contents__link toc-highlight">Fungible Token Supply Definitions</a></li></ul></li><li><a href="#usage-examples" class="table-of-contents__link toc-highlight">Usage Examples</a></li><li><a href="#rationale" class="table-of-contents__link toc-highlight">Rationale</a></li><li><a href="#prior-art--alternatives" class="table-of-contents__link toc-highlight">Prior Art & Alternatives</a></li><li><a href="#test-vectors" class="table-of-contents__link toc-highlight">Test Vectors</a><ul><li><a href="#token-aware-cashaddress-test-vectors" class="table-of-contents__link toc-highlight">Token-Aware CashAddress Test Vectors</a></li><li><a href="#token-encoding-test-vectors" class="table-of-contents__link toc-highlight">Token Encoding Test Vectors</a></li><li><a href="#transaction-validation-test-vectors" class="table-of-contents__link toc-highlight">Transaction Validation Test Vectors</a></li></ul></li><li><a href="#implementations" class="table-of-contents__link toc-highlight">Implementations</a></li><li><a href="#stakeholder-responses--statements" class="table-of-contents__link toc-highlight">Stakeholder Responses & Statements</a></li><li><a href="#feedback--reviews" class="table-of-contents__link toc-highlight">Feedback & Reviews</a></li><li><a href="#acknowledgements" class="table-of-contents__link toc-highlight">Acknowledgements</a></li><li><a href="#changelog" class="table-of-contents__link toc-highlight">Changelog</a></li><li><a href="#copyright" class="table-of-contents__link toc-highlight">Copyright</a></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/docs/intro">Introduction</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/spec/chip">CashTokens CHIP</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/bcmr/chip">Metadata Registries CHIP</a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://x.com/CashTokens" target="_blank" rel="noopener noreferrer" class="footer__link-item">@CashTokens on X.com<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://bitcoincashresearch.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Bitcoin Cash Research<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://old.reddit.com/r/cashtokens" target="_blank" rel="noopener noreferrer" class="footer__link-item">CashTokens Reddit<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://old.reddit.com/r/Bitcoincash/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Bitcoin Cash Reddit<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div>
583<div class="theme-layout-footer-column col footer__col"><div class="footer__title">Development</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://otr.cash/" target="_blank" rel="noopener noreferrer" class="footer__link-item">OpenTokenRegistry<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://chipnet.chaingraph.cash/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Chipnet Explorer<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://3xpl.com/bitcoin-cash" target="_blank" rel="noopener noreferrer" class="footer__link-item">3xpl BCH Explorer<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://explorer.salemkode.com/" target="_blank" rel="noopener noreferrer" class="footer__link-item">SalemKode BCH Explorer<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Other Resources</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://whybitcoincash.com/" target="_blank" rel="noopener noreferrer" class="footer__link-item">WhyBitcoinCash.com<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://bch.info/" target="_blank" rel="noopener noreferrer" class="footer__link-item">BCH.info<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://bitcoincash.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">bitcoincash.org<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://bitcoincashpodcast.com/faqs/Tech/what-is-cashtokens" target="_blank" rel="noopener noreferrer" class="footer__link-item">BCH Podcast FAQ<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">ð¯ 2025 CashTokens.org contributors, released in the public domain. <br><a rel="license" href="https://creativecommons.org/publicdomain/zero/1.0/"> 584 <img src="https://licensebuttons.net/p/zero/1.0/80x15.png" style="border-style: none;" alt="CC0"> 585 </a></div></div></div></footer></div>
586<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"8ecf43c54a82440987e1bad2c4d5d42a","r":1,"spa":2}' crossorigin="anonymous"></script>
586 587</body> 588</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.