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​