Blame view

README.rdoc 8.89 KB
d2fc81491   prudhvi   Adding travis.yml...
1
  = Bitcoin-ruby {<img src="https://api.travis-ci.org/lian/bitcoin-ruby.png?branch=master" />}[http://travis-ci.org/lian/bitcoin-ruby]
111e966ec   Marius Hanne   documentation
2
3
4
5
  
  This is a ruby library for interacting with the bitcoin protocol/network.
  
  Some of the main features are:
60b8668f8   Marius Hanne   update documentation
6
7
8
9
10
11
12
13
14
15
16
  * Bitcoin::Util provides the basic bitcoin utility functions for base58, ECC, etc.
  * Bitcoin::Protocol can parse/create (almost?) all protocol messages
  * Bitcoin::Network::Node connects to peers, fetches the blockchain and keeps it up to date
    (see NODE for usage)
  * Bitcoin::Validation validates block and transaction rules
  * Bitcoin::Storage stores the blockchain and can be queried for transaction data
  * Bitcoin::Script implementation, create/run scripts and verify signatures
  * Bitcoin::Key provides a high-level API for creating and handling keys/addresses
  * Bitcoin::Builder provides a high-level API for creating transactions (and blocks)
  * Bitcoin::Wallet is a draft implementation of a simple wallet
  * Bitcoin::Namecoin implements all the namecoin-specific differences (see NAMECOIN)
111e966ec   Marius Hanne   documentation
17

79a9321d8   Alex Oberhauser   Adding 'Compatibl...
18
19
20
21
  == Compatible with...
  
  * ruby 1.9.3
  * ruby 2.0.0
111e966ec   Marius Hanne   documentation
22
  == Installation
60b8668f8   Marius Hanne   update documentation
23
  We assume you already have a ruby 1.9 or 2.0 compatible interpreter and rubygems environment.
111e966ec   Marius Hanne   documentation
24
25
26
  
   git clone https://github.com/lian/bitcoin-ruby.git; cd bitcoin-ruby
   ruby -Ilib bin/bitcoin_node
60b8668f8   Marius Hanne   update documentation
27
  if you want to have it available system-wide, just build the gem and install it:
111e966ec   Marius Hanne   documentation
28

af17ea70c   Lee Quarella   Fixed readme to r...
29
   gem build bitcoin-ruby.gemspec && gem install bitcoin-ruby-0.0.2.gem
111e966ec   Marius Hanne   documentation
30
31
32
33
34
35
36
37
38
39
40
  
  now you can just call +bitcoin_node+ from anywhere.
  
  
  Note that some aspects of the library (such as networking, storage, etc.) need
  additional dependencies which are not specified in the gemspec. The core requirements are
  intentionally kept to a minimum, so nobody has to install unneeded dependencies.
  
  * +eventmachine+ to run a node / connect to peers
  * +sequel+, +sqlite3+/+pg+/+mysql+ to use a storage backend
  * +em-dns+ or +nslookup+ to get peer addrs from DNS seeds
a33a17ae8   Marius Hanne   update gui depend...
41
  * +gir_ffi+ for the gui
111e966ec   Marius Hanne   documentation
42
  * +bacon+ to run the specs
62a3afc71   TM Lee   Add README for Bu...
43
  If you would like to install using Bundler, put it in your Gemfile and run bundle install
4c28b49a4   Julian Langschaedel   use git for bundl...
44
   gem 'bitcoin-ruby', git: 'https://github.com/lian/bitcoin-ruby', branch: 'master', require: 'bitcoin'
62a3afc71   TM Lee   Add README for Bu...
45

111e966ec   Marius Hanne   documentation
46
  == Client
60b8668f8   Marius Hanne   update documentation
47
48
  There is a node which connects to the network and downloads
  the blockchain into a database. see NODE, Bitcoin::Network::Node.
111e966ec   Marius Hanne   documentation
49

60b8668f8   Marius Hanne   update documentation
50
  It also opens an extra socket where local clients can query statistics,
6d108c692   Marius Hanne   typo
51
  monitor blockchain data, and relay their own transactions to the network.
60b8668f8   Marius Hanne   update documentation
52
  see NODE, Bitcoin::Network::CommandHandler, Bitcoin::Network::CommandClient.
111e966ec   Marius Hanne   documentation
53
54
  
  There is a WALLET implementation to manage a set of keys, list balances and create
60b8668f8   Marius Hanne   update documentation
55
  transactions. see WALLET, Bitcoin::Wallet.
111e966ec   Marius Hanne   documentation
56
57
58
59
60
  
  
  == Library Usage
  
  There are different aspects to the library which can be used separately or in combination.
60b8668f8   Marius Hanne   update documentation
61
  Here are some ideas of what you could do. There are also some demo scripts in examples/,
111e966ec   Marius Hanne   documentation
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  see EXAMPLES.
  
  
  === Keys/Addresses
  
  Generate a Bitcoin::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 Bitcoin::Protocol::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 )
79a9321d8   Alex Oberhauser   Adding 'Compatibl...
92

111e966ec   Marius Hanne   documentation
93
94
95
96
97
98
99
100
101
  Parse a Bitcoin::Protocol::Tx
  
   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 )
79a9321d8   Alex Oberhauser   Adding 'Compatibl...
102

111e966ec   Marius Hanne   documentation
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
   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
  
  === Scripts
  
  If you want to control the Bitcoin::Script yourself, you can do so
  
   txin = tx1.in.first
   txout = tx2.out[txin.prev_out_index]
   script = Bitcoin::Script.new(txin.script_sig + txout.pk_script)
79a9321d8   Alex Oberhauser   Adding 'Compatibl...
126

111e966ec   Marius Hanne   documentation
127
128
129
130
131
132
133
   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
  
  === Create Transactions
60b8668f8   Marius Hanne   update documentation
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  You need to know the previous output you want to spend (tx hash and output index),
  as well as the private key for the address required to sign for it.
  
   # use testnet so you don't acidentially your whole money!
   Bitcoin.network = :testnet3
   
   # make the DSL methods available in your scope
   include Bitcoin::Builder
   
   # the previous transaction that has an output to your address
   prev_hash = "6c44b284c20fa22bd69c57a9dbff91fb71deddc8c54fb2f5aa41fc78c96c1ad1"
   
   # the number of the output you want to use
   prev_out_index = 0
   
   # fetch the tx from whereever you like and parse it
   prev_tx = Bitcoin::P::Tx.from_json(open("http://test.webbtc.com/tx/#{prev_hash}.json"))
   
   # the key needed to sign an input that spends the previous output
   key = Bitcoin::Key.from_base58("92ZRu28m2GHSKaaF2W7RswJ2iJYpTzVhBaN6ZLs7TENCs4b7ML8")
   
   # create a new transaction (and sign the inputs)
   new_tx = build_tx do |t|
   
     # add the input you picked out earlier
     t.input do |i|
       i.prev_out prev_tx
       i.prev_out_index prev_out_index
       i.signature_key key
     end
   
     # add an output that sends some bitcoins to another address
     t.output do |o|
       o.value 50000000 # 0.5 BTC in satoshis
       o.script {|s| s.recipient "mugwYJ1sKyr8EDDgXtoh8sdDQuNWKYNf88" }
     end
   
     # add another output spending the remaining amount back to yourself
     # if you want to pay a tx fee, reduce the value of this output accordingly
     # if you want to keep your financial history private, use a different address
     t.output do |o|
       o.value 49000000 # 0.49 BTC, leave 0.01 BTC as fee
       o.script {|s| s.recipient key.addr }
     end
   
   end
   
   # examine your transaction. you can relay it through http://webbtc.com/relay_tx
   # that will also give you a hint on the error if something goes wrong
   puts new_tx.to_json
111e966ec   Marius Hanne   documentation
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  
  === Node / Network connections
  
  The Bitcoin::Network::Node can connect to peers and download the blockchain into a
  Bitcoin::Storage backend. For now it works completely self-contained:
  
   node = Bitcoin::Network::Node.new(options) # options = {:network => :bitcoin, ...}
   node.run
  
  In the future you will be able to register callbacks to the node and control many aspects
  of its operation yourself. Also see NODE.
  
  If you want to implement your own node, see lib/bitcoin/connection.rb or
  lib/bitcoin/network/node.rb for examples.
  
  
  === Storage / Database backends
f6fe241d8   Marius Hanne   remove dns seed f...
201
202
203
  There is support for different storage backends. Each backend can be used with
  sqlite, postgres or mysql. All backends implement the interface defined in
  Bitcoin::Storage::Backends::StoreBase and return Bitcoin::Storage::Models.
111e966ec   Marius Hanne   documentation
204
205
206
207
208
209
210
  
   store = Bitcoin::Storage.sequel(:db => "sqlite://bitcoin.db") # in-memory db
   store.get_head #=> block
   txouts = store.get_txouts_for_address("15yN7NPEpu82sHhB6TzCW5z5aXoamiKeGy")
   txouts.first.value #=> 5000000000
   txouts.first.type #=> :pubkey
   txouts.first.get_address #=> "15yN7NPEpu82sHhB6TzCW5z5aXoamiKeGy"
f6fe241d8   Marius Hanne   remove dns seed f...
211
  See also STORAGE, Bitcoin::Storage::Backends::UtxoStore, Bitcoin::Storage::Backends::SequelStore and Bitcoin::Storage::Backends::DummyStore for details.
111e966ec   Marius Hanne   documentation
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  
  == Documentation
  
  Always trying to improve, any help appreciated! If anything is unclear to you, let us know!
  
  Documentation is generated using RDoc
  
   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
e53fd44c0   Marius Hanne   change txin.prev_...
232
233
234
235
  To test the postgres/mysql storage backend, create a database and set it as an environment variable:
  
   echo "create database bitcoin_test" | psql
   TEST_DB_POSTGRES="postgres:/bitcoin_test" rake bacon
111e966ec   Marius Hanne   documentation
236
237
238
  If you make changes to the code or add functionality, please also add specs.
  
  == Development
60b8668f8   Marius Hanne   update documentation
239
240
241
  Any help or feedback is greatly appreciated! From getting knee-deep into elliptic-curve acrobatics,
  to cleaning up high-level naming conventions, there is something for everyone to do.
  Even if you are completely lost, just pointing out what is unclear helps a lot!
111e966ec   Marius Hanne   documentation
242
  If you are curious or like to participate in development, drop by \#bitcoin-ruby on irc.freenode.net!
79a9321d8   Alex Oberhauser   Adding 'Compatibl...
243