- Download bitcoin core
- Unpack it wherever you want.
- Create a directory named
data
inside the unpacked folder. - Create a directory named
.bitcoin
inside your home folder:mkdir ~/.bitcoin
- Copy bitcoin.conf into
~/.bitcoin
- Copy rpcauth into
<unpacked_folder>/share/rpcauth
- Run
<unpacked_folder>/share/rpcauth/rpcauth.py <YOUR_USERNAME>
. Keep the output somewhere, you'll need it later. - Edit your
bitcoin.conf
. - Uncomment
regtest=0
and enable it:regtest=1
- Uncomment
rpcuser=alice
and replace the value with your username. - Uncomment
rpcpassword=...
and replace the value with the password you got fromrpcauth
. - Uncomment
rpcauth=bob:...
and replace the value with the line you got fromrpcauth
. - (Optional) Append
datadir=<unpacked_folder>/data
to the end of the file, where<unpacked_folder>
is the absolute path to your unpacked folder. - Run
<unpacked_folder>/bin/bitcoind
- Open another terminal, and run
<unpacked_folder>/bin/bitcoin-cli getbalance
. It should return0
.
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
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
bitcoin-cli generatetoaddress 50 <youraddress>
# Check the blocks are mined
bitcoin-cli getblockcount # Should return 50
Let's connect to our second node: bitcoin-cli addnode "127.0.0.1:18445" add
.
To keep the connection after a restart, add the following to your bitcoin.conf
: addnode=127.0.0.1:18445
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
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
bitcoin-cli -rpcport=8333 getwalletinfo
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 "127.0.0.1:18445"
bitcoin-cli -rpcport=8333 disconnectnode "127.0.0.1:18444"
# 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 "127.0.0.1:18445" 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!
You can run
bitcoin-cli -rpcport=8333 getnewaddress
in the terminal to get a new address and save it somewhere. Its scope here is to use that address later on. In thebitcoin.conf
file you should update the address value with the value you got when running the command in the terminal. I hope this helps!