This project provides a simplified Rust simulation of the concepts presented in the ColliderVM: Stateful Computation on Bitcoin paper. It demonstrates the core mechanisms of ColliderVM, particularly the use of presigned transaction flows and hash collision challenges for enabling stateful computation on Bitcoin without relying on fraud proofs.
Disclaimer: This is a toy simulation and does not implement a production-ready ColliderVM protocol. It simplifies some aspects for clarity and focuses on the protocol's structural flow and the hash collision mechanism.
The ColliderVM paper proposes a method to achieve stateful computation on Bitcoin, addressing limitations of the Bitcoin script language. Key concepts include:
- Stateful Computation: Enabling computations (data & logic) to persist across multiple Bitcoin transactions.
- Actors:
- Signers (n): Offline setup participants who create and sign transaction templates (flows). Assume 1-of-n are honest for safety (preventing invalid state transitions).
- Operators (m): Online execution participants who provide inputs, find nonces via hashing, and broadcast transactions. Assume 1-of-m are honest for liveness (ensuring the process can proceed).
- Presigned Flows (
D): A set of2^Lpre-agreed, parallel transaction sequences. Each flow corresponds to a unique identifierdfrom the setD. - Hash Collision Challenge: To ensure the same input
xis used across steps in a chosen flowd, the Operator must find a noncersuch that the firstBbits of a hashH(x, r)match that specific flow identifierd(i.e.,H(x, r)|_B = d ∈ D). - Computational Gap:
- Honest Work: Finding any valid pair
(x, r)such thatH(x, r)|_B ∈ Dtakes~2^(B-L)hash computations. - Malicious Work (Double Collision): Finding two different pairs
(x, r) ≠ (x', r')that map to the same flowd(i.e.,H(x, r)|_B = H(x', r')|_B = d) takes significantly more work (~2^(B-L/2)), making it computationally expensive to cheat by using different inputs within the same flow.
- Honest Work: Finding any valid pair
- Capital Efficiency: A key goal is to avoid the capital lock-up periods associated with fraud-proof-based systems like BitVM2.
This simulation implements a minimal proof-of-concept:
- Simple Function (
F): Instead of complex logic (like STARK verification), the computationF(x)is split into two subfunctions:F1(x): Checks ifinput_value > 100.F2(x): Checks ifinput_value < 200.- The overall computation succeeds only if
F1(x) AND F2(x)is true for the same inputxwithin the chosen flow.
- Simulated Actors: Generates
nSigners andmOperators withsecp256k1key pairs (SignerInfo,OperatorInfo), but their roles in complex multi-party signing or liveness are simplified. - Simulated Presigning: Creates placeholder Bitcoin
Transactionstructures (create_placeholder_tx) and calculates simplified sighash messages (create_toy_sighash_message). It collects real Schnorr signatures but doesn't handle actual UTXO management or realistic fee calculation. - Simplified Bitcoin Script:
- Hash Check: The script check
H(x, r)|_B = dis executed according to the rules of the paper for the prefix check. However, for now, the concatenation ofxandrfor the input of theBlake3hash is passed separately from the inputxused for the logic of the functionsF1andF2, which would allow the operator to cheat. We need to improve this part to have the same inputxused for both the hash and the logic of the functions. - Signature Check: Scripts include
OP_CHECKSIGVERIFYand the Signer's public key. However, thebitvm::execute_script_buffunction used for simulation does not perform cryptographic signature verification. It checks script logic but assumes signatures are valid if provided.
- Hash Check: The script check
- Limited Flows: Generates
min(2^L, 16)flows instead of the full2^Lfor performance reasons in this demo. - Off-Chain Hashing: The Operator's nonce search (
find_valid_nonce) uses Rust'sblake3library to simulate the~2^(B-L)off-chain work.
The codebase is organized into three main Rust modules:
src/main.rs:- The executable entry point.
- Parses command-line arguments (for the input value
x). - Sets up the
ColliderVmConfig(n, m, L, B, k). - Calls
simulation::run_simulationto orchestrate the entire process. - Prints the final simulation results.
src/collidervm_toy.rs:- Defines the core data structures (
ColliderVmConfig,SignerInfo,OperatorInfo,PresignedStep,PresignedFlow). - Contains constants (e.g.,
F1_THRESHOLD). - Implements helper functions primarily used off-chain or for setup:
create_toy_sighash_message: Simulates sighash generation.calculate_flow_id: ComputesH(x, r)|_Busing Blake3.find_valid_nonce: Simulates the Operator's hash search.
- Implements functions to build the Bitcoin locking scripts (
build_script_f1_locked,build_script_f2_locked) incorporating the simplified logic, hash, and signature checks.
- Defines the core data structures (
src/simulation.rs:- Implements the two main phases of the ColliderVM simulation protocol:
offline_setup: Simulates the Signers generating keys and creating/signing all thePresignedFlows for all potential flow IDsd.online_execution: Simulates the Operator finding a nonce for a given inputx, selecting the corresponding flowd, constructing the full witness and script, and executing the F1 and F2 scripts.
- Uses helper functions and data structures from
collidervm_toy.rs. - Uses
bitvm::execute_script_bufto simulate the execution of the constructed Bitcoin scripts.
- Implements the two main phases of the ColliderVM simulation protocol:
The cargo run [input_value] command triggers the following sequence:
-
Initialization (
main.rs): Parses the optionalinput_value(or defaults to 114) and sets up theColliderVmConfig(n=3, m=2, L=4, B=8, k=2). -
Offline Setup Phase (
simulation::offline_setup): Simulates actions performed by Signers before the inputxis known.- Generates keypairs for 3 Signers and 2 Operators.
- Loops
2^L = 16times (forflow_id0 to 15). - Inside the loop (for each
flow_idd):- F1 Setup:
- Builds the F1 locking script (
build_script_f1_locked) containing checks forx > 100,flow_id == d, and a Signer signature. - Creates a placeholder F1 transaction (
create_placeholder_tx) spending a dummy input. - Calculates a toy sighash for F1 (
create_toy_sighash_message). - All 3 Signers sign this sighash, producing signatures.
- Stores the F1 template, sighash, signatures, and script in a
PresignedStep.
- Builds the F1 locking script (
- F2 Setup:
- Builds the F2 locking script (
build_script_f2_locked) containing checks forx < 200,flow_id == d, and a Signer signature. - Creates a placeholder F2 transaction spending the output of the F1 placeholder transaction.
- Calculates a toy sighash for F2.
- All 3 Signers sign this sighash.
- Stores the F2 template, sighash, signatures, and script in a second
PresignedStep.
- Builds the F2 locking script (
- Adds the
PresignedFlow(containing the F1 and F2 steps) to aHashMapkeyed by theflow_id(d).
- F1 Setup:
- Returns the generated Signer/Operator info and the
presigned_flows_map.
-
Online Execution Phase (
simulation::online_execution): Simulates actions performed by an Operator after the inputx(input_value) is known.- Nonce Search: Calls
find_valid_nonce(input_value, B, L).- This function starts with
nonce = 0. - It repeatedly calculates
d = calculate_flow_id(input_value, nonce, B, L)(which computesBlake3(input_value || nonce)|_B). - If
d < 2^L(i.e.,dis in the setD= {0..15}), it returns the successful(nonce, d). This simulates the~2^(B-L)=~2^(8-4)=~16expected hashes. - If not, it increments the nonce and tries again.
- This function starts with
- Flow Selection: Retrieves the
PresignedFlowfor theflow_id(d) returned byfind_valid_noncefrom thepresigned_flows_map. - (Optional) Off-Chain Checks: Verifies the Signer 0 signature for F1/F2 and the hash calculation
H(x,r)|_B = dusing Rust crypto functions (for logging/debugging). - F1 Script Execution:
- Constructs the witness script:
script_builder.push(sig_f1).push(flow_id).push(input_value). - Concatenates the witness script bytes with the F1 locking script bytes (
step_f1.locking_script). - Calls
bitvm::execute_script_bufon the combined script. - Stores the success/failure result (
script_f1_success).
- Constructs the witness script:
- F2 Script Execution:
- Constructs the witness script:
script_builder.push(sig_f2).push(flow_id).push(input_value). - Concatenates the witness script bytes with the F2 locking script bytes (
step_f2.locking_script). - Calls
bitvm::execute_script_bufon the combined script. - Stores the success/failure result (
script_f2_success).
- Constructs the witness script:
- Result Calculation: Determines overall
successasscript_f1_success && script_f2_success. - Returns a
SimulationResultcontaining the success status and results of individual script executions.
- Nonce Search: Calls
-
Output (
main.rs): Prints a summary message indicating whether the simulation succeeded or failed, based on the returnedSimulationResult.
- Prerequisites: Ensure you have Rust and Cargo installed (https://www.rust-lang.org/tools/install).
- Build: Navigate to the project directory and build the project:
Usage: collidervm_toy [OPTIONS]
Options:
-i, --input <INPUT>
Input value to test (default: 114)
[default: 114]
-p, --preset <PRESET>
Preset configuration to use
[default: default]
Possible values:
- default: Default configuration (quick to run for demos)
- medium: Medium difficulty (10-15 seconds)
- hard: Higher difficulty (~1 minute)
- custom: Custom configuration (use with -n, -m, -l, -b, -k options)
-s, --signers <SIGNERS>
Number of signers (1-of-n honest for safety)
-o, --operators <OPERATORS>
Number of operators (1-of-m honest for liveness)
-l, --l-param <L_PARAM>
Flow set size parameter L (set D size = 2^L)
-b, --b-param <B_PARAM>
Hash prefix bits parameter B
-k, --k-param <K_PARAM>
Number of subfunctions (fixed at 2 for the toy model)
--hash-rate <HASH_RATE>
Skip hash rate calibration and use the provided value
--no-calibration
Disable hash rate calibration
-h, --help
Print help (see a summary with '-h')
-V, --version
Print versionStarted with love by AbdelStark 🧡
Feel free to follow me on Nostr if you’d like, using my public key:
npub1hr6v96g0phtxwys4x0tm3khawuuykz6s28uzwtj5j0zc7lunu99snw2e29
Or just scan this QR code to find me:
Thanks goes to these wonderful people (emoji key):
A₿del ∞/21M 💻 📖 🤔 |
Stephen 💻 |
Phạm Xuân Trung 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!