Signet
Signet (BIP 0325) is a proposed new test network for the Bitcoin block chain which adds an additional signature requirement to block validation. Signet is similar in nature to testnet, but more reliable and centrally controlled. There is a default signet network ("Signet Global Test Net III" as of this writing), but anyone can run their own signet network at their whim.
Run bitcoind with the -signet
flag to use the default global signet (or put signet=1
in the bitcoin.conf
file). If you wish to use a custom signet, you need to provide the block challenge (aka the block script) using -signet_blockscript=<hex>
and the genesis nonce using -signet_genesisnonce=<number>
, and preferably also at least one seed node using -signet_seednode=<host>[:<port>]
.
Differences
- Default Bitcoin network protocol listen port is 38333 (instead of 8333)
- Default RPC connection port is 38332 (instead of 8332)
- Address prefixes are different: pubkey=
0x7D
(125), p2sh=0x57
(87), privkey=0xD9
(217) - The protocol message header bytes are
0xF0C7706A
(instead of0xF9BEB4D9
) - Genesis block is generated based on the signet blockscript and genesis nonce (it is proof of work valid, but does not contain a signet commitment)
- Segwit is always enabled
- Additional consensus requirement that the coinbase witness commitment contains an extended signet commitment, which is a script satisfying the block script (usually a k-of-n multisig)
Why run Signet?
- You are an Instructor, and want to run a controlled Bitcoin network environment for teaching purposes.
- You are a Software Developer, and want to test your software.
- You want to try out experimental changes that you want to implement in Bitcoin.
- You want to test long-term running software and don't want to deal with tens of thousands of block reorgs, or days of no blocks being mined, as is the case with Testnet.
- You want an easy way to test double spends (signet plans to include support for automated double spends, where you provide two conflicting transactions and they are mined in order, with a reorg happening between them).
Genesis Block
Each signet network has its own genesis block. The coinbase signature of the genesis block for a signet network with the blockscript S
is calculated as
sha256(sha256(S))
and the output is simply
OP_RETURN
The nTime is 1534313275
, the nonce is provided (621297
for SGNIII), and the nBits (difficulty target) is 0x1e2adc28
(POW limit 00002adc28cf53b63c82faa55d83e40ac63b5f100aa5d8df62a429192f9e8ce5
).
Getting Started
Fetch and compile signet
$ git clone https://github.com/kallewoof/bitcoin.git signet $ cd signet $ git checkout signet-0.19 $ ./autogen.sh $ ./configure $ make -j5
Create bitcoin.conf file and start up the daemon
$ cd src $ mkdir signet $ echo "signet=1 daemon=1" > signet/bitcoin.conf $ ./bitcoind -datadir=signet
Verify that you're connected
$ ./bitcoin-cli -datadir=signet getconnectioncount ***SHOULD BE MORE THAN ZERO*** $ ./bitcoin-cli -datadir=signet getblockcount ***SHOULD BE MORE THAN ZERO***
Get some coins
There is a command line tool you can use to get coins directly to your instance of Signet, assuming you are on the default network. You can also use the faucet online with an address of yours.
Using online faucet
You first need an address
$ ./bitcoin-cli -datadir=signet getnewaddress
Then go to a faucet, e.g. https://signet.bc-2.jp and enter your address.
Using the command line tool
The tool is in contrib/signet
and is called getcoins.sh
. You can optionally provide a path to bitcoin-cli
using --cmd=[path]
and a compatible faucet using --faucet=[url]
followed by any number of arguments to bitcoin-cli
. The script attempts to autodetect these if left out.
$ cd ../contrib/signet $ ./getcoins.sh -datadir=../../src/signet Payment of 10.00000000 BTC sent with txid c0bfa...
Check that you received the coins
Check your faucet transaction confirming at e.g. https://explorer.bc-2.jp and then send coins around to people and/or use signet for testing your wallet/etc.
You can immediately see the amount using getunconfirmedbalance
i.e.
$ cd ../../src # if you were in contrib/signet $ ./bitcoin-cli -datadir=signet getunconfirmedbalance
You can also see info about the transaction that the faucet gave you.
$ ./bitcoin-cli -datadir=signet gettransaction THETXID
Once it has confirmed, you should see it in getbalance
.
$ ./bitcoin-cli -datadir=signet getbalance
External links
- Pull request #16411 to Bitcoin Core
- Pull request #291 to Rust-Bitcoin
- Github gist explaining how to get started
Faucets
Can also ping @kallewoof on IRC (freenode)/Twitter.
Faucet source code, if you want your own:
- https://github.com/kallewoof/bitcoin-faucet.git (node.js and mongodb)
- https://github.com/stepansnigirev/tinyfaucet.git (python)
Block explorers
Custom Signet
Creating your own signet involves a couple of steps: generate keys used for signing, define the block script, start up a node running on the new signet, and import the private key in order to sign blocks.
Generating keys used for signing a block
The most straightforward way is to simply start up a signet instance and then generating a new key from there.
$ cd PATHTOBITCOIN/bitcoin/src $ ./bitcoind -signet -daemon $ ADDR=$(./bitcoin-cli -signet getnewaddress) $ PRIVKEY=$(./bitcoin-cli -signet dumpprivkey $ADDR) $ ./bitcoin-cli -signet getaddressinfo $ADDR | grep pubkey "pubkey": "02c60c3940e5REDACTEDbd0148cd",
We need to jot down the privkey (echo $PRIVKEY
) and the pubkey (here 02c60...
).
Defining the block script
The block script is just like any old Bitcoin script, but the most common type is a k-of-n multisig. Here we will do a 1-of-1 multisig with our single pubkey above. Our script becomes
51
"1" (signature count)21
Push 0x21=33 bytes (the length of our pubkey above)02c60c3940e5REDACTEDbd0148cd
(our pubkey)51
"1" (pubkey count)ae
OP_CHECKMULTISIG
opcode
Put together, our -signet_blockscript
value becomes 512102c60c3940e5REDACTEDbd0148cd51ae
.
Grinding the genesis nonce
Since the genesis block needs to be proof-of-work valid, we need to actually mine it. This is not a problem though, because Signet difficulty starts out quite low, so it should only take a few seconds.
$ ./bitcoin-cli -signet grindblock 512102c60c3940e5REDACTEDbd0148cd51ae 12345
The genesis nonce is 12345
. Together with the block script, this defines our new Signet network!
Start up a node (issuer)
For the network to be useful, it needs to be generating blocks at decent intervals, so let's start up a node that does that (it may be useful to also use that node as a seed node for other peers).
Note that we are importing $PRIVKEY
at the end; any node that needs to issue blocks must import the privkey we generated above, or it will fail to sign blocks.
$ ./bitcoin-cli -signet stop $ datadir=$HOME/signet-custom $ mkdir $datadir $ echo "signet=1 [signet] daemon=1 signet_blockscript=512102c60c3940e5REDACTEDbd0148cd51ae signet_genesisnonce=12345" > $datadir/bitcoin.conf $ ./bitcoind -datadir=$datadir $ ./bitcoin-cli -datadir=$datadir importprivkey $PRIVKEY
Note: if you run into errors above, you may have a different signet running, which is blocking the ports. Either stop that, or set port and rpcport in the $datadir/bitcoin.conf
file under the [signet]
section and try again from the bitcoind
part above.
Run issuer
Lastly, we start the issuer script located in contrib/signet
.
$ cd ../contrib/signet $ ./issuer.sh 540 ../../src/bitcoin-cli -datadir=$datadir - checking node status - 23:51:01: node OK with 0 connection(s) - 23:51:01: mining at maximum capacity with 540 second delay between each block - 23:51:01: hit ^C to stop - 23:51:01: generating next block - 23:51:08: mined block 1 0000321422407052c06fef1eacbee402571787c9828051981adfbb5d50a2330a to 0 peer(s); idling for 540 seconds
This script will keep on mining blocks every 540 seconds (actually it will take about 60 seconds to generate a block after the difficulty has stabilized, so you should be seeing one block every 600 seconds) until you hit ctrl-C. It may be a good idea to run this in a screen, so you can check back on it occasionally.
You may also want to run the issuer with a lower idle time initially, so you get some mature coinbase outputs faster.
Next is to have your friends/colleagues/etc join the network by setting the signet_blockscript
and signet_genesisnonce
to the same as above, and connecting to your node.
|