Skip to main content

BRC2.0 Protocol (brc20-prog)

BRC2.0 (also known as brc20-prog) is a protocol for deploying and executing EVM-compatible smart contracts directly on Bitcoin via inscriptions. It enables Solidity developers to bring their skills to Bitcoin without learning a new language.

How BRC2.0 Works

BRC2.0 inscribes contract deployments and function calls as JSON data within Bitcoin transactions. An indexer reads these inscriptions and executes the embedded EVM bytecode, maintaining state across transactions.

The Inscription Format

BRC2.0 uses the standard ord inscription envelope:

<pubkey> CHECKSIG
OP_FALSE OP_IF
"ord"
<content-type-tag>
"text/plain;charset=utf-8"
<body-tag>
<json-payload>
OP_ENDIF

The critical security feature is the <pubkey> CHECKSIG at the start—this ensures only the holder of the ephemeral private key can create a valid reveal transaction, preventing frontrunning attacks.

Payload Types

Deploy Operation:

{
"p": "brc20-prog",
"op": "deploy",
"d": "0x608060405234801561001057600080fd5b50..."
}

The d field contains the full EVM deployment bytecode (compiled Solidity).

Call Operation:

{
"p": "brc20-prog",
"op": "call",
"c": "0x1234567890abcdef1234567890abcdef12345678",
"d": "0xa9059cbb000000000000000000000000..."
}
  • c: The target contract address
  • d: ABI-encoded function call data

The Commit-Reveal-Activation Pattern

BRC2.0 uses a multi-transaction pattern to prevent frontrunning and ensure atomic execution:

Two-Transaction Pattern (for calls)

Transaction 1: COMMIT
├─ Input: User's UTXO
└─ Output: Exact sats to taproot address

Transaction 2: REVEAL
├─ Input: Commit output (requires valid signature)
├─ Script: Pubkey+CHECKSIG + inscription envelope
└─ Output: OP_RETURN (completes the call)

Three-Transaction Pattern (for deployments)

Transaction 1: COMMIT
├─ Input: User's UTXO
└─ Output: Exact sats to taproot address

Transaction 2: REVEAL
├─ Input: Commit output
├─ Script: Inscription envelope with bytecode
└─ Output: 546-sat inscription UTXO

Transaction 3: ACTIVATION
├─ Input: 546-sat inscription UTXO
└─ Output: OP_RETURN (activates the contract)

The three-transaction pattern creates a persistent inscription UTXO that can be tracked, then "activates" it to deploy the contract.

Anti-Frontrunning Mechanisms

The Frontrunning Problem

Without protection, an attacker could:

  1. See a commit transaction in the mempool
  2. Construct their own reveal before the original creator
  3. Get their reveal mined first, hijacking the inscription

The Solution: Presign + Atomic Broadcast

BRC2.0 implements a hybrid defense:

  1. Pre-build all transactions before any are broadcast
  2. Pre-sign all transactions with RBF-enabled sequences
  3. Broadcast atomically in a single RPC batch call
  4. The reveal is already signed when commit hits mempool—attackers have no window

The Pubkey+CHECKSIG in the reveal script means only the commit creator's signature is valid, making competing reveals impossible.

Contract Address Derivation

BRC2.0 uses Ethereum's contract address formula:

address = keccak256(rlp([sender, nonce]))[12:]

Where:

  • sender: The deployer's Ethereum-style address (derived from Bitcoin pubkey)
  • nonce: The deployer's transaction count (0 for first deployment)

This allows predicting contract addresses before deployment—useful for setting up cross-contract references.

ABI Encoding

Function calls use standard Ethereum ABI encoding:

┌─────────────────────────────────────────────────────────┐
│ Function Selector (4 bytes) │
│ keccak256("functionName(type1,type2)")[:4] │
├─────────────────────────────────────────────────────────┤
│ Argument 1 (32 bytes, left-padded) │
├─────────────────────────────────────────────────────────┤
│ Argument 2 (32 bytes, left-padded) │
├─────────────────────────────────────────────────────────┤
│ ... │
└─────────────────────────────────────────────────────────┘

Example: transfer(address,uint256) with args (0x1234..., 1000)

Selector:  0xa9059cbb (keccak256("transfer(address,uint256)")[:4])
Arg 1: 0x0000000000000000000000001234567890abcdef...
Arg 2: 0x00000000000000000000000000000000000000000000000000000000000003e8

Precise Fee Calculation

BRC2.0 uses the "dummy transaction technique" for exact fee calculation:

  1. Build a complete reveal transaction with real script and control block
  2. Calculate exact virtual size (vsize) from the dummy
  3. Commit output = inscription_output (546 sats) + (reveal_vsize × fee_rate)

This precision is critical—too little causes reveal failure, too much wastes sats.

Inscription Protection

When funding a BRC2.0 operation, existing inscriptions on UTXOs must be protected. The protocol automatically inserts a split transaction:

UTXO containing inscription


┌─────────────────────┐
│ SPLIT TX │
├─────────────────────┤
│ Output 1: Clean │ ──→ Used for commit funding
│ Output 2: Protected │ ──→ Keeps inscription safe
└─────────────────────┘

The mempool indexer traces inscription state through unconfirmed transactions, allowing safe splitting.

See Also