There are format difference between Bitcoin testnet and mainnet. We wanted to enable both the networks, making it comfortable for the developer to switch from one to another (note: keys and protocols have slight differences between testnet and mainnet.
For this reason in any statement that is specific for the network, by swapping the word testnet with bitcoin, you change the way the statement works.
For example, In order to create a key for the testnet, you can use the statement
When I create the testnet key
On the other hand, to create a key for mainnet you can use:
When I create the bitcoin key
The example below is created for the testnet as we believe that's a convenient starting point.
Note: you don't need to define a scenario, as the zencode statements for bitcoin are always loaded.
On this page we prioritize security over easy of use, therefore we have chosen to keep some operations separated.
Particularly the generation of private and public key (and the creation and signature of transactions, further down), which can indeed be merged into one script, but you would end up with both the keys in the same output.
The script below generates a bitcoin testnet private key.
Note: you don't need to declare your identity using the statement Given I am 'User1234', but you can still do it if it comes handy, and then use the statement Then print my 'keys' to format the output.
The output should look like this:
You want to store this into the file keys.json
Key generation in Zenroom uses by default a pseudo-random as seed, that is internally generated.
You can also opt to use a seed generated elsewhere, for example by using the keypairoom library or it's npm package.
The statements looks like:
When I create the testnet key with secret key 'mySeed'
Which requires you to load a 32 bytes long base64 object named 'mySeed', the statement is defined here.
Once you have created a private key, you can feed it to the following script to generate the public key:
The output should look like this:
You want to store this into the file pubkey.json
Next, you'll need to generate a bitcoin testnet address, you'll need the keys.json you've just generated as input to the following script:
The output should look like:
The statements used to manage a transaction, follow closely the logic of the Bitcoin protocol. What we'll do here is:
- Prepare a JSON file containing the amount to be transferred, recipient, sender and fee.
- Add to the JSON file a list of the unspent transactions, as it is returned from a Bitcoin explorer (we're using Blockstream in the test).
- Then we use the file above, to create a testnet transaction.
- After creating the transaction, first we'll sign it using the key we generated above, then we'll create a raw transaction out of it, which can be posted to any Bitcoin client.
Now prepare a JSON file containing the amount, recipient, fee and sender: the sender in this example is the one we have just generated as testnet_address. The file should look like this:
Then, get a list of the unspent transactions from your address, which is again the testnet_address we have generated above, but at this point we have already transferred some coins to this address (otherwise the list of unspent transactions would be empty). In the example we curl blockstream.info with the address we generated above:
The result should be a JSON file looking like:
Now merge the transaction_data.json and unspent.json two files together into order.json.
You can do so for example by using jq:
jq -s '.[0] * .[1]' unspent.json transaction_data.json
Now, you can feed the file order.json to the script:
Which will produce an unsigned transaction, formatted in human-readable JSON, that should look like:
If the recipient address is saved under a name other than recipient then the transaction can be created using the statement:
When I create the testnet transaction to ''
You can now pass the transaction produced from the above script, along with keys.json to the following script that will sign the transaction and format it so that we can pass it to any Bitcoin node.
The signed transaction should look like:
Note: this script and the previous one can be merged into one script that creates the transaction, signs it and prints it out as raw transaction.
In this example we kept the script separated as this script was originally meant to demonstrate how to make an offline Bitcoin wallet, where the signature happens on different machine (which can be kept offline for security reasons). You can merge the two scripts and feed the resulting script with keys.json we created on top of this page and order.json
All the smart contracts and the data you see in this page are generated by the scripts bitcoin.bats . If you want to run the scripts (on Linux) you should:
- git clone https://github.com/dyne/Zenroom.git
- install jq
- download a zenroom binary and place it /bin or /usr/bin or in ./Zenroom/src