Skip to content

Instantly share code, notes, and snippets.

@A60AB5450353F40E
Created June 6, 2025 05:26
Show Gist options
  • Save A60AB5450353F40E/d64fdc6dd57c49fc83e6ef132fd87ae5 to your computer and use it in GitHub Desktop.
Save A60AB5450353F40E/d64fdc6dd57c49fc83e6ef132fd87ae5 to your computer and use it in GitHub Desktop.

Understanding the UTXO Model: A Guide for Bitcoin Cash Developers

Introduction

Welcome to Bitcoin Cash development! If you're coming from other blockchain platforms or traditional web development, the UTXO (Unspent Transaction Output) model might be a new concept to grasp. This guide will break down how UTXOs work in Bitcoin Cash and provide insights on how to design effective smart contracts using this model.

What is a UTXO?

In Bitcoin Cash, think of UTXOs as individual digital bills in your wallet. Unlike account-based blockchains (like Ethereum) that track a single balance for each address, Bitcoin Cash tracks specific "bills" of cryptocurrency.

When you create a transaction in Bitcoin Cash:

  • You're consuming existing UTXOs as inputs
  • Creating new UTXOs as outputs
  • The sum of outputs cannot exceed the sum of inputs
  • Any difference between input and output amounts becomes the miner fee

This model might seem less intuitive at first, but it offers excellent parallelization capabilities and privacy benefits.

Understanding Locking Scripts

Each UTXO in Bitcoin Cash has a "locking script" (also called a scriptPubKey) attached to it. As a developer, you'll be designing these scripts to define the conditions under which a UTXO can be spent.

Think of a locking script as a list of requirements that must be met. When someone wants to spend a UTXO, they must provide an "unlocking script" (scriptSig) that satisfies all conditions in the locking script.

This differs fundamentally from Solidity smart contracts on EVM chains. In Bitcoin Cash:

  • Code doesn't define actions to be executed
  • Code defines constraints that must be satisfied
  • Anything not explicitly constrained is permitted

This last point is crucial to internalize as you design contracts.

Basic Contract Types

The most common contract in Bitcoin Cash is P2PKH (Pay-to-Public-Key-Hash). It requires:

  • A valid signature matching a specified public key hash
  • The signature must cover the transaction data

As you build your first contracts, you'll likely use this pattern often. It ensures only the holder of a specific private key can spend the funds.

Advanced Contract Development with CashScript

With Bitcoin Cash's enhanced script capabilities, you can develop more complex contracts. For example, using CashScript (a high-level language for Bitcoin Cash contracts), you could write:

contract SplitPayment {
    function spend(pubkey pk, sig s) {
        // Verify signature
        require(checkSig(s, pk));
        
        // Ensure 50% goes to each recipient
        int amount = tx.inputs[this.activeInputIndex].value;
        require(tx.outputs[0].value == amount / 2);
        require(tx.outputs[0].address == 0x123...);
        require(tx.outputs[1].value == amount / 2);
        require(tx.outputs[1].address == 0x456...);
    }
}

Important Developer Note: When your locking script doesn't require a signature verification (like checkSig), any third party on the network can create a transaction spending that UTXO. This can be intentional—allowing for trustless, automatic execution—but make sure you understand the implications. Without signature requirements, you're creating a contract that anyone can trigger, not just specific users or yourself.

Common Development Pitfalls

Many developers new to Bitcoin Cash make the mistake of under-constraining their contracts. For example:

// Problematic contract
contract IncompleteDistribution {
    function spend() {
        // Only constrain one output
        require(tx.outputs[0].value == tx.inputs[this.activeInputIndex].value / 2);
        require(tx.outputs[0].address == 0x123...);
        // Remaining 50% not constrained!
    }
}

In this example, the second 50% is unconstrained. The person creating the transaction can send it anywhere—likely to themselves! Don't assume that funds automatically return to you or your contract; explicitly constrain every output you care about.

Debugging Tips

When testing your Bitcoin Cash contracts:

  • Use testnet or local regtest environments first
  • Consider all possible transaction structures that could satisfy your constraints
  • Remember that miners will include any valid transaction regardless of your intentions
  • Test edge cases like zero amounts or maximum integer values

Conclusion

The UTXO model in Bitcoin Cash offers powerful capabilities for creating trustless, secure, and efficient smart contracts. As you develop, always remember the fundamental principle: explicitly constrain everything you care about, because anything not constrained is permitted.

By thinking in terms of constraints rather than procedures, you'll be able to create robust contracts that behave exactly as intended. Welcome to Bitcoin Cash development—we're excited to see what you'll build!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment