Saturday, 26 August 2017

Bitcoin core tutorial & code walk through (Part 5) - rawtransaction

1) In part 5, we will look at Bitcoin raw transaction. Raw transaction gives you full manual control of the Bitcoin transaction, with the possibility of making errors and losing bitcoins permanently.

The bitcoin-cli command can be used to create raw transaction to send to any recipient address. There is decode raw transaction command to display the raw transaction that we have created. After that, we can use send raw transaction command to actually spend the bitcoin.

For testing purpose, the regtest network is used.


Firstly, we use listunspent command to find out the UTXO (the txid) in the wallet
./src/bitcoin-cli -regtest listunspent 

Then, we use getaccountaddress to find out the default address (the address) 

./src/bitcoin-cli -regtest getaccountaddress ""

Then, we use createrawtransaction command to construct the raw transaction
./src/bitcoin-cli -regtest createrawtransaction "[{\"txid\":\"2ca49406de60010f88876ac142f7846647942b33522a3a10bc493df480cffb34\",\"vout\":0}]" "{\"mjQgnYbydSCupJzkQS9HDBoP1CGcZZQMjt\":0.01}

The txid is from the listunspent command and address is from the getaccountaddress command. The vout of 0 is the vector output associated with the txid. The 0.01 is the amount to be paid to the address.

** when forming a new transaction, the txid of vin, must be a valid txid in listunspent, the vout of vin, must be a valid vout of that referenced transaction.

We can see that relationship using decoderawtransaction and listunspent, this decoderawransaction command shows the output of the transaction that was created. 
{
  "txid": "23eb6ae82550ce2dfcc9014c9226a755609195100139cdd57e58d2a0509ea175",
  "hash": "23eb6ae82550ce2dfcc9014c9226a755609195100139cdd57e58d2a0509ea175",
  "version": 2,
  "size": 85,
  "vsize": 85,
  "locktime": 0,
  "vin": [
    {
      "txid": "2ca49406de60010f88876ac142f7846647942b33522a3a10bc493df480cffb34",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.01000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 a3a350969090584be8887193c4eb96125ae06226 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914a3a350969090584be8887193c4eb96125ae0622688ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "mjQgnYbydSCupJzkQS9HDBoP1CGcZZQMjt"
        ]
      }
    }
  ]
}

Then, we sign the raw transaction
./src/bitcoin-cli -regtest signrawtransaction 020000000134fbcf80f43d49bc103a2a52332b94476684f742c16a87880f0160de0694a42c0000000000ffffffff0140420f00000000001976a9142ab10fb15ad20af203ee529a973cdbb1a0c2e68688ac00000000
{
  "hex": "020000000134fbcf80f43d49bc103a2a52332b94476684f742c16a87880f0160de0694a42c0000000049483045022100b5928c21d2ea2436e669948e6eb4036a0d1de9b70210d3b103d475c9cf5b7b0b02200ac3a7fd690b16607ba833bef0e15dd84a21f0b609692727af7838dd7ac21f9d01ffffffff0140420f00000000001976a9142ab10fb15ad20af203ee529a973cdbb1a0c2e68688ac00000000",
  "complete": true

}

Finally, we spend the bitcoins.
./src/bitcoin-cli -regtest sendrawtransaction 020000000134fbcf80f43d49bc103a2a52332b94476684f742c16a87880f0160de0694a42c0000000049483045022100b5928c21d2ea2436e669948e6eb4036a0d1de9b70210d3b103d475c9cf5b7b0b02200ac3a7fd690b16607ba833bef0e15dd84a21f0b609692727af7838dd7ac21f9d01ffffffff0140420f00000000001976a9142ab10fb15ad20af203ee529a973cdbb1a0c2e68688ac00000000
error code: -26
error message:
256: absurdly-high-fee

See here, if the ( input - output ) = transaction fee is too big, bitcoin core will reject to send the transaction.

2) In this analysis, the source code that handles raw transaction RPC will be walked through.
rpc/rawtransaction.cpp
UniValue createrawtransaction(const JSONRPCRequest& request)
This function creates an object of CMutableTransaction rawTx. It then sets the rawTx.nLockTime from parameter 2. It parses txid and vout, and push CTxIn object into rawTx. The function checks for output data or address. If address is used, it sets CScript scriptPubKey with the address. The the CTxOut is set with the amount and scriptPubKey. Lastly, it encodes rawTx with the function EncodeHexTx(rawTx) and returns the hex.

UniValue decoderawtransaction(const JSONRPCRequest& request)
The function creates an object of CMutableTransaction mtx, call DecodeHexTx() into mtx. It then calls TxToUniv() and returns the UniValue result.

UniValue sendrawtransaction(const JSONRPCRequest& request)
The function creates an object of CMutableTransaction mtx, decode the parameter with DecodeHexTx(). It creates CTransactionRef object , with the data of decoded mtx. It checks the mempool, the connection manager. If connection manager (g_connman) is available, it creates CInv object and push the inventory into CNode * pnode. It returns the transaction hash (txid).

UniValue signrawtransaction(const JSONRPCRequest& request)
The function creates std::vector<unsigned char> txData from the raw transaction hex data, and then CDataStream is made from the txData.
Next, the std::vector<CMutableTransaction> txVariants is made from the CDataStream objects. Then, a new CMutableTransaction mergedTx is created from txVariants.
Then, then CCoinsView and CCoinsViewCache are created to fetch previous inputs. 
If the optional key is passed as parameters, it is stored in CKey object.
It previous txout is passed as parameters, a COutPoint object and Coin are created to add to CCoinsView object.

It also checks if redeem script is given or not in the parameters.
Then, CKeyStore object is added. 
In the signing part, a SignatureData sigdata is created. ProduceSignature() is called to sign and CombineSignature() is called to merge other signatures. The UpdateTransaction() is called to update the mergedTx object. Finally, the UniValue result is filled with hex and complete field and returned.

script/sign.cpp
bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
This function takes the CScript, SignatureData, and BaseSignatureCreator, and calls SignStep() to update boolean variable named "solved". Depending the type of TX_SCRIPTHASH or TX_WITNESS_V0_KEYHASH or TX_WITNESS_V0_SCRIPTHASH, it processes and updates the sigdata. The return value is a logical "and" of VerifyScript() and the bool variable "solved".


static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey, std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
The function consists of a big switch-case conditions. Depending on the key type, different actions are taken to sign the public key. The key type is decided using Solver().

script/standard.cpp
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet)
This function firstly setup a std:multimap templates of txnouttype and CScript. If transaction is pay to script hash, or witness keyhash, or witness script hash, or null data; set the transaction type and return. If not, the function enters a for loop. In the for loop, it setup two CScript iterator, compare the iterators. If there is a match, it returns the transaction type if it is not TX_MULTISIG. Otherwise, the function set type to TX_NONSTANDARD and returns false.

Wednesday, 2 August 2017

Bitcoin core tutorial & code walk through (Part 4) - gettransaction

1) Today i will talk about some basic concepts in cryptography and its applications in Bitcoin.

Hashing
- deterministic
- arbitrary length input to fixed length output
- could be many to 1 mapping (collision)
- difficult to reverse (one way mapping)
- hashed message authentication code (HMAC), integrity and authenticity of the message

Encryption
- 1 to 1 mapping
- reversible

private key --> public key --> bitcoin address
      ECC encryption         hashing
            K = G*k
where
G: generator function
k: private key
K: public key

Bitcoin network node with 4 functions
- wallet, miner, blockchain, network routing

Merkle root: binary hash tree used in a block, it is a summary of transactions in a block

Fork: a change in consensus rules

Colored coins:
- use bitcoin transaction to record extrinsic assets
- bitcoin is intrinsic to the blockchain
- avoid using a colored coin related key in a regular bitcoin wallet,
- colored coins should not be sent to address managed by regular wallets

Coinbase
- coinbase transaction is first transaction in each block
- coinbase in genesis block cannot be spent, and that coinbase transaction cannot be displayed

P2PKH
- pay to public key hash
- hide the public key until users are ready to spend their coins
- P2PK is pay to public key
- the first bitcoin transaction is P2PK

2) In this section, i will show you how to get the details of bitcoin transaction

$ ./src/bitcoin-cli -regtest getblock    60fba3ca57ca71dfcc3361abf3b2b3c199e6f4a0b1c1d4e7d8ac12cb9a7de986
{
  "hash": "60fba3ca57ca71dfcc3361abf3b2b3c199e6f4a0b1c1d4e7d8ac12cb9a7de986",
  "confirmations": 511,
  "strippedsize": 226,
  "size": 226,
  "weight": 904,
  "height": 1,
  "version": 536870912,
  "versionHex": "20000000",
  "merkleroot": "2ca49406de60010f88876ac142f7846647942b33522a3a10bc493df480cffb34",
  "tx": [
    "2ca49406de60010f88876ac142f7846647942b33522a3a10bc493df480cffb34"
  ],
......
}

The command getblock returns the txid of the block. The "tx" field contains the txid.

$ ./src/bitcoin-cli -regtest gettransaction  2ca49406de60010f88876ac142f7846647942b33522a3a10bc493df480cffb34
{
  "amount": 50.00000000,
  "confirmations": 511,
  "generated": true,
  "blockhash": "60fba3ca57ca71dfcc3361abf3b2b3c199e6f4a0b1c1d4e7d8ac12cb9a7de986",
  "blockindex": 0,
  "blocktime": 1499419297,
  "txid": "2ca49406de60010f88876ac142f7846647942b33522a3a10bc493df480cffb34",
  "walletconflicts": [
  ],
  "time": 1499419297,
  "timereceived": 1499419297,
  "bip125-replaceable": "no",
  "details": [
    {
      "account": "",
      "address": "mhTqgiUaBFPgA2kPrKqDNVqh8xsrkBMkGu",
      "category": "generate",
      "amount": 50.00000000,
      "vout": 0
    }
  ],
  "hex": "02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a01000000232102910a020f84bca55765fdfc4ef9e788cd6ee137242338533543f6914979fb7ce5ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000"
}

The command gettransaction returns the object about the given transaction.

3)  In this analysis, the source code that handles gettransaction RPC will be walked through.

For gettransaction rpc

wallet/rpcwallet.cpp
UniValue gettransaction(const JSONRPCRequest& request)

The function firstly get a pointer to the CWallet object.
It creates a CWalletTx object, CAmount object, calls WalletTxToJSON() to display the output in JSON format. The ListTransactions() will include the sent and received transaction. Then, it calls EncodeHexTx().

core_write.cpp
The EncodeHexTx(const CTransaction& tx, const int serialFlags)  encodes a string, and returns the UniValue to the RPC caller.