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,92 @@
|
|
1
|
+
module BTC
|
2
|
+
class Diagnostics
|
3
|
+
|
4
|
+
# Instance unique for this thread.
|
5
|
+
def self.current
|
6
|
+
Thread.current[:BTCRubyDiagnosticsCurrentInstance] ||= self.new
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :last_message
|
10
|
+
attr_accessor :last_info
|
11
|
+
attr_accessor :last_item
|
12
|
+
|
13
|
+
# Begins recording of series of messages and returns all recorded events.
|
14
|
+
# If there is no record block on any level, messages are not accumulated,
|
15
|
+
# but only last_message is updated.
|
16
|
+
# Returns a list of all recorded messages.
|
17
|
+
def record(&block)
|
18
|
+
recording_groups << Array.new
|
19
|
+
last_group = nil
|
20
|
+
begin
|
21
|
+
yield
|
22
|
+
ensure
|
23
|
+
last_group = recording_groups.pop
|
24
|
+
end
|
25
|
+
last_group
|
26
|
+
end
|
27
|
+
|
28
|
+
# Prints out every message to a stream.
|
29
|
+
# Default stream is $stderr.
|
30
|
+
# You can nest these calls with different streams and each of them will
|
31
|
+
# receive logged messages.
|
32
|
+
def trace(stream = $stderr, &block)
|
33
|
+
@trace_streams << stream
|
34
|
+
# Use uniq list internally so when nested we don't write the same thing twice.
|
35
|
+
@uniq_trace_streams = @trace_streams.uniq
|
36
|
+
begin
|
37
|
+
yield
|
38
|
+
ensure
|
39
|
+
@trace_streams.pop
|
40
|
+
@uniq_trace_streams = @trace_streams.uniq
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds a diagnostic message.
|
46
|
+
# Use it to record warnings and reasons for errors.
|
47
|
+
# Do not use when the input is nil - code that have produced that nil
|
48
|
+
# could have already recorded a specific message for that.
|
49
|
+
def add_message(message, info: nil)
|
50
|
+
self.last_message = message
|
51
|
+
self.last_info = info
|
52
|
+
self.last_item = Item.new(message, info)
|
53
|
+
|
54
|
+
# add to each recording group
|
55
|
+
recording_groups.each do |group|
|
56
|
+
group << Item.new(message, info)
|
57
|
+
end
|
58
|
+
|
59
|
+
@uniq_trace_streams.each do |stream|
|
60
|
+
stream.puts message
|
61
|
+
end
|
62
|
+
|
63
|
+
return self
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Array of arrays
|
69
|
+
attr_accessor :recording_groups
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
@trace_streams = []
|
73
|
+
@uniq_trace_streams = []
|
74
|
+
@recording_groups = []
|
75
|
+
end
|
76
|
+
|
77
|
+
class Item
|
78
|
+
attr_accessor :message
|
79
|
+
attr_accessor :info
|
80
|
+
|
81
|
+
def initialize(message, info)
|
82
|
+
@message = message
|
83
|
+
@info = info
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_s
|
87
|
+
message.to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module BTC
|
2
|
+
module StringExtensions
|
3
|
+
|
4
|
+
# Converts binary string as a private key to a WIF Base58 format.
|
5
|
+
def to_wif(network: nil, public_key_compressed: nil)
|
6
|
+
BTC::WIF.new(private_key: self, network: network, public_key_compressed: public_key_compressed).to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
# Decodes string in WIF format into a binary private key (32 bytes)
|
10
|
+
def from_wif
|
11
|
+
addr = BTC::WIF.new(string: self)
|
12
|
+
addr ? addr.private_key : nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Converts binary data into hex string
|
16
|
+
def to_hex
|
17
|
+
BTC::Data.hex_from_data(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Converts hex string into a binary data
|
21
|
+
def from_hex
|
22
|
+
BTC::Data.data_from_hex(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Various hash functions
|
26
|
+
def hash256
|
27
|
+
BTC.hash256(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def hash160
|
31
|
+
BTC.hash160(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
def sha1
|
35
|
+
BTC.sha1(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def ripemd160
|
39
|
+
BTC.ripemd160(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def sha256
|
43
|
+
BTC.sha256(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
def sha512
|
47
|
+
BTC.sha512(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def hmac_sha256(data: nil, key: nil)
|
51
|
+
raise ArgumentError, "Either data or key must be specified" if !data && !key
|
52
|
+
BTC.hmac_sha256(data: data || self, key: key || self)
|
53
|
+
end
|
54
|
+
|
55
|
+
def hmac_sha512(data: nil, key: nil)
|
56
|
+
raise ArgumentError, "Either data or key must be specified" if !data && !key
|
57
|
+
BTC.hmac_sha512(data: data || self, key: key || self)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ::String
|
64
|
+
include BTC::StringExtensions
|
65
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'digest/sha2'
|
3
|
+
require 'digest/rmd160'
|
4
|
+
require 'digest/hmac'
|
5
|
+
|
6
|
+
module BTC
|
7
|
+
|
8
|
+
# This allows doing `BTC.sha256(...)`
|
9
|
+
module HashFunctions; end
|
10
|
+
include HashFunctions
|
11
|
+
extend self
|
12
|
+
|
13
|
+
module HashFunctions
|
14
|
+
|
15
|
+
def sha1(data)
|
16
|
+
raise ArgumentError, "Data is missing" if !data
|
17
|
+
Digest::SHA1.digest(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def sha256(data)
|
21
|
+
raise ArgumentError, "Data is missing" if !data
|
22
|
+
Digest::SHA256.digest(data)
|
23
|
+
end
|
24
|
+
|
25
|
+
def sha512(data)
|
26
|
+
raise ArgumentError, "Data is missing" if !data
|
27
|
+
Digest::SHA512.digest(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def ripemd160(data)
|
31
|
+
raise ArgumentError, "Data is missing" if !data
|
32
|
+
Digest::RMD160.digest(data)
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash256(data)
|
36
|
+
sha256(sha256(data))
|
37
|
+
end
|
38
|
+
|
39
|
+
def hash160(data)
|
40
|
+
ripemd160(sha256(data))
|
41
|
+
end
|
42
|
+
|
43
|
+
def hmac_sha256(data: nil, key: nil)
|
44
|
+
raise ArgumentError, "Data is missing" if !data || !key
|
45
|
+
Digest::HMAC.digest(data, key, Digest::SHA256)
|
46
|
+
end
|
47
|
+
|
48
|
+
def hmac_sha512(data: nil, key: nil)
|
49
|
+
raise ArgumentError, "Data is missing" if !data || !key
|
50
|
+
Digest::HMAC.digest(data, key, Digest::SHA512)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module BTC
|
2
|
+
|
3
|
+
# Transaction ID <-> Transaction Hash conversion
|
4
|
+
# Block ID <-> Block Hash conversion
|
5
|
+
|
6
|
+
# Converts string transaction or block ID into binary hash.
|
7
|
+
def self.hash_from_id(identifier)
|
8
|
+
return nil if !identifier # so we can convert optional ID into optional hash without extra headache
|
9
|
+
BTC::Data.data_from_hex(identifier).reverse
|
10
|
+
end
|
11
|
+
|
12
|
+
# Converts binary hash to hex identifier (as a big-endian 256-bit integer).
|
13
|
+
def self.id_from_hash(hash)
|
14
|
+
return nil if !hash # so we can convert optional hash into optional ID without extra headache
|
15
|
+
BTC::Data.hex_from_data(hash.reverse)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|