btcruby 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +18 -0
- data/.travis.yml +7 -0
- data/FAQ.md +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +18 -0
- data/HOWTO.md +17 -0
- data/LICENSE +19 -0
- data/README.md +59 -0
- data/Rakefile +6 -0
- data/TODO.txt +40 -0
- data/bin/console +19 -0
- data/btcruby.gemspec +20 -0
- data/documentation/address.md +73 -0
- data/documentation/base58.md +52 -0
- data/documentation/block.md +127 -0
- data/documentation/block_header.md +120 -0
- data/documentation/constants.md +88 -0
- data/documentation/data.md +54 -0
- data/documentation/diagnostics.md +90 -0
- data/documentation/extensions.md +76 -0
- data/documentation/hash_functions.md +58 -0
- data/documentation/hash_id.md +22 -0
- data/documentation/index.md +230 -0
- data/documentation/key.md +177 -0
- data/documentation/keychain.md +180 -0
- data/documentation/network.md +75 -0
- data/documentation/opcode.md +220 -0
- data/documentation/openssl.md +7 -0
- data/documentation/p2pkh.md +71 -0
- data/documentation/p2sh.md +64 -0
- data/documentation/proof_of_work.md +84 -0
- data/documentation/script.md +280 -0
- data/documentation/signature.md +71 -0
- data/documentation/transaction.md +213 -0
- data/documentation/transaction_builder.md +188 -0
- data/documentation/transaction_input.md +133 -0
- data/documentation/transaction_output.md +130 -0
- data/documentation/wif.md +72 -0
- data/documentation/wire_format.md +70 -0
- data/lib/btcruby/address.rb +296 -0
- data/lib/btcruby/base58.rb +108 -0
- data/lib/btcruby/big_number.rb +47 -0
- data/lib/btcruby/block.rb +170 -0
- data/lib/btcruby/block_header.rb +231 -0
- data/lib/btcruby/constants.rb +59 -0
- data/lib/btcruby/currency_formatter.rb +64 -0
- data/lib/btcruby/data.rb +98 -0
- data/lib/btcruby/diagnostics.rb +92 -0
- data/lib/btcruby/errors.rb +8 -0
- data/lib/btcruby/extensions.rb +65 -0
- data/lib/btcruby/hash_functions.rb +54 -0
- data/lib/btcruby/hash_id.rb +18 -0
- data/lib/btcruby/key.rb +517 -0
- data/lib/btcruby/keychain.rb +464 -0
- data/lib/btcruby/network.rb +73 -0
- data/lib/btcruby/opcode.rb +197 -0
- data/lib/btcruby/open_assets/asset.rb +35 -0
- data/lib/btcruby/open_assets/asset_address.rb +49 -0
- data/lib/btcruby/open_assets/asset_definition.rb +75 -0
- data/lib/btcruby/open_assets/asset_id.rb +24 -0
- data/lib/btcruby/open_assets/asset_marker.rb +94 -0
- data/lib/btcruby/open_assets/asset_processor.rb +377 -0
- data/lib/btcruby/open_assets/asset_transaction.rb +184 -0
- data/lib/btcruby/open_assets/asset_transaction_builder/errors.rb +15 -0
- data/lib/btcruby/open_assets/asset_transaction_builder/provider.rb +32 -0
- data/lib/btcruby/open_assets/asset_transaction_builder/result.rb +47 -0
- data/lib/btcruby/open_assets/asset_transaction_builder.rb +418 -0
- data/lib/btcruby/open_assets/asset_transaction_input.rb +64 -0
- data/lib/btcruby/open_assets/asset_transaction_output.rb +140 -0
- data/lib/btcruby/open_assets.rb +26 -0
- data/lib/btcruby/openssl.rb +536 -0
- data/lib/btcruby/proof_of_work.rb +110 -0
- data/lib/btcruby/safety.rb +26 -0
- data/lib/btcruby/script.rb +733 -0
- data/lib/btcruby/signature_hashtype.rb +37 -0
- data/lib/btcruby/transaction.rb +511 -0
- data/lib/btcruby/transaction_builder/errors.rb +15 -0
- data/lib/btcruby/transaction_builder/provider.rb +54 -0
- data/lib/btcruby/transaction_builder/result.rb +73 -0
- data/lib/btcruby/transaction_builder/signer.rb +28 -0
- data/lib/btcruby/transaction_builder.rb +520 -0
- data/lib/btcruby/transaction_input.rb +298 -0
- data/lib/btcruby/transaction_outpoint.rb +30 -0
- data/lib/btcruby/transaction_output.rb +315 -0
- data/lib/btcruby/version.rb +3 -0
- data/lib/btcruby/wif.rb +118 -0
- data/lib/btcruby/wire_format.rb +362 -0
- data/lib/btcruby.rb +44 -2
- data/sample_code/creating_a_p2sh_multisig_address.rb +21 -0
- data/sample_code/creating_a_transaction_manually.rb +44 -0
- data/sample_code/generating_an_address.rb +20 -0
- data/sample_code/using_transaction_builder.rb +49 -0
- data/spec/address_spec.rb +206 -0
- data/spec/all.rb +6 -0
- data/spec/base58_spec.rb +83 -0
- data/spec/block_header_spec.rb +18 -0
- data/spec/block_spec.rb +18 -0
- data/spec/currency_formatter_spec.rb +46 -0
- data/spec/data_spec.rb +50 -0
- data/spec/diagnostics_spec.rb +41 -0
- data/spec/key_spec.rb +205 -0
- data/spec/keychain_spec.rb +261 -0
- data/spec/network_spec.rb +48 -0
- data/spec/open_assets/asset_address_spec.rb +33 -0
- data/spec/open_assets/asset_id_spec.rb +15 -0
- data/spec/open_assets/asset_marker_spec.rb +47 -0
- data/spec/open_assets/asset_processor_spec.rb +567 -0
- data/spec/open_assets/asset_transaction_builder_spec.rb +273 -0
- data/spec/open_assets/asset_transaction_spec.rb +70 -0
- data/spec/proof_of_work_spec.rb +53 -0
- data/spec/script_spec.rb +66 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/transaction_builder_spec.rb +338 -0
- data/spec/transaction_spec.rb +162 -0
- data/spec/wire_format_spec.rb +283 -0
- metadata +141 -7
@@ -0,0 +1,88 @@
|
|
1
|
+
[Index](index.md)
|
2
|
+
|
3
|
+
BTC Constants
|
4
|
+
=============
|
5
|
+
|
6
|
+
These are defined in **constants.rb**.
|
7
|
+
|
8
|
+
Units
|
9
|
+
-----
|
10
|
+
|
11
|
+
#### SATOSHI = 1
|
12
|
+
|
13
|
+
Satoshi is the smallest unit representable in Bitcoin [transactions](transaction.md).
|
14
|
+
|
15
|
+
#### COIN = 100\_000\_000
|
16
|
+
|
17
|
+
One bitcoin equals 100 million satoshis.
|
18
|
+
|
19
|
+
#### BIT = 100
|
20
|
+
|
21
|
+
1 bit is 100 satoshis (1 millionth of a bitcoin).
|
22
|
+
|
23
|
+
|
24
|
+
Network Rules
|
25
|
+
-------------
|
26
|
+
|
27
|
+
Changing these will result in incompatibility with other nodes.
|
28
|
+
|
29
|
+
#### MAX\_BLOCK\_SIZE = 1\_000\_000
|
30
|
+
|
31
|
+
The maximum allowed size for a serialized [block](block.md), in bytes.
|
32
|
+
|
33
|
+
#### MAX\_BLOCK\_SIGOPS = MAX\_BLOCK\_SIZE/50
|
34
|
+
|
35
|
+
The maximum allowed number of signature check operations in a [block](block.md).
|
36
|
+
|
37
|
+
#### MAX\_MONEY = 21\_000\_000 * COIN
|
38
|
+
|
39
|
+
No amount larger than this (in satoshis) is valid.
|
40
|
+
|
41
|
+
#### COINBASE\_MATURITY = 100
|
42
|
+
|
43
|
+
Coinbase transaction outputs can only be spent after this number of new blocks.
|
44
|
+
|
45
|
+
#### LOCKTIME\_THRESHOLD = 500\_000\_000
|
46
|
+
|
47
|
+
Threshold for [BTC::Transaction#lock_time](transaction.md): below this value it is interpreted
|
48
|
+
as a [block](block.md) number, otherwise as UNIX timestamp.
|
49
|
+
|
50
|
+
#### BIP16\_TIMESTAMP = 1333238400
|
51
|
+
|
52
|
+
[P2SH](p2sh.md) BIP16 didn't become active until April 1, 2012.
|
53
|
+
All [transactions](transaction.md) before this timestamp should not be verified with P2SH rule.
|
54
|
+
|
55
|
+
#### MAX\_SCRIPT\_SIZE = 10000
|
56
|
+
|
57
|
+
Scripts longer than 10K bytes are invalid.
|
58
|
+
|
59
|
+
#### MAX\_SCRIPT\_ELEMENT\_SIZE = 520
|
60
|
+
|
61
|
+
Maximum number of bytes per "pushdata" [opcode](opcode.md).
|
62
|
+
|
63
|
+
#### MAX\_KEYS\_FOR\_CHECKMULTISIG = 20
|
64
|
+
|
65
|
+
Number of [public keys](key.md) allowed for [OP_CHECKMULTISIG](opcode.md).
|
66
|
+
|
67
|
+
#### MAX\_OPS\_PER\_SCRIPT = 201
|
68
|
+
|
69
|
+
Maximum number of [operations](opcode.md) allowed per [script](script.md) (excluding pushdata operations and OP_*N*).
|
70
|
+
Multisig operation additionally increases count by a number of pubkeys.
|
71
|
+
|
72
|
+
|
73
|
+
Soft Rules
|
74
|
+
----------
|
75
|
+
|
76
|
+
Can bend these without becoming incompatible with everyone.
|
77
|
+
|
78
|
+
#### MAX\_INV\_SZ = 50000
|
79
|
+
|
80
|
+
The maximum number of entries in an 'inv' protocol message.
|
81
|
+
|
82
|
+
#### MAX\_BLOCK\_SIZE\_GEN = MAX\_BLOCK\_SIZE / 2
|
83
|
+
|
84
|
+
The maximum size for mined blocks.
|
85
|
+
|
86
|
+
#### MAX\_STANDARD\_TX\_SIZE = MAX\_BLOCK\_SIZE\_GEN / 5
|
87
|
+
|
88
|
+
The maximum size for transactions we're willing to relay/mine.
|
@@ -0,0 +1,54 @@
|
|
1
|
+
[Index](index.md)
|
2
|
+
|
3
|
+
BTC::Data
|
4
|
+
=========
|
5
|
+
|
6
|
+
`BTC::Data` module implements common routines dealing with binary strings.
|
7
|
+
All functions are also available as methods of `BTC::Data` object.
|
8
|
+
|
9
|
+
Module Functions
|
10
|
+
----------------
|
11
|
+
|
12
|
+
#### random_data(length = 32)
|
13
|
+
|
14
|
+
Returns a cryptographically secure random binary string of a given length. Default length is 32 bytes.
|
15
|
+
|
16
|
+
#### data\_from\_hex(string)
|
17
|
+
|
18
|
+
Returns a binary string decoded from a hex-encoded string.
|
19
|
+
|
20
|
+
Raises `FormatError` if argument is not a valid hex string.
|
21
|
+
|
22
|
+
#### hex\_from\_data(string)
|
23
|
+
|
24
|
+
Returns a hex-encoded string.
|
25
|
+
|
26
|
+
#### bytes\_from\_data(string)
|
27
|
+
#### bytes\_from\_data(string, offset: 0, limit: nil)
|
28
|
+
#### bytes\_from\_data(string, range: nil)
|
29
|
+
|
30
|
+
Returns an array of bytes from a given string.
|
31
|
+
|
32
|
+
If `offset` is specified, returns bytes starting with a given offset.
|
33
|
+
|
34
|
+
If `limit` is specified, limits number of bytes accordingly.
|
35
|
+
|
36
|
+
If `range` is specified, returns an array of bytes within the specified range.
|
37
|
+
|
38
|
+
#### data\_from\_bytes(bytes)
|
39
|
+
|
40
|
+
Returns a binary string made from the given array of bytes (integers).
|
41
|
+
|
42
|
+
#### ensure\_ascii\_compatible\_encoding(string, options = nil)
|
43
|
+
|
44
|
+
Returns `string` as-is if it is ASCII-compatible (that is, if you are interested in 7-bit characters exposed as `#bytes`).
|
45
|
+
If it is not, attempts to transcode to UTF8 replacing invalid characters if there are any.
|
46
|
+
|
47
|
+
If `options` are not specified, uses safe defaults: replaces unknown characters with a standard character.
|
48
|
+
|
49
|
+
If `options` are specified, they are used as-is for `String#encode` method.
|
50
|
+
|
51
|
+
#### ensure\_binary\_encoding(string)
|
52
|
+
|
53
|
+
Returns string as-is if it is already encoded in binary encoding (aka BINARY or ASCII-8BIT).
|
54
|
+
If it is not, converts to binary by calling standard method `#b`.
|
@@ -0,0 +1,90 @@
|
|
1
|
+
[Index](index.md)
|
2
|
+
|
3
|
+
BTC::Diagnostics
|
4
|
+
================
|
5
|
+
|
6
|
+
Diagnostics provides extensive details of inner workings of various algorithms.
|
7
|
+
For instance, when script is parsed and detects non-canonical encoding of certain elements,
|
8
|
+
it is not an error condition, but an unusual case that can be important for debugging.
|
9
|
+
|
10
|
+
You can wrap any piece of code in `Diagnostics.current.record { ... }` to collect all diagnostic messages
|
11
|
+
or use `Diagnostics.current.trace { ... }` to output all the messages to STDERR.
|
12
|
+
|
13
|
+
Class Method
|
14
|
+
------------
|
15
|
+
|
16
|
+
#### current
|
17
|
+
|
18
|
+
An instance of `BTC::Diagnostics` unique to the current thread.
|
19
|
+
|
20
|
+
|
21
|
+
Instance Methods
|
22
|
+
----------------
|
23
|
+
|
24
|
+
#### last_message
|
25
|
+
|
26
|
+
Returns the latest recorded message. See `add_message`.
|
27
|
+
|
28
|
+
#### last_info
|
29
|
+
|
30
|
+
Returns the latest recorded info object associated with the latest message. See `add_message`.
|
31
|
+
|
32
|
+
#### last_item
|
33
|
+
|
34
|
+
Returns the `Diagnostics::Item` object that contains latest message and info.
|
35
|
+
|
36
|
+
#### add_message(*message*, info: nil)
|
37
|
+
|
38
|
+
Records a `message` (String) with an optional `info` object.
|
39
|
+
|
40
|
+
When executed within a `trace {...}` block, `message` is written to STDERR or another stream specified in `trace`.
|
41
|
+
|
42
|
+
When executed within a `record {...}` block, an `Item` containing both `message` and `info` is added to an array returned from `record`.
|
43
|
+
|
44
|
+
#### record { ... }
|
45
|
+
|
46
|
+
Returns an array of all `Item` instances recorded by `add_message` within the block.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
Diagnostics.current.record do
|
50
|
+
Diagnostics.current.add_message("Hello")
|
51
|
+
Diagnostics.current.add_message("world")
|
52
|
+
end.map(&:to_s)
|
53
|
+
```
|
54
|
+
|
55
|
+
```
|
56
|
+
["Hello", "world"]
|
57
|
+
```
|
58
|
+
|
59
|
+
#### trace(*stream* = $stderr) { ... }
|
60
|
+
|
61
|
+
Writes every recorded message to a given stream. Default stream is `$stderr`.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
Diagnostics.current.trace do
|
65
|
+
Diagnostics.current.add_message("Hello")
|
66
|
+
Diagnostics.current.add_message("world")
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
```
|
71
|
+
Hello
|
72
|
+
world
|
73
|
+
```
|
74
|
+
|
75
|
+
Diagnostics::Item
|
76
|
+
-----------------
|
77
|
+
|
78
|
+
Item class represents a pair of `message` (String) and an arbitrary `info` object.
|
79
|
+
|
80
|
+
#### message
|
81
|
+
|
82
|
+
Message string.
|
83
|
+
|
84
|
+
#### info
|
85
|
+
|
86
|
+
Additional object of arbitrary type. Default value is `nil`.
|
87
|
+
|
88
|
+
#### to_s
|
89
|
+
|
90
|
+
Returns `message`.
|
@@ -0,0 +1,76 @@
|
|
1
|
+
[Index](index.md)
|
2
|
+
|
3
|
+
Core Extensions
|
4
|
+
===============
|
5
|
+
|
6
|
+
Core Extensions are convenience methods available on standard classes like `String`.
|
7
|
+
We do not extend core classes by default to avoid conflicts with other libraries and your own extensions.
|
8
|
+
To enable convenience methods, include `btcruby/extensions.rb` in your application.
|
9
|
+
|
10
|
+
Extensions are automatically available in BTCRuby interactive console `bin/console` and in unit tests.
|
11
|
+
|
12
|
+
String Extensions
|
13
|
+
-----------------
|
14
|
+
|
15
|
+
#### to\_wif(network: *BTC::Network*, public\_key\_compressed: *false|true*)
|
16
|
+
|
17
|
+
Converts a binary string representing a 32-byte private key to [WIF](wif.md) format.
|
18
|
+
|
19
|
+
If `network` is not specified, [BTC::Network.default](network.md#default) is used.
|
20
|
+
|
21
|
+
If `public_key_compressed` is not specified, `false` is used.
|
22
|
+
|
23
|
+
|
24
|
+
#### from_wif
|
25
|
+
|
26
|
+
Converts [WIF-encoded](wif.md) string to a raw 32-byte [private key](key.md#private_key).
|
27
|
+
Raises `FormatError` if the receiver is not a valid WIF-encoded string.
|
28
|
+
|
29
|
+
#### to_hex
|
30
|
+
|
31
|
+
Converts a binary string to a hex-encoded string.
|
32
|
+
|
33
|
+
#### from_hex
|
34
|
+
|
35
|
+
Converts a hex-encoded string to a binary string.
|
36
|
+
Raises `FormatError` if the receiver is not a valid hex-encoded string.
|
37
|
+
|
38
|
+
#### sha1
|
39
|
+
|
40
|
+
Returns a binary string compressed using [SHA-1](http://en.wikipedia.org/wiki/SHA-1) algorithm.
|
41
|
+
|
42
|
+
#### sha256
|
43
|
+
|
44
|
+
Returns a binary string compressed using [SHA-256](http://en.wikipedia.org/wiki/SHA-2) algorithm.
|
45
|
+
|
46
|
+
#### sha512
|
47
|
+
|
48
|
+
Returns a binary string compressed using [SHA-512](http://en.wikipedia.org/wiki/SHA-2) algorithm.
|
49
|
+
|
50
|
+
#### ripemd160
|
51
|
+
|
52
|
+
Returns a binary string compressed using [RIPEMD-160](http://en.wikipedia.org/wiki/RIPEMD) algorithm.
|
53
|
+
|
54
|
+
#### hash256
|
55
|
+
|
56
|
+
Returns a binary string compressed using two passes of [SHA-256](http://en.wikipedia.org/wiki/SHA-256) algorithm. Known in Bitcoin as *Hash256*.
|
57
|
+
|
58
|
+
#### hash160
|
59
|
+
|
60
|
+
Returns a binary string compressed using composition `ripemd160(sha256(string))`. Known in Bitcoin as *Hash160*.
|
61
|
+
|
62
|
+
#### hmac_sha256(key: *String*)
|
63
|
+
|
64
|
+
Returns a result of [HMAC](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using [SHA-256](http://en.wikipedia.org/wiki/SHA-2) hash using `self` as data.
|
65
|
+
|
66
|
+
#### hmac_sha256(data: *String*)
|
67
|
+
|
68
|
+
Returns a result of [HMAC](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using [SHA-256](http://en.wikipedia.org/wiki/SHA-2) hash using `self` as key.
|
69
|
+
|
70
|
+
#### hmac_sha512(key: *String*)
|
71
|
+
|
72
|
+
Returns a result of [HMAC](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using [SHA-512](http://en.wikipedia.org/wiki/SHA-2) hash using `self` as data.
|
73
|
+
|
74
|
+
#### hmac_sha512(data: *String*, key: *String*)
|
75
|
+
|
76
|
+
Returns a result of [HMAC](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using [SHA-512](http://en.wikipedia.org/wiki/SHA-2) hash using `self` as key.
|
@@ -0,0 +1,58 @@
|
|
1
|
+
[Index](index.md)
|
2
|
+
|
3
|
+
BTC::HashFunctions
|
4
|
+
==================
|
5
|
+
|
6
|
+
Bitcoin uses various hash functions, all of which are available in the module `BTC::HashFunctions`.
|
7
|
+
All functions take binary string arguments and return binary strings.
|
8
|
+
Use [hex conversion methods](data.md) to convert string to/from hex encoding if needed.
|
9
|
+
|
10
|
+
You typically access these via `BTC` object:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
>> BTC.sha256("correct horse battery staple")
|
14
|
+
=> "\xc4\xbb\xcb\x1f..."
|
15
|
+
```
|
16
|
+
|
17
|
+
If you include [Core Extensions](extensions.md), you can use these and some other functions directly on the String:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
>> "correct horse battery staple".sha256.to_hex
|
21
|
+
=> "c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a"
|
22
|
+
```
|
23
|
+
|
24
|
+
Module Functions
|
25
|
+
----------------
|
26
|
+
|
27
|
+
#### sha1(*string*)
|
28
|
+
|
29
|
+
Returns a binary string compressed using [SHA-1](http://en.wikipedia.org/wiki/SHA-1) algorithm.
|
30
|
+
|
31
|
+
#### sha256(*string*)
|
32
|
+
|
33
|
+
Returns a binary string compressed using [SHA-256](http://en.wikipedia.org/wiki/SHA-2) algorithm.
|
34
|
+
|
35
|
+
#### sha512(*string*)
|
36
|
+
|
37
|
+
Returns a binary string compressed using [SHA-512](http://en.wikipedia.org/wiki/SHA-2) algorithm.
|
38
|
+
|
39
|
+
#### ripemd160(*string*)
|
40
|
+
|
41
|
+
Returns a binary string compressed using [RIPEMD-160](http://en.wikipedia.org/wiki/RIPEMD) algorithm.
|
42
|
+
|
43
|
+
#### hash256(*string*)
|
44
|
+
|
45
|
+
Returns a binary string compressed using two passes of [SHA-256](http://en.wikipedia.org/wiki/SHA-256) algorithm. Known in Bitcoin as *Hash256*.
|
46
|
+
|
47
|
+
#### hash160(*string*)
|
48
|
+
|
49
|
+
Returns a binary string compressed using composition `ripemd160(sha256(string))`. Known in Bitcoin as *Hash160*.
|
50
|
+
|
51
|
+
#### hmac_sha256(data: *String*, key: *String*)
|
52
|
+
|
53
|
+
Returns a result of [HMAC](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using [SHA-256](http://en.wikipedia.org/wiki/SHA-2) hash.
|
54
|
+
|
55
|
+
#### hmac_sha512(data: *String*, key: *String*)
|
56
|
+
|
57
|
+
Returns a result of [HMAC](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using [SHA-512](http://en.wikipedia.org/wiki/SHA-2) hash.
|
58
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
[Index](index.md)
|
2
|
+
|
3
|
+
Hash ↔ ID Conversion
|
4
|
+
======================
|
5
|
+
|
6
|
+
[Transactions](transaction.md) and [blocks](block.md) are identified by hashes of their binary contents.
|
7
|
+
In practice these hashes are typically presented as hex-encoded big-endian 256-bit integers which we call *IDs*.
|
8
|
+
*Transaction ID* and *Block ID* are computed by reversing the bytes of the original binary hash and then encoding it in hex.
|
9
|
+
|
10
|
+
Most of the time, each object that exposes a binary *hash* attribute, also exposes a corresponding *id* attribute.
|
11
|
+
However, if you need to manually convert a *hash* to *id* or the other way around, use the following methods on the `BTC` object.
|
12
|
+
|
13
|
+
Functions
|
14
|
+
---------
|
15
|
+
|
16
|
+
#### BTC.hash\_from\_id(*hex\_string*)
|
17
|
+
|
18
|
+
Returns a binary hash string for a given hex string.
|
19
|
+
|
20
|
+
#### BTC.id\_from\_hash(*hash*)
|
21
|
+
|
22
|
+
Returns a hex-encoded identifier for a given binary hash string.
|
@@ -0,0 +1,230 @@
|
|
1
|
+
BTCRuby Reference
|
2
|
+
=================
|
3
|
+
|
4
|
+
Find your topic in the index, or refer to one of the examples below.
|
5
|
+
|
6
|
+
Classes and Modules
|
7
|
+
-------------------
|
8
|
+
|
9
|
+
Bitcoin Data Structures | Utilities | Crypto
|
10
|
+
:----------------------------------------------|:------------------------------------|:--------------------------
|
11
|
+
[Constants](constants.md) | [Base58](base58.md) | [HashFunctions](hash_functions.md)
|
12
|
+
[Address](address.md) | [Core Extensions](extensions.md) | [Key](key.md)
|
13
|
+
↳ [PublicKeyAddress](p2pkh.md) | [Data](data.md) | [Keychain](keychain.md)
|
14
|
+
↳ [ScriptHashAddress](p2psh.md) | [Diagnostics](diagnostics.md) | [OpenSSL](openssl.md)
|
15
|
+
↳ [WIF](wif.md) | [Hash↔ID Conversions](hash_id.md) |
|
16
|
+
[Block](block.md) | [ProofOfWork](proof_of_work.md) |
|
17
|
+
[BlockHeader](block_header.md) | [WireFormat](wire_format.md) |
|
18
|
+
[Network](network.md) | |
|
19
|
+
[Opcode](opcode.md) | |
|
20
|
+
[Script](script.md) | |
|
21
|
+
[Signatures and Hash Types](signature.md) | |
|
22
|
+
[Transaction](transaction.md) | |
|
23
|
+
[TransactionInput](transaction_input.md) | |
|
24
|
+
[TransactionOutput](transaction_output.md) | |
|
25
|
+
[TransactionBuilder](transaction_builder.md) | |
|
26
|
+
|
27
|
+
Glossary
|
28
|
+
--------
|
29
|
+
|
30
|
+
**[Address](address.md)** is a compact identifier that represents a destination for a Bitcoin payment.
|
31
|
+
To parse addresses use base class [BTC::Address](address.md). To encode addresses use subclasses [BTC::PublicKeyAddress](p2pkh.md) and [BTC::ScriptHashAddress](p2sh.md).
|
32
|
+
|
33
|
+
**[Base58 encoding](base58.md)** is used to encode Bitcoin [addresses](address.md),
|
34
|
+
private keys in [WIF](wif.md) and extended keys for [BIP32 keychains](keychain.md).
|
35
|
+
|
36
|
+
**[Blocks](block.md)** and **[Block Headers](block_header.md)** form a block chain that contains [transactions](transaction.md).
|
37
|
+
|
38
|
+
**[BIP32](keychain.md)** ("HD Wallets") is a standard for deriving series of [keys](key.md) or [addresses](address.md) from a single seed.
|
39
|
+
Use [BTC::Keychain](keychain.md) class to decode extended public and private keys (“xpubs” and “xprvs”) and derive chains of keys.
|
40
|
+
|
41
|
+
**[Data](data.md)** is what we call a binary string. BTCRuby uses binary strings by default.
|
42
|
+
Use methods defined in [BTC::Data](data.md) namespace to convert strings between hex and binary and access raw bytes in a safe manner.
|
43
|
+
|
44
|
+
**[Hash functions](hash_functions.md)** used in Bitcoin are accessible via `BTC` namespace: `BTC.hash256`, `BTC.hash160`, `BTC.sha256` and so on.
|
45
|
+
|
46
|
+
**[Input](transaction_input.md)** is a part of a bitcoin [transaction](transaction.md) that
|
47
|
+
unlocks bitcoins stored in the [outputs](transaction_output.md) of the previous transactions.
|
48
|
+
Every input contains a reference to some output (transaction hash and a numeric index of the output)
|
49
|
+
and a [signature script](script.md) that typically contains [signatures](key.md) and other data
|
50
|
+
to satisfy conditions defined by the corresponding output script.
|
51
|
+
|
52
|
+
**[Keys](key.md)** allow signing transactions and verifying existing signatures.
|
53
|
+
Class [BTC::Key](key.md) encapsulates a pair of public and private keys (or only a public key)
|
54
|
+
and provides methods to sign transactions and verify signatures.
|
55
|
+
|
56
|
+
**[Keychain](keychain.md)** is a chain of [keys](key.md) generated from a single seed
|
57
|
+
(or *extended key*) by a mechanism defined in BIP32.
|
58
|
+
|
59
|
+
**[Opcode](opcode.md)** is a basic unit of a [script](script.md). It could represent a piece of binary data
|
60
|
+
(e.g. a [signature](signature.md)) or an operation on data (e.g. signature verification).
|
61
|
+
See [BTC::Opcode](opcode.md) class for a list of available opcodes and related conversion methods.
|
62
|
+
|
63
|
+
**[Output](transaction_output.md)** is a part of a bitcoin [transaction](transaction.md) that specifies
|
64
|
+
destination of the bitcoins being transferred. Every output has an amount (in satoshis) and a script (that typically corresponds to an [address](address.md)).
|
65
|
+
|
66
|
+
**[P2PKH](p2pkh.md)** (pay-to-pubkey-hash) is a classic type of [address](address.md) that
|
67
|
+
compresses a public [key](key.md) in a 20-byte hash value. P2PKH-addresses start with "1" on mainnet
|
68
|
+
and "n" or "m" on testnet. Use [BTC::PublicKeyAddress](p2pkh.md) class to encode these addresses.
|
69
|
+
|
70
|
+
**[P2SH](p2sh.md)** (pay-to-script-hash) is a type of [address](address.md) that represents an arbitrary [script](script.md) as a single 20-byte hash.
|
71
|
+
P2SH-address starts with "3" on mainnet and "2N" or "2M" on testnet. Use [BTC::ScriptHashAddress](p2sh.md) class to encode these addresses.
|
72
|
+
|
73
|
+
**[Script](script.md)** is a predicate consisting of [opcodes](opcode.md) that defines control
|
74
|
+
over bitcoins in a [transaction output](transaction_output.md) or satisfies a predicate when
|
75
|
+
unlocking (spending) bitcoins in a [transaction input](transaction_input.md).
|
76
|
+
To create and inspect scripts, use [BTC::Script](script.md) class.
|
77
|
+
|
78
|
+
**[Transaction](transaction.md)** (abbreviated "tx") is an object that represents transfer of bitcoins from one or more [inputs](transaction_input.md) to one or more [outputs](transaction_output.md). Use [BTC::Transaction](transaction.md) class to inspect transactions or create them transactions manually. To build transaction we recommend using [BTC::TransactionBuilder](transaction_builder.md), which takes care of a lot of difficulties and exposes easy to use, yet powerful enough API.
|
79
|
+
|
80
|
+
**[Transaction ID](transaction.md)** (abbreviated "txid") is a reversed hex representation of transaction hash. To convert between IDs and hashes of transactions and blocks, use `BTC.hash_from_id` and `BTC.id_from_hash` methods.
|
81
|
+
|
82
|
+
**[Transaction Builder](transaction_builder.md)** is a high-level API to build [transactions](transaction,md). It selects unspent [outputs](transaction_output.md), prepares correct [signature scripts](script.md), computes mining fees and takes care of the change.
|
83
|
+
|
84
|
+
**[WIF](wif.md)** (Wallet Import Format aka "sipa format") is used to encode a single [private key](key.md) in [Base58check](base58.md) encoding.
|
85
|
+
|
86
|
+
**[Wire Format](wire_format.md)** is a low-level binary format to encode network messages. Used to encode transactions and blocks. Higher-level objects expose `data` method that takes care of this encoding, but if you need to compose or parse some custom messages, use [BTC::WireFormat](wire_format.md) class.
|
87
|
+
|
88
|
+
|
89
|
+
Examples
|
90
|
+
--------
|
91
|
+
|
92
|
+
### 1. Generating a Bitcoin address
|
93
|
+
|
94
|
+
This example demonstrates how to generate a key and get its address.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
key = BTC::Key.random
|
98
|
+
|
99
|
+
puts key.to_wif # private key in WIF format
|
100
|
+
# => L4RqZhbn2VsVgy2wCWW8kUPpA4xEkH7WbfPtj1MdFug5MayHzLeT
|
101
|
+
|
102
|
+
puts key.address.to_s # public address
|
103
|
+
# => 1MFqAcAxNsAKj5e6yksZCCyfNukSdDGsEY
|
104
|
+
|
105
|
+
puts key.to_wif(network: BTC::Network.testnet)
|
106
|
+
# => cUnq2cbdTZZkrQWCavKG7ntsnJFeQjDCfhYMqRp8m2L5cL1yHDmc
|
107
|
+
|
108
|
+
puts key.address(network: BTC::Network.testnet).to_s
|
109
|
+
# => n1mnTfFwBtbaWC7ihKqw28BzEuM9YqxRyw
|
110
|
+
```
|
111
|
+
|
112
|
+
|
113
|
+
### 2. Making Transactions
|
114
|
+
|
115
|
+
Transaction builder helps composing arbitrary transactions using just keys or unspent outputs.
|
116
|
+
It takes care of computing a proper change amount, adding fees and signing inputs.
|
117
|
+
It is also highly customizable, so you may use it for very complex transactions.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
builder = BTC::TransactionBuilder.new
|
121
|
+
|
122
|
+
# 1. Provide a list of addresses to get unspent outputs from.
|
123
|
+
# If address is a WIF instance, it will be used to sign corresponding input
|
124
|
+
# If address is a public address (or P2SH), its input will remain unsigned.
|
125
|
+
builder.input_addresses = [ "L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy" ]
|
126
|
+
|
127
|
+
# 2. Use external API (e.g. Chain.com) to fetch unspent outputs for the input addresses.
|
128
|
+
# In this example we simply hard-code a single unspent output.
|
129
|
+
# Note: transaction ID and output index must be provided.
|
130
|
+
builder.unspent_outputs_provider_block = lambda do |addresses, outputs_amount, outputs_size, fee_rate|
|
131
|
+
txout = BTC::TransactionOutput.new(
|
132
|
+
value: 50_000,
|
133
|
+
script: BTC::PublicKeyAddress.with_string("17XBj6iFEsf8kzDMGQk5ghZipxX49VXuaV").script,
|
134
|
+
transaction_id: "115e8f72f39fad874cfab0deed11a80f24f967a84079fb56ddf53ea02e308986",
|
135
|
+
index: 0
|
136
|
+
)
|
137
|
+
[ txout ]
|
138
|
+
end
|
139
|
+
|
140
|
+
# 3. Specify payment address and amount
|
141
|
+
builder.outputs = [ BTC::TransactionOutput.new(
|
142
|
+
value: 10_000,
|
143
|
+
script: BTC::Address.parse("17XBj6iFEsf8kzDMGQk5ghZipxX49VXuaV").script) ]
|
144
|
+
|
145
|
+
# 4. Specify the change address
|
146
|
+
builder.change_address = BTC::Address.parse("1CBtcGivXmHQ8ZqdPgeMfcpQNJrqTrSAcG")
|
147
|
+
|
148
|
+
# 5. Build the transaction and broadcast it.
|
149
|
+
result = builder.build
|
150
|
+
tx = result.transaction
|
151
|
+
puts tx.to_hex
|
152
|
+
|
153
|
+
# => 01000000018689302ea03ef5dd56fb7940a867f9240fa811eddeb0fa4c87ad9ff3728f5e11
|
154
|
+
# 000000006b483045022100e280f71106a84a4a1b1a2035eae70266eb53630beab2b59cc8cf
|
155
|
+
# f40b1a5bdbb902201dcbae9bb12730fe5563dc37e3a33e064f2efa78ba0af5c0179187aece
|
156
|
+
# 180b6c0121029f50f51d63b345039a290c94bffd3180c99ed659ff6ea6b1242bca47eb93b5
|
157
|
+
# 9fffffffff0210270000000000001976a91447862fe165e6121af80d5dde1ecb478ed17056
|
158
|
+
# 5b88ac30750000000000001976a9147ab89f9fae3f8043dcee5f7b5467a0f0a6e2f7e188ac
|
159
|
+
# 00000000
|
160
|
+
```
|
161
|
+
|
162
|
+
|
163
|
+
### 3. Creating a transaction manually
|
164
|
+
|
165
|
+
To manually create a transaction, you will need to specify raw inputs,
|
166
|
+
compute the signature and compose a signature script for each input and
|
167
|
+
take care of calculating fees and change.
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
include BTC
|
171
|
+
|
172
|
+
tx = Transaction.new
|
173
|
+
|
174
|
+
# 1. Add a raw input with previous transaction ID and output index.
|
175
|
+
tx.add_input(TransactionInput.new(
|
176
|
+
previous_id: "aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31",
|
177
|
+
previous_index: 0))
|
178
|
+
|
179
|
+
# 2. Add a raw output with a script
|
180
|
+
tx.add_output(TransactionOutput.new(
|
181
|
+
value: 100_000,
|
182
|
+
script: PublicKeyAddress.with_string("1CBtcGivXmHQ8ZqdPgeMfcpQNJrqTrSAcG").script))
|
183
|
+
|
184
|
+
# 3. Get the private key from WIF
|
185
|
+
key = Key.new(wif: "L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")
|
186
|
+
|
187
|
+
# 4. Sign the input (assuming it links to an output with address 18oxCAnbuKHDjP7KzLBDj8mLjggDBjE1Q9)
|
188
|
+
hashtype = BTC::SIGHASH_ALL
|
189
|
+
sighash = tx.signature_hash(input_index: 0,
|
190
|
+
output_script: Address.parse("18oxCAnbuKHDjP7KzLBDj8mLjggDBjE1Q9").script,
|
191
|
+
hash_type: hashtype)
|
192
|
+
tx.inputs[0].signature_script = Script.new << (key.ecdsa_signature(sighash) + WireFormat.encode_uint8(hashtype)) << key.public_key
|
193
|
+
|
194
|
+
# Get transaction data and broadcast it
|
195
|
+
puts tx.data # => raw binary data
|
196
|
+
puts tx.to_hex # hex-encoded data
|
197
|
+
# => 0100000001313eb630b128102b60241ca895f1d0ffca2170d5a0990e094f2182c102ab94aa
|
198
|
+
# 000000006a473044022039148258144202301221a305adb38ce0a182ecb4055c6015cdd735
|
199
|
+
# 8372d7ad6d022008aa259c87177f0e4e887dd0947c57fd140eb8f8a826f14ef8389dbc26ef
|
200
|
+
# a7b20121029f50f51d63b345039a290c94bffd3180c99ed659ff6ea6b1242bca47eb93b59f
|
201
|
+
# ffffffff01a0860100000000001976a9147ab89f9fae3f8043dcee5f7b5467a0f0a6e2f7e1
|
202
|
+
# 88ac00000000
|
203
|
+
```
|
204
|
+
|
205
|
+
|
206
|
+
### 4. Creating a P2SH multisig address
|
207
|
+
|
208
|
+
To create a P2SH multisig address you will need a set of public keys.
|
209
|
+
In the example below we generate three random keys and compose 2-of-3 multisig script
|
210
|
+
which is then transformed into a P2SH address. To redeem from this address you will need
|
211
|
+
not only two signatures, but also the original multisig script.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
keys = [BTC::Key.random, BTC::Key.random, BTC::Key.random]
|
215
|
+
pubkeys = keys.map(&:public_key)
|
216
|
+
|
217
|
+
multisig_script = BTC::Script.multisig(public_keys: pubkeys, signatures_required: 2)
|
218
|
+
puts multisig_script.to_s # => "OP_2 02c008dc... 03cab527... 024ac920... OP_3 OP_CHECKMULTISIG"
|
219
|
+
|
220
|
+
p2sh_script = multisig_script.p2sh_script
|
221
|
+
puts p2sh_script.to_s # => "OP_HASH160 a6bdcfcac410d1c1acbf34701da382ca34a691a3 OP_EQUAL"
|
222
|
+
|
223
|
+
address = p2sh_script.standard_address
|
224
|
+
puts address.to_s # => 3GtfUjaNBqG9wjw3CCgbxLUrbjtSDg4nDf
|
225
|
+
```
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|