Download zip Select Archive Format
Name Last Update history
File dir bin Loading commit data...
File dir concept-examples Loading commit data...
File dir lib Loading commit data...
File dir spec Loading commit data...
File txt .gitignore Loading commit data...
File txt COPYING Loading commit data...
File txt Gemfile Loading commit data...
File txt README Loading commit data...
File txt Rakefile Loading commit data...
File txt bitcoin-ruby.gemspec Loading commit data...

README

= 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 in bin/ you can run to try things out:

=== bitcoin_connect

Connect to a network node and chat a little.

=== bitcoin_blockchain

Connect to a node and download the whole blockchain into storage.

 bitcoin_blockchain # connects to testnet using dummy store
 bitcoin_blockchain -n bitcoin -s sequel::postgres///bitcoin
 bitcoin_blockchain -h

=== bitcoin_verify_tx

Fetch a transaction and all its prev_outs from local storage
and verify the signatures.

 bitcoin_verify_tx [options] <tx_hash>
 bitcoin_verify_tx -s sequel::postgres:/bitcoin 0f6741210a02e196ca5f5ad17f684968623546c1accdbcb701a668a51a7ba9fd

Note: For this to work, you obviously need to have the transactions in your storage.

=== bbe_verify_tx

In case you don't have a local storage, this script fetches a transaction and
all its prev_outs from blockexplorer.com and verifies the signatures.

 bbe_verify_tx <tx_hash> [testnet]

=== bitcoin_balance

Collect transactions and display balance for an address.

 bitcoin_balance -s sequel::postgres:/bitcoin -l moz14kFmgHPszRvS6rvhfEVYmx4RbcNMfH

=== bitcoin_wallet

To use the wallet you should create a configfile. It's not required but more convenient.
See the +Config+ +Files+ section for details.

 all:
   network: bitcoin
   storage: "sequel::postgres:/bitcoin"
   command: "127.0.01:9999"
 wallet:
   keystore: "simple::file=keys.json"
   # keystore: "deterministic::seed=foo,nonce=2116,keys=7"

The +simple+ keystore will create one key and put it into the given file.
You can later ask it to generate more keys.

The +deterministic+ keystore uses the seed (which should be a large, unique, random string!)
and generates the given number of keys. The nonce is optional, it just speeds up finding the first key.
See Bitcoin::Wallet::KeyGenerator for details.

Then you can list all addresses in the wallet:

 bitcoin_wallet list

Display transaction history for a specific address:

 bitcoin_wallet list <address>

Create new keys/addresses (only with +simple+ keystore; with +deterministic+ you have to edit your config and increase the number of keys):

 bitcoin_wallet new

Import keys from base58 format:

 bitcoin_wallet import <base58>

Export keys to base58 format:

 bitcoin_wallet export <address>

And finally send bitcoins to an address:

 bitcoin_wallet send <type>:<address>:<amount> [<fee>]
 bitcoin_wallet send address:1GQkkFvAFW2ts3YLnEvMnu76WyCB6yDb4d:0.1 0.005

This will create a transaction and display it, asking for confirmation.
If you accept, it will be sent to your node and relayed to the rest of the network.

There's also experimental multisig support, but you need to have all keys in your wallet for now:

 bitcoin_wallet send <type>:<m>:<key>:<key>:<amount> [<fee>]
 bitcoin_wallet send multisig:1:1GQkkFvAFW2ts3YLnEvMnu76WyCB6yDb4d:1C5uWeXorS46ZubciCLN4zyR7sAqeNJfLD:1.0 0.005

=== bitcoin_shell

Launches an irb session with bitcoin loaded where you can try stuff out.

=== Storage Backends

For examples that require storage backends, you can specify them using
a string containing the backend name and a configuration string.
The default backend is always +dummy+ which needs no configuration

 dummy
 sequel::sqlite:///tmp/bitcoin.db
 sequel::postgres:/bitcoin
 sequel::postgres://user:pass@host/database


=== Config Files

Some of the commands look for a config file in default locations, and provide
an option to specify a custom location. The default locations are:

* /etc/bitcoin-ruby.yml
* ~/.bitcoin-ruby.yml
* ./bitcoin-ruby.yml

Files are loaded in order (if they exist) and may override each others settings.

Inside a config file, you can put options for the various commands, separated
into categories.

 all:
   network: bitcoin
   storage: sequel::postgres:/bitcoin
   command: 127.0.0.1:1234
 blockchain:
   max:
     connect: 30
 wallet:
   keystore: "simple::file=keys.json"

Options in the +all+ category are loaded by every command, and are loaded first
(so command-specific options will override them).

Other categories are loaded by the corresponding command and may override options
from the +all+ category (ie. +bitcoin_wallet+ loads +all+ and +wallet+).


== 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.dummy  # or:
 store = Bitcoin::Storage.sequel(:db => "postgres:/bitcoin")
 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.

== Development

If you are curious or like to participate in development, drop by \#bitcoin-ruby on irc.freenode.net!