This is an early preview of CashTokens, a new type of on-chain contract for Bitcoin Cash. Feedback and security reviews are especially appreciated.
This post is primarily intended for developers familiar with the Bitcoin Cash VM language. For a higher-level summary, see: PMv3 & CashTokens: Build Decentralized Applications on Bitcoin Cash.
CashTokens are a Bitcoin Cash virtual machine-enforced scheme for issuing, validating, and redeeming tokens. Tokens can be issued either by a trusted entity or by a Bitcoin Cash covenant configured to behave as a corporation and issuing its own tokens.
Decentralized applications can use CashTokens in external networks, relying on an on-chain covenant to adjudicate disputes. This can allow users to deposit and withdraw Bitcoin Cash from these decentralized applications without requiring them to be developed exclusively in Bitcoin Cash virtual machine (VM) bytecode or operate entirely on the Bitcoin Cash blockchain.
Interactions with both CashToken corporation and token covenants can be fully supported by SPV wallets.
CashToken schemes can be practically implemented with only one change to Bitcoin Cash: a scalable inductive proof primitive. However, many production use cases will also require either a small increase in the 520-byte VM stack item size limit or a set of new transaction introspection opcodes.
Transaction Introspection (TxInt) Opcodes
Transaction introspection (TxInt) — the examination of transaction elements beyond the standard unlocking bytecode during validation — can already be performed by any bitcoin VM capable of validating arbitrary signatures (
OP_CHECKDATASIG). However, TxInt opcodes would dramatically improve the efficiency of these contracts in terms of transaction size and VM processing requirements. For example, TxInt opcodes could reduce CashChannels from
~900 bytes, ~90 operations to
~400 bytes, ~40 operations.
TxInt opcodes rely on data which is already used by the Bitcoin Cash VM during signature validation (
OP_CHECKMULTISIG), so activation should not require VM architectural changes or increased node processing requirements.
CashToken Inductive Proofs
CashToken inductive proofs allow CashTokens to prove their lineage in the Bitcoin Cash VM context.
Without induction, contracts would require validating the token’s full transfer history at each spend, requiring proofs for each transfer: transaction 1 must include transaction 0 for validation, transaction 2 must include transaction 1 (which also includes transaction 0), etc. Even with clever de-duplication schemes, this strategy still experiences linear growth of transaction size and validation costs. One possible solution to this infinite transaction growth is a modification to the transaction format like PMv3.
With induction, contracts must validate only 1) the CashToken covenant is of the expected format, and 2) the parent transaction’s CashToken covenant was of the expected format.
If both are true, the lineage of the token is verified, since the parent transaction’s token UTXO could not have been spent without itself proving its lineage or proving its own parent CashToken covenant was spent successfully. After an initial “notarization” step, where the CashToken covenant proves that it’s parent transaction was the hash encoded in the token, all future covenant transactions can be proven to descend from the notarized transaction by performing the inductive proof step.
Finally, other covenants can validate the structure of a CashToken when it is moved in a transaction with the covenant, allowing CashToken covenants to work as tokens for decentralized applications.
A commented-example of token issuance, token notarization, token transfer, and token redemption with a corporation covenant is available as a GitHub gist.
This template provides scripts for each stage of a simplified "depository" CashToken Corporation, where users may deposit 10,000 satoshis in exchange for a CashToken. This implementation supports exactly 4 homogeneous tokens. Tokens are tracked in a 2 level Merkle tree: rt / \ b0 b1 / \ / \ a0 a1 a2 a3 The covenant begins with no depositors (all leaves start as the hash of 0) and a dust balance. A user deposits 10,000 satoshis, receiving a CashToken (recorded at a0) secured by a single key. Then the CashToken is "notarized" to prove it is a descendant of the mint transaction. Once notarized, the owner transfers the CashToken to a 2-of-3 multisig for stronger security. From there, the owner transfers the token to a different owner (now single sig). Finally, the new owner redeems the CashToken with the corporation, withdrawing their 10,000 satoshi deposit, and replacing a0 in the tree with the hash of 0 (making the leaf available to other depositors). There are 5 transaction types demonstrated: [...]
The inductive proof token covenant in this demo requires around ~330 bytes and ~150 operations, well within the 520-byte stack item size limit (which also limits P2SH script sizes) and the 201 operation limit. The example corporation covenant is a contrived “depository” contract, but a similar scheme can be used to create a variety of decentralized applications with various deposit, withdrawal, and consensus strategies (see Drivechains, Hivemind).
The goal of this initial demo is to gauge interest and recruit reviewers for more definitive specifications. The target upgrade date for a TxInt opcode proposal is May 2022. Some TxInt opcodes could be enabled earlier, but many should only be enabled with expanded integer support. Additional notes are available in the gist.
Feedback & Discussion Groups
If you have questions, feedback, or you’re interested in contributing to future CashTokens or TxInt Opcodes specifications, please join us on Telegram:
- Subscribe to CashTokens on Telegram ➔
- CashToken Dev Chat on Telegram ➔
- CashToken Discussion on Bitcoin Cash Research ➔
This post is part of a series on developing decentralized prediction markets on Bitcoin Cash.