Skip to content

Instantly share code, notes, and snippets.

Forked from System-Glitch/
Created May 10, 2021 20:02
Show Gist options
  • Save Jolly-Pirate/1e8ca6c46351b773e9de482fcf016b7f to your computer and use it in GitHub Desktop.
Save Jolly-Pirate/1e8ca6c46351b773e9de482fcf016b7f to your computer and use it in GitHub Desktop.
Tutorial for bitcoin regtest
# Script to generate a new block every minute
# Put this script at the root of your unpacked folder
echo "Generating a block every minute. Press [CTRL+C] to stop.."
address=`./bin/bitcoin-cli getnewaddress`
while :
echo "Generate a new block `date '+%d/%m/%Y %H:%M:%S'`"
./bin/bitcoin-cli generatetoaddress 1 $address
sleep 60

How to Bitcoin regtest


  1. Download bitcoin core
  2. Unpack it wherever you want.
  3. Create a directory named data inside the unpacked folder.
  4. Create a directory named .bitcoin inside your home folder: mkdir ~/.bitcoin
  5. Copy bitcoin.conf into ~/.bitcoin
  6. Copy rpcauth into <unpacked_folder>/share/rpcauth
  7. Run <unpacked_folder>/share/rpcauth/ <YOUR_USERNAME>. Keep the output somewhere, you'll need it later.
  8. Edit your bitcoin.conf.
  9. Uncomment regtest=0 and enable it: regtest=1
  10. Uncomment rpcuser=alice and replace the value with your username.
  11. Uncomment rpcpassword=... and replace the value with the password you got from rpcauth.
  12. Uncomment rpcauth=bob:... and replace the value with the line you got from rpcauth.
  13. (Optionnal) Append datadir=<unpacked_folder>/data to the end of the file, where <unpacked_folder> is the absolute path to your unpacked folder.
  14. Run <unpacked_folder>/bin/bitcoind
  15. Open another terminal, and run <unpacked_folder>/bin/bitcoin-cli getbalance. It should return 0.

Your first node is set. Now let's setup another one to connect to. We need to use another port and another data dir.

Run: bitcoind -port=18445 -rpcport=8333 -datadir=<unpacked_folder>/data2

Generate a new address

We'll start by generating a new wallet address. We will use it for all our future operations, so keep it somewhere.

bitcoin-cli getnewaddress

Generate some blocks

bitcoin-cli generatetoaddress 50 <youraddress>

# Check the blocks are mined
bitcoin-cli getblockcount # Should return 50

Connect to other nodes

Let's connect to our second node: bitcoin-cli addnode "" add.
To keep the connection after a restart, add the following to your bitcoin.conf: addnode=

Check if your nodes are connected: bitcoin-cli getaddednodeinfo.

Now check if the second node is synchronized: bitcoin-cli -rpcport=8333 getblockcount.

Let's mine some blocks and check if everything is synchronized:

bitcoin-cli generatetoaddress 25 "<your_address>"
bitcoin-cli getblockcount # Should return 75
bitcoin-cli -rpcport=8333 getblockcount # Should return 75 

Transfer funds

We got some funds from mining the first blocks. We will transfer them to our wallet on the second node.

address=`bitcoin-cli -rpcport=8333 getnewaddress`
bitcoin-cli sendtoaddress "$1" 10

# Check the funds have been received
address=`bitcoin-cli -rpcport=8333 getwalletinfo`

Double spend

As we only have two nodes in the network, it's easy to make a 51% attack. We're going to double spend some bitcoin.

# Get a unspent output with a non-zero output
bitcoin-cli listunspent

# Create a raw transaction and sign it
# Don't forget to set the amount of your vout a little bit lower than the amount of your utxo so your tx has fees
transaction=`bitcoin-cli createrawtransaction '[{"txid":"<TX_ID>","vout":0}]' '{"$address":12.49}'`
bitcoin-cli signrawtransactionwithwallet "$transaction"

Keep the generated hex of the signed transaction. We need to disconnect both nodes and broadcast the transaction from the other node.

# Disconnect nodes
bitcoin-cli disconnectnode ""
bitcoin-cli -rpcport=8333 disconnectnode ""

# Broadcast from other node
bitcoin-cli -rpcport=8333 sendrawtransaction "<HEX>"

To make a double spend, we need to create another transaction with the same utxo and broadcast it on the chain where the first one wasn't broadcasted.

# Generate a second address to make it easier to differenciate both transactions
address=`bitcoin-cli -rpcport=8333 getnewaddress`

transaction=`bitcoin-cli createrawtransaction '[{"txid":"<TX_ID>","vout":0}]' '{"$address":12.49}'`
bitcoin-cli signrawtransactionwithwallet "$transaction"
bitcoin-cli sendrawtransaction "<HEX>"

We need to mine some blocks so when we join the two nodes, the longest chain is kept. (In our case, the one with the second transaction).

bitcoin-cli generate 50

# Join
bitcoin-cli addnode "" add

Check that the first transaction doesn't exist anymore:

bitcoin-cli -rpcport=8333 listtransactions

The last one should have the address we used for the second transaction. The double-spend worked!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment