Update 15_2_Programming_Bitcoind_with_C.md

This commit is contained in:
Javier Vargas 2020-06-24 13:16:49 +02:00 committed by GitHub
parent 8de7475d37
commit a58385d5fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,10 +11,11 @@ We're going to program a simplistic first cut version of `sendtoaddress`, which
1. Request an address and an amount
2. Set an arbitrary fee
3. Find a UTXO that's large enough for the amount + the fee
4. Create a change address
5. Create a raw transaction that sends from the UTXO to the address and the change address
6. Sign the transaction
7. Send the transaction
4. Create a bench 32 address
5. Create a change address
6. Create a raw transaction that sends from the UTXO to the address and the change address
7. Sign the transaction
8. Send the transaction
### Plan for Your Future
@ -152,7 +153,24 @@ if (!tx_id) {
> **WARNING:** A real program would use subroutines for this sort of lookup, so that you could confidentally call various RPCs from a library of C functions. We're just going to blob it all into `main` as part of our KISS philosophy of simple examples.
### 4. Create a Change Address
### 4. Create a Bech32 Address
Repeat the standard RPC-lookup methodology to get a new address using get new address method.
```
lu_response = bitcoinrpc_resp_get (btcresponse);
lu_result = json_object_get(lu_response,"result");
char *address = strdup(json_string_value(lu_result));
printf("adress %s \n", address);
```
Output
```
$ cc getaddress.c -lbitcoinrpc -ljansson -o getaddress
$ ./getaddress
adress tb1qpxlguwckkqalcg6xrv4ujlmkzqe79nkngcvudf
```
### 5. Create a Change Address
Repeat the standard RPC-lookup methodology to get a change address:
```
@ -183,7 +201,7 @@ The only difference is in what particular information we extract from our JSON o
> **WARNING:** Here's another place that a subroutine would be really nice: to abstract out the whole RPC method initialization and call.
### 5. Create a Raw Transaction
### 6. Create a Raw Transaction
Creating the actual raw transaction is the other tricky part of programming your `sendtoaddress` replacement. That's because it requires the creation of a complex JSON object as a paramter.
@ -194,7 +212,7 @@ createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex"
```
To review, your inputs will be a JSON array containing one JSON object for each UTXO. Then the ouputs will all be in one JSON object. It's easiest to create these JSON elements from the inside out, using `jansson` commands.
#### 5.1. Create the Input Parameters
#### 6.1. Create the Input Parameters
To create the input object for your UTXO, use `json_object`, then fill it with key-values using either `json_object_set_new` (for newly created references) or `json_object_set` (for existing references):
```
@ -213,7 +231,7 @@ inputparams = json_array();
json_array_append(inputparams,inputtxid);
```
#### 5.2 Create the Output Parameters
#### 6.2 Create the Output Parameters
To create the output array for your transaction, follow the same format, creating a JSON object with `json_object`, then filling it with `json_object_set`:
```
@ -231,7 +249,7 @@ json_object_set(outputparams, changeaddress, json_string(tx_change_string));
> **WARNING:** You might expect to input your Bitcoin values as numbers, using `json_real`. Unfortunately, this exposes one of the major problems with integrating the `jansson` library and Bitcoin. Bitcoin is only valid to eight significant digits past the decimal point. You might recall that .00000001 BTC is a satoshi, and that's the smallest possible division of a Bitcoin. Doubles in C offer more significant digits than that, though they're often imprecise out past eight decimals. If you try to convert straight from your double value in C (or a float value, for that matter) to a Bitcoin value, the imprecision will often create a Bitcoin value with more than eight significant digits. Before Bitcoin Core 0.12 this appears to work, and you could use `json_real`. But as of Bitcoin Core 0.12, if you try to give `createrawtransaction` a Bitcoin value with too many significant digits, you'll instead get an error and the transaction will not be created. As a result, if the Bitcoin value has _ever_ become a double or float, you must reformat it to eight significant digits past the digit before feeding it in as a string. This is obviously a kludge, so you should make sure it continues to work in future versions of Bitcoin Core.
#### 5.3 Create the Parameter Array
#### 6.3 Create the Parameter Array
To finish creating your parameters, simply to bundle them all up in a JSON array:
```
@ -240,7 +258,7 @@ params = json_array();
json_array_append(params,inputparams);
json_array_append(params,outputparams);
```
#### 5.4 Make the RPC Call
#### 6.4 Make the RPC Call
Use the normal method to create your RPC call:
```
@ -263,7 +281,7 @@ lu_result = json_object_get(lu_response,"result");
char *tx_rawhex = strdup(json_string_value(lu_result));
```
### 6. Sign the Transaction
### 7. Sign the Transaction
It's a lot easier to assign a simple parameter to a function. You just create a JSON array, then assign the parameter to the array:
```
@ -294,7 +312,7 @@ json_decref(lu_signature);
> ***WARNING:*** A real-world program would obviously carefully test the response of every RPC command to make sure there were no errors. That's especially true for `signrawtransaction`, because you might end up with a partially signed transaction. Worse, if you don't check the errors in the JSON object, you'll just see the `hex` and not realize that it's either unsigned or partially signed.
### 7. Send the Transaction
### 8. Send the Transaction
You can now send your transaction, using all of the previous techniques:
```