Bitcoin-ruby
This is a ruby library for interacting with the bitcoin protocol/network. It can parse and generate protocol messages, run basic scripts, connect to other peers and download and store the blockchain (WITHOUT verification yet!).
Installation
We assume you already have a ruby 1.9 compatible interpreter and rubygems environment.
git clone https://github.com/lian/bitcoin-ruby.git; cd bitcoin-ruby
ruby -Ilib bin/bitcoin_connect
Note that some aspects of the library (such as networking, or storage) may need additional dependencies which are not specified in the gemspec. You'll find out what's missing once it fails when you try to use it ;)
Demos
There are a few demo scripts you can run to try things out:
bin/bitcoin_connect
Connect to a network node and chat a little.
bin/bitcoin_blockchain
Connect to a node and download the whole blockchain into storage.
bin/bbe_verify_tx
Fetch a transaction and all its prev_outs from blockexplorer.com and verify the signatures.
./bin/bbe_verify_tx <tx_hash> [testnet]
bin/bitcoin_shell
Launches an irb session with bitcoin loaded where you can try stuff out.
Library Usage
There are different aspects to the library which can be used separately or in combination. Here are some examples of what you could do.
Keys / Addresses
Generate a key:
key = Bitcoin::generate_key
key #=> [<privkey>, <pubkey>]
Get the address from a public key
address = Bitcoin::pubkey_to_address(key[1])
address #=> <bitcoin address>
Check if an address is valid
Bitcoin::valid_address?(address) #=> true
Blocks / Transactions parsing
Parse a block
raw_block = File.open('spec/bitcoin/fixtures/rawblock-0.bin', 'rb') {|f| f.read}
blk = Bitcoin::Protocol::Block.new(raw_block)
blk.hash #=> 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
blk.tx.count #=> 1
blk.to_hash #=> ...
Bitcoin::Protocol::Block.from_json( blk.to_json )
Parse a transaction
raw_tx = File.open('spec/bitcoin/fixtures/rawtx-01.bin', 'rb') {|f| f.read}
tx = Bitcoin::Protocol::Tx.new(raw_tx)
tx.hash #=> 6e9dd16625b62cfcd4bf02edb89ca1f5a8c30c4b1601507090fb28e59f2d02b4
tx.in.size #=> 1
tx.out.size #=> 2
tx.to_hash #=> ...
Bitcoin::Protocol::Tx.from_json( tx.to_json )
Bitcoin::Script.new(tx.out[0].pk_script).to_string
#=> "OP_DUP OP_HASH160 b2e21c1db922e3bdc529de7b38b4c401399e9afd OP_EQUALVERIFY OP_CHECKSIG"
Transaction verification / Scripts
Get the matching transactions (in this example tx1 is the spending transaction)
rawtx1 = File.open("spec/bitcoin/fixtures/rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin", 'rb') {|f| f.read}
rawtx2 = File.open("spec/bitcoin/fixtures/rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin", 'rb') {|f| f.read}
tx1 = Bitcoin::Protocol::Tx.new(rawtx1)
tx2 = Bitcoin::Protocol::Tx.new(rawtx2)
Then simply ask the transaction to verify an input
tx1.verify_input_signature(0, tx2) #=> true
Or, if you want to control the script yourself
txin = tx1.in.first
txout = tx2.out[txin.prev_out_index]
script = Bitcoin::Script.new(txin.script_sig + txout.pk_script)
result = script.run do |pubkey, sig, hash_type|
hash = tx1.signature_hash_for_input(0, nil, txout.pk_script)
Bitcoin.verify_signature(hash, sig, pubkey.unpack("H*")[0])
end
result #=> true
Node / Network connections
The networking part is still work in progress. For now, you'll probably want to roll your own; see connection.rb or network/node.rb for examples.
Storage / Database backends
There are multiple database backends available, currently an in-memory dummy and and activerecord/postgres backend.
store = Bitcoin::Storage::Backends::Dummy.new
store.store_block(Bitcoin.network[:genesis_block])
store.get_block(Bitcoin.network[:genesis_hash])
store.get_head #=> Bitcoin.network[:genesis_hash]
Documentation
Still needs some love, but you can generate RDoc documentation
rake rdoc
The specs are also a good place to see how something works.
Specs
The specs can be run with
rake bacon
or, if you want to run a single spec
ruby spec/bitcoin/bitcoin_spec.rb
If you make changes to the code or add functionality, please also add specs.