CashScript lets developers write the rules for spending Bitcoin Cash in a readable programming language. Its compiler turns those rules into BCH bytecode, and its TypeScript SDK helps an application build the transactions that use them.
For example, an escrow contract might let two parties release a payment together, with a separate refund path after a deadline. CashScript expresses those conditions. The application still has to collect the signatures, construct the transaction, and explain the result to the people signing it.
This guide covers stable version 0.13.2, checked on September 8, 2026. The 0.14 releases are marked as prereleases at that date.
Start with the output being spent
BCH tracks funds as unspent transaction outputs, or UTXOs. A contract sets the conditions for spending an output. Each spending transaction must satisfy those conditions, and the output can be spent only once.
An application that continues across transactions commonly creates a replacement output carrying its next state. A staged-payment contract, for example, could require each withdrawal to pay a fixed amount and return the remaining balance to a contract output. The state may be represented in the amount, locking bytecode, or an NFT commitment. CashScript's covenant guide explains how contracts inspect and constrain these outputs.
That makes transaction design central to the application. Which inputs are consumed? Which outputs must be recreated? Who pays the fee? What happens to BCH and token change? Two transactions trying to spend the same state output also compete with each other, so the application needs a way to handle that conflict.
From source code to a contract
A source file defines constructor parameters, such as a public key or deadline, and public functions that describe its spending paths. The CashScript compiler produces an artifact containing bytecode, interface information, and compiler metadata. Applications can use JSON artifacts or TypeScript artifacts with generated argument types.
The SDK combines that artifact with the constructor arguments to instantiate a particular contract. Changing a constructor value can change the resulting bytecode and the destination being funded.
Keep the source, compiler version, artifact, constructor values, and contract type together. They are what you need to reproduce a deployment and check that an application is funding the intended contract.
Building the spending transaction
The TypeScript transaction builder assembles inputs and outputs, uses unlockers to satisfy spending conditions, calculates transaction size and fees, and submits through a network provider. Helpers can gather UTXOs and add BCH or fungible-token change.
Those helpers save work, but the application chooses how to use them. It still needs to select the right token category, preserve any NFTs it should retain, and create the correct next state. The SDK guards against some construction mistakes; it cannot know whether the resulting payment matches the user's intent.
Before requesting a signature, show what leaves the wallet, what returns as change, and what remains locked. That review matters even when the contract itself is correct.
What stable CashScript supports after Layla
The 0.13 release notes document the main additions:
for,while, anddo-whileloops, with debugging support.- Bit inversion and shift operators.
- P2S contract support in the SDK.
- Default runtime checks for boolean and fixed-length byte function arguments.
- Transaction-size, fee, UTXO-selection, and change helpers.
The SDK's default local VM target is BCH_2026_05. Because 0.13 includes breaking compiler and SDK changes, existing projects should follow the migration notes and compare newly compiled artifacts before updating a deployment.
Loops are especially useful when the same check applies to several inputs or outputs. A developer can write the check once and repeat it. The loop still has to finish within the VM's resource budget: a transaction that runs out of that budget fails validation.
Two meanings of function
A CashScript public function is an entry point for spending from a contract. Layla's OP_DEFINE and OP_INVOKE provide reusable routines inside the VM. CashScript 0.13.2 supports the former; user-defined reusable functions arrive in the 0.14 prereleases. Check the version you are using before following an example that calls one function from another.
P2S is another choice to make explicitly. It puts a script directly in an output, while P2SH places a hash of the script there. Wallet support and the size of the resulting transactions help determine which fits a deployment. The P2S specification describes the relevant limits and relay rules.
Test the ways a transaction can go wrong
CashScript's debugging tools evaluate transactions locally through Libauth and connect failures to source locations. Mock network providers let you test without broadcasting, and Bitauth IDE offers a closer view of script execution.
A useful test suite starts with a valid spend, then changes one condition at a time. For the escrow example, try the wrong signer, a missing signature, and a refund just before and at the allowed deadline. For a stateful contract, try changing the replacement output or omitting it entirely.
Also test minimum and maximum amounts, malformed token commitments, reordered inputs and outputs, fees, change, and loops near their resource limits. If the contract depends on an oracle or an admin key, include stale messages, unauthorized actions, and recovery paths.
Run these tests against the compiled artifact and the VM rules your deployment uses. Independent review is most useful when it covers that same artifact, its transaction-building code, and its assumptions about outside services.
Where the model fits
CashScript can express escrow, timelocked refunds, vault policies, oracle-conditioned payouts, staged payments, and markets built from contract outputs. Covenants can also constrain token issuance or transfers while the relevant outputs remain under their rules. A token sent to an unrestricted output does not automatically retain the contract's restrictions.
Independently spendable positions fit the UTXO model naturally. A market in which every action updates one shared output needs more coordination, because only one competing spend can succeed. The UTXO contract guide explores that tradeoff in more detail.
Recurring payments need an additional distinction: a contract can enforce when a payment is allowed, but someone still has to construct and submit the transaction. A timelock does not schedule a payment by itself.
The application around the contract
A contract can verify a signed price message without knowing whether the quoted price is truthful. It can enforce an authorized withdrawal while the website presents that withdrawal misleadingly. Those are application and trust questions that the bytecode alone cannot settle.
Document who controls oracles, administration, minting, and recovery; which network providers the application needs; and how users can proceed if a provider fails. Publish enough information to verify the source against the funded contract, and make the important transaction details visible before signing.
CashScript removes much of the repetitive work involved in writing BCH contracts. Its practical value is that developers can spend more time making the spending rules understandable, testing the transitions between states, and building a wallet flow people can use with confidence.