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 addressd: 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:
- See a commit transaction in the mempool
- Construct their own reveal before the original creator
- Get their reveal mined first, hijacking the inscription
The Solution: Presign + Atomic Broadcast
BRC2.0 implements a hybrid defense:
- Pre-build all transactions before any are broadcast
- Pre-sign all transactions with RBF-enabled sequences
- Broadcast atomically in a single RPC batch call
- 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:
- Build a complete reveal transaction with real script and control block
- Calculate exact virtual size (vsize) from the dummy
- 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
- BRC2.0 Integration — How to deploy and call contracts
- Alkanes Protocol — Token-focused operations