Merge branch 'ch03'

pull/186/head
Andreas M. Antonopoulos 8 years ago
commit d7ea27d194

@ -22,7 +22,7 @@ If you're a developer, you will want to setup a development environment with all
[TIP]
====
In many of the examples in this chapter we will be using the operating system's command-line interface (also known as a "shell"), accessed via a "terminal" application. The shell will display a prompt; you type a command; and the shell responds with some text and a new prompt for your next command. The prompt may look different on your system, but in the examples below it is denoted by a +$+ symbol. In the examples when you see text after a +$+ symbol, don't type the +$+ symbol but type the command immediately following it, then press enter to execute the command. In the examples, the lines below each command are the operating system's responses to that command. When you see the next +$+ prefix, you'll know it's a new command and you should repeat the process.
In many of the examples in this chapter we will be using the operating system's command-line interface (also known as a "shell"), accessed via a "terminal" application. The shell will display a prompt; you type a command; and the shell responds with some text and a new prompt for your next command. The prompt may look different on your system, but in the examples below it is denoted by a +$+ symbol. In the examples, when you see text after a +$+ symbol, don't type the +$+ symbol but type the command immediately following it, then press enter to execute the command. In the examples, the lines below each command are the operating system's responses to that command. When you see the next +$+ prefix, you'll know it's a new command and you should repeat the process.
====
In this example, we are using the +git+ command to create a local copy ("clone") of the source code.
@ -255,6 +255,8 @@ It is also recommended to set alertnotify so you are notified of problems;
for example: alertnotify=echo %s | mail -s "Bitcoin Alert" admin@foo.com
----
As you can see, the first time you run +bitcoind+ it tells you that you need to build a configuration file, with at least an rpcuser and rpcpassword entry. Additionally, it is recommended you set up the alerting mechanism. In the next section we will examine the various configuration options and set up a configuration file.
==== Configuring the Bitcoin Core Node
Edit the configuration file in your preferred editor and set the parameters, replacing the password with a strong password as recommended by bitcoind. Do _not_ use the password shown in the book. Create a file inside the +.bitcoin+ directory (under your user's home directory) so that it is named +.bitcoin/bitcoin.conf+ and provide a username and password:
@ -265,9 +267,7 @@ rpcuser=bitcoinrpc
rpcpassword=CHANGE_THIS
----
While you're editing this configuration file, you might want to set a few other options. In addition to the +rpcuser+ and +rpcpassword+ options, Bitcoin Core offers dozens of configuration options that modify the behavior of the network node, the storage of the blockchain and many other aspects of its operation.
To see a listing of these options, run +bitcoind --help+:
In addition to the +rpcuser+ and +rpcpassword+ options, Bitcoin Core offers more than one hundred configuration options that modify the behavior of the network node, the storage of the blockchain and many other aspects of its operation. To see a listing of these options, run +bitcoind --help+:
----
bitcoind --help
@ -316,6 +316,13 @@ maxreceivebuffer/maxsendbuffer:: Limit per-connection memory buffer to this many
minrelaytxfee:: Set the minimum fee transaction you will relay. Below this value, the transaction is treated as zero fee. Use this on memory-constrained nodes to reduce the size of the in-memory transaction pool.
[[txindex]]
.Transaction Database Index and txindex Option
****
((("transaction database index")))By default, Bitcoin Core builds a database containing _only_ the transactions related to the user's wallet. If you want to be able to access _any_ transaction with commands like +getrawtransaction+ (see ), you need to configure Bitcoin Core to build a complete transaction index, which can be achieved with the((("txindex option (Bitcoin Core)"))) +txindex+ option. Set +txindex=1+ in the Bitcoin Core configuration file. If you don't set this option at first and later set it to full indexing, you need to restart bitcoind with the +-reindex+ option and wait for it to rebuild the index.
****
Here's how you might combine the above options:
A fully-indexed node, running as an API back-end for a bitcoin application:
@ -350,9 +357,7 @@ rpcpassword=CHANGE_THIS
----
====
Now, run the Bitcoin Core client. The first time you run it, it will reconstruct a complete local copy of the bitcoin blockchain by downloading all the blocks.
To test your configuration, run Bitcoin Core with the option +printtoconsole+ to run in the foreground with output to the console:(((range="endofrange", startref="ix_ch03-asciidoc3")))
Once you've edited the configuration file and set the options that best represent your needs, we can test +bitcoind+ with this configuration. Run Bitcoin Core with the option +printtoconsole+ to run in the foreground with output to the console:(((range="endofrange", startref="ix_ch03-asciidoc3")))
----
$ bitcoind -printtoconsole
@ -595,11 +600,7 @@ The transaction decode shows all the components of this transaction, including t
We can further explore the blockchain by examining the previous transaction referenced by its txid in this transaction using the same commands (e.g., +getrawtransaction+). Jumping from transaction to transaction we can follow a chain of transactions back as the coins are transmitted from owner address to owner address.
[[txindex]]
.Transaction Database Index and txindex Option
****
((("transaction database index")))By default, Bitcoin Core builds a database containing _only_ the transactions related to the user's wallet. If you want to be able to access _any_ transaction with commands like +getrawtransaction+, you need to configure Bitcoin Core to build a complete transaction index, which can be achieved with the((("txindex option (Bitcoin Core)"))) +txindex+ option. Set +txindex=1+ in the Bitcoin Core configuration file (usually found in your home directory under _.bitcoin/bitcoin.conf_). Once you change this parameter, you need to restart bitcoind and wait for it to rebuild the index.(((range="endofrange", startref="ix_ch03-asciidoc30")))(((range="endofrange", startref="ix_ch03-asciidoc29")))(((range="endofrange", startref="ix_ch03-asciidoc28")))(((range="endofrange", startref="ix_ch03-asciidoc27")))(((range="endofrange", startref="ix_ch03-asciidoc26")))(((range="endofrange", startref="ix_ch03-asciidoc25")))(((range="endofrange", startref="ix_ch03-asciidoc24")))(((range="endofrange", startref="ix_ch03-asciidoc23")))
****
(((range="endofrange", startref="ix_ch03-asciidoc30")))(((range="endofrange", startref="ix_ch03-asciidoc29")))(((range="endofrange", startref="ix_ch03-asciidoc28")))(((range="endofrange", startref="ix_ch03-asciidoc27")))(((range="endofrange", startref="ix_ch03-asciidoc26")))(((range="endofrange", startref="ix_ch03-asciidoc25")))(((range="endofrange", startref="ix_ch03-asciidoc24")))(((range="endofrange", startref="ix_ch03-asciidoc23")))
==== Exploring Blocks
@ -664,21 +665,122 @@ $ bitcoin-cli getblock 0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b3&#x
The block contains 419 transactions the 64th transaction listed (+0627052b...+) is Alice's coffee payment. The +height+ entry tells us this is the 277316th block in the blockchain.
==== Using Bitcoin Core's Programmatic Interface
The +bitcoin-cli+ helper is very useful for exploring the Bitcoin Core API and testing functions. But the whole point of an Application Programming Interface is to access functions programmatically. In this section we will demonstrate accessing Bitcoin Core from another program.
Bitcoin Core's API is a JSON-RPC interface. JSON stands for JavaScript Object Notation and it is a very convenient way to present data that both humans and programs can easily read. RPC stands for Remote Procedure Call, which means that we are calling procedures (functions) that are remote (on the Bitcoin Core node) via a network protocol. In this case, the network protocol is HTTP, or HTTPS (for encrypted connections).
When we used the +bitcoin-cli+ command to get help on a command, it showed us an example of using +curl+, the versatile command-line HTTP client to construct one of these JSON-RPC calls:
----
$ curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
----
This command shows that +curl+ submits an HTTP request to the local host (127.0.0.1), connecting to the default bitcoin port (8332), and submitting a +jsonrpc+ request for the +getinfo+ method, using a +text/plain+ encoding.
If you're implementing a JSON-RPC call in your own program, you can use a generic HTTP library to construct the call, similar to what is shown in the +curl+ example above.
However, there are libraries in most every programming language that "wrap" the Bitcoin Core API in a way that makes this a lot simpler. We will use the +python-bitcoinlib+ library to simplify API access. Remember, this requires you to have a running Bitcoin Core instance which will be used to make JSON-RPC calls.
The Python script below makes a simple +getinfo+ call and prints the +block+ parameter from the data returned by Bitcoin Core:
[[rpc_example]]
.Running +getinfo+ via Bitcoin Core's JSON-RPC API
====
[source,python]
----
include::code/rpc_example.py[]
----
====
Running it, gives us the following result:
----
$ python rpc_example.py
394075
----
It tells us that our local Bitcoin Core node has 394075 blocks in its blockchain. Not a spectacular result, but it demonstrates the basic use of the library as a simplified interface to Bitcoin Core's JSON-RPC API.
Next, let's use the +getrawtransaction+ and +decodetransaction+ calls to retrieve the details of Alice's coffee payment. In the following example, we retrieve Alice's transaction and list the transaction's outputs. For each output, we show the recipient address and value. As a reminder, Alice's transaction had one output paying Bob's Cafe and one output for change back to Alice.
[[rpc_transaction]]
.Retrieving a transaction and iterating its outputs
====
[source,python]
----
include::code/rpc_transaction.py[]
----
====
Running this code, we get:
----
$ python rpc_transaction.py
([u'1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA'], Decimal('0.01500000'))
([u'1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK'], Decimal('0.08450000'))
----
Both of the examples above are rather simple. You don't really need a program to run them, you could just as easily use the +bitcoin-cli+ helper. The next example, however, requires several hundred RPC calls and more clearly demonstrates the use of a programmatic interface.
In <<rpc_block>>, we first retrieve block 277316, then retrieve each of the 419 transactions within by reference to each transaction ID. Next, iterate through each of the transaction's outputs and add up the value.
[[rpc_block]]
.Retrieving a block and adding all the transaction outputs
====
[source,python]
----
include::code/rpc_block.py[]
----
====
Running this code, we get:
----
$ python rpc_block.py
('Total value in block: ', Decimal('10322.07722534'))
----
Our example code calculates the total value transacted in this block is 10,322.07722534 BTC (inclusive of the 25 BTC reward and 0.0909 BTC in fees). Compare that to the amount reported by a block explorer site, by searching for the block hash or height. Some block explorers report the total value excluding the reward and excluding the fees. See if you can spot the difference.
[[alt_libraries]]
=== Alternative Clients, Libraries, and Toolkits
((("clients, alternative", id="ix_ch03-asciidoc47", range="startofrange")))((("libraries, alternative", id="ix_ch03-asciidoc48", range="startofrange")))((("toolkits, alternative", id="ix_ch03-asciidoc49", range="startofrange")))Beyond the reference client (bitcoind), other clients and libraries can be used to interact with the bitcoin network and data structures. These are implemented in a variety of programming languages, offering programmers native interfaces in their own language.
((("clients, alternative", id="ix_ch03-asciidoc47", range="startofrange")))((("libraries, alternative", id="ix_ch03-asciidoc48", range="startofrange")))((("toolkits, alternative", id="ix_ch03-asciidoc49", range="startofrange"))) There are many alternative clients, libraries, toolkits and even full-node implementations in the bitcoin ecosystem. These are implemented in a variety of programming languages, offering programmers native interfaces in their preferred language.
Below we list some of the best libraries, clients and toolkits, organized by programming languages:
==== C/C++
https://github.com/bitcoin/bitcoin[Bitcoin Core] :: The reference implementation of bitcoin
https://github.com/libbitcoin/libbitcoin[libbitcoin]:: ((("libbitcoin library")))Cross-Platform C++ development toolkit, node and consensus library
https://github.com/libbitcoin/libbitcoin-explorer[bitcoin explorer]:: ((("Bitcoin Explorer")))Libbitcoin's command-line tool
https://github.com/jgarzik/picocoin[picocoin]:: ((("picocoin")))A C language lightweight client library for bitcoin by Jeff Garzik
Alternative implementations include:
==== JavaScript
https://bitcore.io/[Bitcore] :: Full node, API and library by Bitpay
https://github.com/bitcoinjs/bitcoinjs-lib[BitcoinJS] :: A pure JavaScript Bitcoin library for node.js and browsers
https://github.com/libbitcoin/libbitcoin[libbitcoin]:: ((("libbitcoin library")))Bitcoin Cross-Platform C++ Development Toolkit
https://github.com/libbitcoin/libbitcoin-explorer[bitcoin explorer]:: ((("Bitcoin Explorer")))Bitcoin Command Line Tool
https://github.com/libbitcoin/libbitcoin-server[bitcoin server]:: ((("Bitcoin Server")))Bitcoin Full Node and Query Server
==== Java
https://code.google.com/p/bitcoinj/[bitcoinj]:: ((("BitcoinJ library")))A Java full-node client library
https://opensource.conformal.com/wiki/btcd[btcd]:: ((("btcd","client")))A Go language full-node bitcoin client
https://bitsofproof.com[Bits of Proof (BOP)]:: ((("Bits of Proof (BOP)")))A Java enterprise-class implementation of bitcoin
https://github.com/jgarzik/picocoin[picocoin]:: ((("picocoin")))A C implementation of a lightweight client library for bitcoin
https://github.com/vbuterin/pybitcointools[pybitcointools]:: ((("pybitcointools library")))A Python bitcoin library
https://github.com/richardkiss/pycoin[pycoin]:: ((("pycoin library")))Another Python bitcoin library
==== Python
https://github.com/petertodd/python-bitcoinlib[python-bitcoinlib]:: ((("python-bitcoinlib library"))) A Python bitcoin library, consensus library and node by Peter Todd
https://github.com/richardkiss/pycoin[pycoin]:: ((("pycoin library")))A Python bitcoin library by Richard Kiss
https://github.com/vbuterin/pybitcointools[pybitcointools]:: ((("pybitcointools library")))A Python bitcoin library by Vitalik Buterin
==== Ruby
https://github.com/sinisterchipmunk/bitcoin-client[bitcoin-client]:: A Ruby library wrapper for the JSON-RPC API
==== Go
https://opensource.conformal.com/wiki/btcd[btcd]:: ((("btcd","client")))A Go language full-node bitcoin client
==== Rust
https://github.com/apoelstra/rust-bitcoin[rust-bitcoin]:: Rust Bitcoin Library for serialization, parsing and API calls
==== C#
https://github.com/MetacoSA/NBitcoin[NBitcoin]:: Comprehensive Bitcoin library for the .NET framework.
==== Objective-C
https://github.com/oleganza/CoreBitcoin[CoreBitcoin]:: Bitcoin toolkit for ObjC and Swift
Many more libraries exist in a variety of other programming languages and more are created all the time.

@ -0,0 +1,37 @@
from bitcoin.rpc import RawProxy
p = RawProxy()
# The block height where Alice's transaction was recorded
blockheight = 277316
# Get the block hash of block with height 277316
blockhash = p.getblockhash(blockheight)
# Retrieve the block by its hash
block = p.getblock(blockhash)
# Element tx contains the list of all transaction IDs in the block
transactions = block['tx']
block_value = 0
# Iterate through each transaction ID in the block
for txid in transactions:
tx_value = 0
# Retrieve the raw transaction by ID
raw_tx = p.getrawtransaction(txid)
# Decode the transaction
decoded_tx = p.decoderawtransaction(raw_tx)
# Iterate through each output in the transaction
for output in decoded_tx['vout']:
# Add up the value of each output
tx_value = tx_value + output['value']
# Add the value of this transaction to the total
block_value = block_value + tx_value
print("Total value in block: ", block_value)

@ -0,0 +1,10 @@
from bitcoin.rpc import RawProxy
# Create a connection to local Bitcoin Core node
p = RawProxy()
# Run the getinfo command, store the resulting data in info
info = p.getinfo()
# Retrieve the 'blocks' element from the info
print(info['blocks'])

@ -0,0 +1,16 @@
from bitcoin.rpc import RawProxy
p = RawProxy()
# Alice's transaction ID
txid = "0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2"
# First, retrieve the raw transaction in hex
raw_tx = p.getrawtransaction(txid)
# Decode the transaction hex into a JSON object
decoded_tx = p.decoderawtransaction(raw_tx)
# Retrieve each of the outputs from the transaction
for output in decoded_tx['vout']:
print(output['scriptPubKey']['addresses'], output['value'])
Loading…
Cancel
Save