Riecoin needs support! We are offering a 1,000,000 RIC bounty, which was worth more than $500,000 during the Riecoin ATH, to whoever makes a fruitful partnership with us, and significantly contributes to the Riecoin adoption.
This page will explain how to create a Riecoin Segwit Transaction from scratch. Since Riecoin reached almost 100% Segwit adoption, we can forget about the obsolete Legacy transactions and our example will be a "pure" Segwit transaction, with only P2WPKH inputs and outputs to make things simpler. One should be able to manually create arbitrary Segwit P2WPKH transaction without using existing wallets after reading this page.
How transactions work in Bitcoin/Riecoin
As one can often read while studying Bitcoin and other cryptocurrencies, there is no concept of balance internally. The system rather works with "tokens", called Unspent Transaction Outputs (UTXOs), which can be consumed (as inputs) and produced (as outputs) via transactions. Outputs can themselves be consumed later (but until then they are unspent, hence their name of UTXOs). Note that the number of outputs or their values do not have to be the same as the inputs.
One must satisfy some conditions in order to be able to spend an UTXO. In the P2WPKH case, a proof of ownership of a private key such that the Ripemd160 of the Sha256 of its public key gives the value required by the UTXO must be shown. Note that we always consider the compressed public key here.
The balance of an address would be the sum of the values of the UTXOs that can be spent using its private key.
Suppose that we want to send 7.5 RIC to ric1qr3yxckxtl7lacvtuzhrdrtrlzvlydane2h37ja. We know that we have 8 RIC available, consisting of the following three UTXOs, consisting of a value, the Transaction Id in which they were created, and the output index (which output in the transaction):
1. 5 RIC 10bba5503fd17c4d91b84bada8b7e3fa162e2225dc64e8224155cd171aa92ebf:0 2. 2 RIC 10bba5503fd17c4d91b84bada8b7e3fa162e2225dc64e8224155cd171aa92ebf:1 3. 1 RIC 6057db6d1c2e4c6e9395c10e8a8e421cac0ae54d4b9f223b287d555ffa6b61c8:0
So the second UTXO was created in Transaction 10bba5503fd17c4d91b84bada8b7e3fa162e2225dc64e8224155cd171aa92ebf, and is its second output (we count starting with 0). These UTXOs will become the inputs of our transaction.
Input 1 requires to prove the ownership of a private key such that the hash of its public key is (this is called the witness program)
While inputs 2 and 3 require this to be
Input 1 can be spent with ric1qfx5jqhfh7nuffnlg5nzud07skuvzzd48zy8r39, which we know the private key. It and the public key are
Inputs 2 and 3 can be spent with ric1qwprhxtdm0x62czkedwz09a3j52a0q8vqfl462v, with keys
One can verify that computing the Ripemd160 of the Sha256 of the public keys gives the two hashes above. Proving that we know the private keys without revealing it is done in the signature step of the transaction building.
Regarding the outputs of the transaction, we know that we need one output worth 7.5 RIC to pay ric1qr3yxckxtl7lacvtuzhrdrtrlzvlydane2h37ja. What will happen to the remaining 0.5 RIC? If we don't do anything else, the whole amount will become the transaction fee, which can be claimed by the miner who finds the block including the transaction. So unless you are feeling generous, there should be a change address which will receive the remaining amount, minus a small amount for the fee. Let's choose a fee 0.001 RIC, so there will be 0.499 RIC that will be sent to a change address, which will be ric1qpttn5u8u9470za84kt4y0lzz4zllzm4pyzhuge.
We now have enough context to build the transaction. Three UTXOs will be the inputs of our transaction, and this will generate two new outputs.
We start with the Transaction Version, which is currently 2. This takes 4 bytes, or 8 hex digits, and is encoded in Little Endian.
Segwit Transactions must include these two bytes after the Transaction Version, called the Marker and the Flag,
Now, we will insert the inputs. This is firstly done by indicating how many they are: 3.
One input consists of the previous Transaction Id, the Output Index, a ScriptSig, and the Sequence.
- For some reason, TxId Endianness must be reversed!
- The input index takes 4 bytes and is in Litlle Endian;
- The ScriptSig was used in Legacy Transactions to sign the inputs here and prove that you can spend it. However, this section was moved to another place for Segwit, so the ScriptSig is empty (but we still need to precise its size of 0);
- The sequence can be assumed to be ffffffff.
Here is what we get for the three inputs,
bf2ea91a17cd554122e864dc25222e16fae3b7a8ad4bb8914d7cd13f50a5bb10 00000000 00 ffffffff bf2ea91a17cd554122e864dc25222e16fae3b7a8ad4bb8914d7cd13f50a5bb10 01000000 00 ffffffff c8616bfa5f557d283b229f4b4de50aac1c428e8a0ec195936e4c2e1c6ddb5760 00000000 00 ffffffff
Now, we insert the outputs. Like before, we first specify how many of them there are.
The outputs consist of the amount and the ScriptPubKey.
- The amounts are represented as 64 bits integers (8 bytes/16 hex digits), as riemanns. So for example, 7.5 RIC is equal to 750000000 riemanns, which is in hexadecimal 2cb41780. But this must be encoded in Little Endian.
- The ScriptPubKey is calculated by extracting the witness program from the address, then prepending it with its size + 2, the byte 0, and its size. For P2WPKH, these three bytes are 160014.
We obtain for both outputs,
8017b42c00000000 16 00 14 1c486c58cbffbfdc317c15c6d1ac7f133e46f679 e069f90200000000 16 00 14 0ad73a70fc2d7cf174f5b2ea47fc42a8bff16ea1
We must now sign the inputs and place the signatures in the "witness section", which in some way replace the legacy ScriptSigs as previously mentioned. This is a process even more complicated than everything we have seen so far reunited.
For signing one output, we must sign the hash of the serialization of the ten following fields:
- nVersion: same as before, 02000000;
- hashPrevouts: concatenate the bytes of the TxId (32 bytes) + index (4 bytes) of all the inputs, and compute the sha2562 of this;
- hashSequence: concatenate the sequences (ffffffff repeated as many times as there are inputs) and compute the sha2562 of this;
- outpoint: concatenate the bytes of the TxId + index of the current input (and don't hash this time)
- scriptCode: for the current input, put the witness program size + 5, the two bytes 76a9, the witness program size, the witness program itself and append this with the two bytes 88ac;
- value: the 64 bits/8 bytes value of the current input in Little Endian
- nSequence of the input: just insert ffffffff;
- hashOutputs: concatenate all the outputs, in the format amount (Little Endian 8 bytes) . witness program size + 2 . 00 . witness program, and compute the sha2562 of this;
- nLocktime of the transaction: can be assumed to be 00000000;
- sighash type of the signature: 01000000.
Here are the three sequences of bytes that must be hashed before signature for the inputs
020000003eccbd42844af745cde75c65b7313fbdf64b2d17eb10a61ab4501feca4b3ea0a82a7d5bb59fc957ff7f737ca0b8be713c705d6173783ad5edb067819bed70be8bf2ea91a17cd554122e864dc25222e16fae3b7a8ad4bb8914d7cd13f50a5bb10000000001976a91449a9205d37f4f894cfe8a4c5c6bfd0b7182136a788ac0065cd1d00000000ffffffff9cb4a3a5b32561591e235cc40756210ca2142c0f9e03b772e9add7aa5bfdadd30000000001000000 020000003eccbd42844af745cde75c65b7313fbdf64b2d17eb10a61ab4501feca4b3ea0a82a7d5bb59fc957ff7f737ca0b8be713c705d6173783ad5edb067819bed70be8bf2ea91a17cd554122e864dc25222e16fae3b7a8ad4bb8914d7cd13f50a5bb10010000001976a9147047732dbb79b4ac0ad96b84f2f632a2baf01d8088ac00c2eb0b00000000ffffffff9cb4a3a5b32561591e235cc40756210ca2142c0f9e03b772e9add7aa5bfdadd30000000001000000 020000003eccbd42844af745cde75c65b7313fbdf64b2d17eb10a61ab4501feca4b3ea0a82a7d5bb59fc957ff7f737ca0b8be713c705d6173783ad5edb067819bed70be8c8616bfa5f557d283b229f4b4de50aac1c428e8a0ec195936e4c2e1c6ddb5760000000001976a9147047732dbb79b4ac0ad96b84f2f632a2baf01d8088ac00e1f50500000000ffffffff9cb4a3a5b32561591e235cc40756210ca2142c0f9e03b772e9add7aa5bfdadd30000000001000000
We must hash them with sha2562:
bd2f4e4e676e682c2760ae18dfce1f07424c57de8c75a385f29ee421e33102a8 1624973f09825d95f76e5f73bb021c0c9e09851fbc7bcd959361937fe2a230a7 b329eedd40b74b7d6d8e1ee16607b8832ec5ef0190bb801b34240edb7fc0ae32
These must be signed with the correct private key. Note that the signatures are randomized, so there is no way to be sure that this step was done right without being sure that the whole transaction is valid... And they may also have different sizes (no leading or trailing zeros should be added).
3045022100965965c0268c40488616755394742bd54ada24bcf6d961e5971a3edcc9751ee30220113825b328013a5d118769705691fa36d91cb641529b23a352fa0ca206fac4af 3045022100d9c15a85357a66d4b9b7af3420eb44153769e6caa85489601cfa3a8d496d369d02206dd4f2ad9bee01c4ceb568bbfac2dc29397607c6b12c0bab144d43b6c5b1fca8 304402201e5b36bfd298fc2d051a3a367fe953a906e65a046084d2369068935ff3e76d8f02205287b14b5af590ce128cf173f90278fcc6de156c2a9bcb2563c1b436a8c0ee5e
With the signatures, we can build the witnesses. Their format is
02 . signature size + 1 . signature . 01 . public key size . public key
So the witnesses are
02483045022100965965c0268c40488616755394742bd54ada24bcf6d961e5971a3edcc9751ee30220113825b328013a5d118769705691fa36d91cb641529b23a352fa0ca206fac4af0121033a90b7771433d6534cae4dbc176df40e83af72982aa593aba475856a8327b165 02483045022100d9c15a85357a66d4b9b7af3420eb44153769e6caa85489601cfa3a8d496d369d02206dd4f2ad9bee01c4ceb568bbfac2dc29397607c6b12c0bab144d43b6c5b1fca801210250e0eaac228d58d4386129e260dd4c947b0ef4f65cdc9773ffe67bc78d5ff1d4 0247304402201e5b36bfd298fc2d051a3a367fe953a906e65a046084d2369068935ff3e76d8f02205287b14b5af590ce128cf173f90278fcc6de156c2a9bcb2563c1b436a8c0ee5e01210250e0eaac228d58d4386129e260dd4c947b0ef4f65cdc9773ffe67bc78d5ff1d4
We end the transaction with the Lock Time, which can like the Sequences be assumed to be
Finally, our transaction is this 520 byte sequence
To calculate the Transaction Id, the Segwit related bytes must be stripped (Marker/Flag and Witnesses), and the sha2562 of the remaining must be calculated (and the Endianness reversed)
The Transaction Id is
Which can be entered in a Riecoin Explorer, as the transaction was actually sent to the Riecoin network and included in a block.
Notes and references
- It is actually in the Variable Integer/VarInt Format. We use here just one byte for any number between 1 and 251 inputs. For 252 inputs and more, we must put the byte FD and then encode the number in Little Endian with 2 bytes.
- Read this to learn more about what could be its possible use.
- For this, you can look at the Bech32 specification or study/use reference code.
- And there is even one more subtlety. Signatures are actually two numbers r and s, and the s must not exceed some threshold. If so, one could either make another signature or replace s by n - s, n being the order of the group used for Secp256k1. See this to learn more.