Reference implementation for ergoplatform/sigmastate-interpreter#1114.
This repository shows how an Ergo contract can verify a bounded fact about Bitcoin transaction bytes:
These non-witness Bitcoin transaction bytes hash to the expected txid, and at least one parsed output has the expected scriptPubKey hash.
The current canonical contract is btc_verify_parser.ergo. It proves output
membership by structurally walking the authenticated transaction bytes. Earlier
R6 outputs-section helper contracts remain in the repository as history, not as
the recommended pattern.
| File | Status | Purpose |
|---|---|---|
btc_verify_parser.ergo |
Canonical, mainnet spend-tested | R4 txid + R5 parsed output script hash |
btc_ergo_proof.py |
Tested helper | Build and locally verify proof JSON |
btc_tx_parser.py |
Tested helper | Parse Bitcoin transactions and strip SegWit witness data |
btc_verify_outputs.ergo |
Historical | R4 + R5 + R6 outputs-section helper hash |
btc_verify_full.ergo |
Historical unsafe baseline | R4 + R5 arbitrary slice |
btc_txid_verify.ergo |
Building block | Txid-only verification |
btc_verify_executeFromVar.ergo |
Supplementary historical variant | executeFromVar exploration |
Run the parser examples:
python btc_tx_parser.py
python test_rosen_bridge.pyRun the test suite:
python scripts/check.pyBuild a proof JSON object:
python btc_ergo_proof.py build --raw-tx <raw_tx_hex> --output-index 1Verify a proof JSON object locally:
python btc_ergo_proof.py verify-local test-vectors/valid/rosen-bridge-output1.proof.jsonFor btc_verify_parser.ergo, the box and context ABI is:
| Location | Type | Meaning |
|---|---|---|
SELF.R4 |
Coll[Byte] |
Bitcoin txid in natural double-SHA256 byte order |
SELF.R5 |
Coll[Byte] |
SHA256(scriptPubKey) for the target output script |
getVar(1) |
Coll[Byte] |
Non-witness Bitcoin transaction bytes |
The contract checks:
sha256(sha256(txBytes)) == R4- transaction structure fits the bounded subset;
- one parsed output has
sha256(scriptPubKey) == R5; - locktime lands exactly at the end of the parsed outputs.
The bounded parser accepts only:
- non-witness serialization only;
- single-byte CompactSize counts and script lengths (
< 0xfd); - 1 or 2 inputs;
- 1 to 4 outputs;
- non-empty output scripts;
- no trailing bytes before or after locktime.
Transactions outside this subset are rejected. This is intentional. ErgoScript has no unbounded loops over runtime-variable Bitcoin transaction structure, so a small explicit parser is safer than implying full Bitcoin parser support.
This repository does not prove:
- Bitcoin block inclusion;
- Bitcoin finality or confirmations;
- best-chain selection;
- current UTXO spendability;
- full Bitcoin script execution;
- support for every valid Bitcoin transaction shape;
- authorization to spend a production Ergo box.
The parser is a verifier, not an authorizer. Production designs must compose it with signatures, state-machine checks, token rules, height/finality policy, and a separate Bitcoin inclusion/finality layer when trust minimization requires it.
See:
Bitcoin explorers and most libraries display txids reversed from their natural
double-SHA256 byte order. Register R4 stores the natural order, the raw
SHA256(SHA256(tx_bytes)) output.
Use:
from btc_tx_parser import display_to_natural, natural_to_displayCopying a displayed explorer txid directly into R4 will fail.
The Python tests cover:
- valid Rosen Bridge SegWit fixture after witness stripping;
- proof JSON generation and local verification;
- wrong txid byte order;
- full SegWit bytes passed instead of stripped bytes;
- target script hash appearing only in
scriptSig; - truncated bytes;
- trailing bytes;
- more than four outputs;
- empty output script;
- unsupported CompactSize marker;
- public valid and invalid JSON vectors;
- AppKit compilation of the canonical contracts;
The canonical parser was reported as mainnet spend-tested at block 1,776,872,
spend transaction:
4298f96593ec179e8aa364efdede4ff5ad7f08d0d9bdc9562f78ee288cdb9129
Earlier historical contracts were also spend-tested and remain documented in
AUDIT.md.
Built by odiseusme for Ergo issue #1114. This repository is a reference artifact, not a consensus-standard Bitcoin parser and not a complete Bitcoin-to-Ergo bridge.