Practical implementation of the BitVM2 protocol by Distributed Lab. You can check the original BitVM2 paper and our implementation paper for more details).
Important
This project is under heavy development and API can drastically vary due to its early development stage. We do not guarantee any backward compatibility until the first release and recommend using it with great caution.
The project contains multiple crates:
Crate | Description |
---|---|
bitcoin-splitter |
A crate for splitting the Bitcoin script into multiple parts as suggested by the recent 1). |
bitcoin-winternitz |
Winternitz Signature and recovery implementation based on BitVM's [signatures] package. |
bitcoin-utils |
Helper package containing the implementation of certain fundamental operations and debugging functions. |
bitcoin-testscripts |
A collection of test scripts for testing BitVM2 concept. |
bitcoin-scriptexec |
A helper crate for executing Bitcoin scripts. Fork of BitVM package. |
docker compose up -d
Warning
Sometimes Docker Compose may fail at step of creating the volumes, the most simple solution is, in regards of failure, just trying starting it again several times until it works.
Let us create a temporary alias for bitcoin-cli
from the container like this:
alias bitcoin-cli="docker compose exec bitcoind bitcoin-cli"
Create a fresh wallet for your user:
bitcoin-cli createwallet "my"
Warning
Do not create more than one wallet, otherwise further steps would require a bit of modification.
Generate fresh address and store it to environmental variable:
export ADDRESS=$(bitcoin-cli -rpcwallet="my" getnewaddress "main" "bech32")
Then mine 101 blocks to your address:
bitcoin-cli generatetoaddress 101 $ADDRESS
Note
Rewards for mined locally blocks will go to this address, but, by
protocol rules, BTCs are mature only after 100 confirmations, so
that's why 101 blocks are mined. You can see other in immature
balances fields, after executing next command.
For more info about Bitcoin RPC API see 2.
bitcoin-cli -rpcwallet="my" getbalances
Compile nero-cli
:
cargo install --path ./nero-cli
Generate random pair of keys for payout path spending:
nero-cli --config ./nero.toml generate-keys
Possible output:
abffe139daab7e63742643886728755f08288f5d05fb6a0aebc3f3ff41d1d83c
02dedae18ba57d264289ae13f9009ba4ff62d006d8a64078724a5f153c8f7cca71
Generate some random input for script:
nero-cli --config ./nero.toml generate-input
Now you got a generated script input in input.txt
file in hex format
and in Bitcoin script in stdout, for example output could be:
OP_PUSHBYTES_3 f4531f OP_PUSHBYTES_4 5bca4206 OP_PUSHBYTES_4 d3d2de1f OP_PUSHBYTES_4 831e530e OP_PUSHBYTES_4 35364014 OP_PUSHBYTES_4 c54c6802 OP_PUSHBYTES_4 be8eaa14 OP_PUSHBYTES_4 1907b201 OP_PUSHBYTES_4 9eb1a719 OP_PUSHBYTES_3 f4531f OP_PUSHBYTES_4 5bca4206 OP_PUSHBYTES_4 d3d2de1f OP_PUSHBYTES_4 831e530e OP_PUSHBYTES_4 35364014 OP_PUSHBYTES_4 c54c6802 OP_PUSHBYTES_4 be8eaa14 OP_PUSHBYTES_4 1907b201 OP_PUSHBYTES_4 9eb1a719
Now, let's generate and send assert transaction:
nero-cli --config ./nero.toml assert-tx --input ./input.txt --amount 0.007BTC --pubkey dedae18ba57d264289ae13f9009ba4ff62d006d8a64078724a5f153c8f7cca71
This could take a while for fibonachi sequence. You'll then get a transaction id:
a35153ff68d3fce1fd1f270c4a3a3ef1f1fb1703055c03f6b5b1fef9d08f50ee:0
And all disprove scripts in
disproves
directories with payout script inpayout.txt
.
Which you could fetch and check:
bitcoin-cli getrawtransaction A35153ff68d3fce1fd1f270c4a3a3ef1f1fb1703055c03f6b5b1fef9d08f50ee
Then convert it from hex to JSON:
bitcoin-cli decoderawtransaction 020000000001014754bb8d55fb1a9dcf2380c7011eed1601e3c070aeb9f2481f0c28e322199ac90100000000fdffffff0260ae0a0000000000225120d75e8e13e5467b03ea564f8f60c9acdc0859a320bf5359c2accd20e34cbb73ec67c94704000000002251203d8f7c4be893b12bd0a81aa99dd313f01f6cde1eca6ce67d2b029c940b5c804c0140b045b92d05c9b78ca58bc7402650bf8bac49a06b8d85991ca841fff95e1f21ed3f40c5ec84a966dc824b0a706ec8de8e2f5fa0f754ded8c27e1162aaa86d861700000000
Let's spend it by payout transaction. To pass the default locktime of two weeks, we need to mine 2017 blocks:
bitcoin-cli generatetoaddress 2017 $ADDRESS &> /dev/null
And then spend it:
nero-cli --config ./nero.toml spend-payout --assert a35153ff68d3fce1fd1f270c4a3a3ef1f1fb1703055c03f6b5b1fef9d08f50ee:0 --seckey Abffe139daab7e63742643886728755f08288f5d05fb6a0aebc3f3ff41d1d83c --address $ADDRESS
Output:
7bb040e609cc1acababfb17a50b6c48646c28d5afdcbb45cf33dca1e69542d2a
nero-cli --config ./nero.toml assert-tx --input ./input.txt --amount 0.007BTC --pubkey dedae18ba57d264289ae13f9009ba4ff62d006d8a64078724a5f153c8f7cca71 --address $ADDRESS --distort
Output:
11283f38271775b6250ce97d9f633a6977f4318625ab7ea4d36b8535e7c2c692:0 # <-- assert tx out
445 # <-- spendable disprove script (because of invalid states)
And let's spend it using disprove script from local directory
disproves
by number:
nero-cli --config ./nero.toml spend-disprove --assert 11283f38271775b6250ce97d9f633a6977f4318625ab7ea4d36b8535e7c2c692:0 --address $ADDRESS --disprove 445