Skip to content

Latest commit

 

History

History
executable file
·
196 lines (99 loc) · 8.21 KB

zencode-scenarios-bitcoin.md

File metadata and controls

executable file
·
196 lines (99 loc) · 8.21 KB

Testnet vs Mainnet

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.

Key generation

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.

Private key

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

Generate a private key from a known seed

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.

Public key

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

Create testnet address

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 transaction: setup and execution

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.

Load amount, recipient, sender and fee

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:

Load unspent transaction

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

Create the transaction

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 ''

Sign the transaction and format as raw transaction

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

The script used to create the material in this page

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: