This is Part 2 of 'The hard way - Bitcoin' series and I will start with 'the easy way' section first because even this gets a bit complex, then will continue with the hard stuff, crafting a Bitcoin transaction from scratch using basic math and cryptography.
We are going to generate private key, public key and Bitcoin testnet address to be used in this article.
https://gist.github.com/47a545fd30269780f65e44d09c79a730
In Bitcoin we have this concept called UTXO (Unspent Transaction Output) which is the unspent output of a previous transaction.
https://gist.github.com/867c54630617c7ab3c4220f5489eec0e
Create transaction with two parameters: input (previous transaction hash and previous transaction output index) and output (receiving address and amount to send in Satoshi).
https://gist.github.com/0d63e03478b4b81d1b8ec2732c9e1e77
Sign the input to be spent using private key and lock script.
https://gist.github.com/fe4feff08e653e0a0953362987ea326f
Create unlock script using signed endorsement and the public key then set it as transaction's input.
https://gist.github.com/0b6dc794c489f3a3b9ff8cd06523d293
Validate input with public key, lock script and signed endorsement.
https://gist.github.com/d06bc4f53bf1ef5281c88cbaf8fe638c
Validate encoded transaction as a whole.
https://gist.github.com/d4811ebc702d5f8f683eb209d363d6dc
Broadcast the transaction to network.
https://gist.github.com/883f9154c5efdc129f2d3034de397eb1
Check address and transaction history.
https://gist.github.com/1a66a15606eacef3b12292b24c43e0a4
Now lets get down to real business and craft our own transaction starting with a few utility methods that we are going to use along the way.
Two methods to convert big numbers to bytes string and vice-versa, padding with 0x00
to satisfy the required length if any.
https://gist.github.com/608aa367f83a6ff1c7f8fee3327ce999
Base58 encoding / decoding methods, Bitcoin address decoding to Hash160 (hashing twice with sha256 then ripe160) and build Bitcoin script based on destination address that can be Pay-to-PublicKey-Hash or Pay-to-Script-hash.
https://gist.github.com/c005e824b52d02af11ed04ce1ac8819c
Multiple utility methods to transform different data types into hex string.
https://gist.github.com/b6c036e3613f1aa5d2d2168f902677f0
Now, lets check the previous transaction that we want to spend.
https://gist.github.com/92d878f3ebc00c6c2674554966427828
Build transaction input from previous UTXO (Unspent Transaction Output): value, tx hash and output index.
https://gist.github.com/c7fd040710213423aa5f81bf330680a0
Build transaction output with output value and lock script.
https://gist.github.com/0029f5f5db19955ef4a6eb90a0c07875
Build the second output which is the 'change' transaction.
https://gist.github.com/631d45555846b92f691b55d34c57d4d0
Before creating the actual transction lets introduce a few elliptic curve methods methods and parameters that we all know and love already.
https://gist.github.com/bd0e2dcbb33764da27a535ead421ebe8
And these are the core methods of Elliptic Curve Digital Signature Algorithm (ECDSA), the sign/verify methods with DER signature encoding.
https://gist.github.com/1d8b61f89ba6d392686e87651174fa74
We are getting there, build Bitcoin transaction passing in the input and the two outputs.
https://gist.github.com/9754487fe8045e2fa6515b1bdccb30b3
Finally, to sign the transaction we need 3 things: private key, public key and the lock script of previous UTXO to spend.
https://gist.github.com/4bedb6c9b63bce6f92dea64316e6736b
And VOILA! take the returned transaction hex and decode/validate it:
https://gist.github.com/27a626a65d1cd9807eff1db242e0deb2
then submit it to Bitcoin testnet network via:
- Broadcast TX
- or using
bitcoin-cli
command line tool
https://gist.github.com/c7f530e00a47d3d22ec0aca2d1439d3e
Creating transaction is a bit more difficult than generating a Bitcoin address that we saw in Part 1 but it is all possible once you understand the basics of Bitcoin like UTXOs, script and transactions.
Here are the most important references but feel free to get in touch for more information.
The very end.