Module: Bitcoin::Util
- Included in:
- Bitcoin
- Defined in:
- lib/bitcoin.rb
Instance Method Summary (collapse)
- - (Boolean) address_checksum?(address)
- - (Object) address_version
- - (Object) base58_to_int(base58_val)
- - (Object) bitcoin_elliptic_curve
- - (Object) bitcoin_hash(hex)
- - (Object) bitcoin_mrkl(a, b)
- - (Object) block_hash(prev_block, mrkl_root, time, bits, nonce, ver)
-
- (Object) checksum(hex)
checksum is a 4 bytes sha256-sha256 hexdigest.
-
- (Object) decode_compact_bits(bits)
target compact bits (int) to bignum hex.
- - (Object) decode_target(target_bits)
- - (Object) encode_base58(hex)
-
- (Object) encode_compact_bits(target)
target bignum hex to compact bits (int).
- - (Object) generate_address
- - (Object) generate_key
-
- (Object) hash160(hex)
hash160 is a 20 bytes (160bits) rmd610-sha256 hexdigest.
- - (Object) hash160_from_address(address)
- - (Object) hash160_to_address(hex)
- - (Object) hash_mrkl_tree(tx)
- - (Object) htb(h)
- - (Object) hth(h)
- - (Object) inspect_key(key)
- - (Object) int_to_base58(int_val)
- - (Object) open_key(private_key, public_key)
- - (Object) pubkey_to_address(pubkey)
- - (Object) sha256(hex)
- - (Object) sign_data(key, data)
-
- (Boolean) valid_address?(address)
TODO.
- - (Object) verify_signature(hash, signature, public_key)
Instance Method Details
- (Boolean) address_checksum?(address)
44 45 46 47 48 49 50 51 |
# File 'lib/bitcoin.rb', line 44 def address_checksum?(address) a = base58_to_int(address).to_s(16) if address_version == "00" Bitcoin.checksum( address_version + a[0...40] ) == a[-8..-1] else Bitcoin.checksum( a[0...42] ) == a[-8..-1] end end |
- (Object) address_version
28 29 30 |
# File 'lib/bitcoin.rb', line 28 def address_version Bitcoin::network[:address_version] end |
- (Object) base58_to_int(base58_val)
100 101 102 103 104 105 106 107 108 |
# File 'lib/bitcoin.rb', line 100 def base58_to_int(base58_val) alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" int_val, base = 0, alpha.size base58_val.reverse.each_char.with_index do |char,index| raise ArgumentError, 'Value not a valid Base58 String.' unless char_index = alpha.index(char) int_val += char_index*(base**index) end int_val end |
- (Object) bitcoin_elliptic_curve
142 143 144 |
# File 'lib/bitcoin.rb', line 142 def bitcoin_elliptic_curve ::OpenSSL::PKey::EC.new("secp256k1") end |
- (Object) bitcoin_hash(hex)
161 162 163 164 165 |
# File 'lib/bitcoin.rb', line 161 def bitcoin_hash(hex) Digest::SHA256.digest( Digest::SHA256.digest( [hex].pack("H*").reverse ) ).reverse.unpack("H*")[0] end |
- (Object) bitcoin_mrkl(a, b)
167 |
# File 'lib/bitcoin.rb', line 167 def bitcoin_mrkl(a, b); bitcoin_hash(b + a); end |
- (Object) block_hash(prev_block, mrkl_root, time, bits, nonce, ver)
169 170 171 172 173 |
# File 'lib/bitcoin.rb', line 169 def block_hash(prev_block, mrkl_root, time, bits, nonce, ver) h = "%08x%08x%08x%064s%064s%08x" % [nonce, bits, time, mrkl_root, prev_block, ver] bitcoin_hash(h) end |
- (Object) checksum(hex)
checksum is a 4 bytes sha256-sha256 hexdigest.
39 40 41 42 |
# File 'lib/bitcoin.rb', line 39 def checksum(hex) b = [hex].pack("H*") # unpack hex Digest::SHA256.hexdigest( Digest::SHA256.digest(b) )[0...8] end |
- (Object) decode_compact_bits(bits)
target compact bits (int) to bignum hex
111 112 113 114 115 116 117 |
# File 'lib/bitcoin.rb', line 111 def decode_compact_bits(bits) bytes = Array.new(size=((bits >> 24) & 255), 0) bytes[0] = (bits >> 16) & 255 if size >= 1 bytes[1] = (bits >> 8) & 255 if size >= 2 bytes[2] = (bits ) & 255 if size >= 3 bytes.map{|i| "%02x" % [i] }.join.rjust(64, '0') end |
- (Object) decode_target(target_bits)
133 134 135 136 137 138 139 140 |
# File 'lib/bitcoin.rb', line 133 def decode_target(target_bits) case target_bits when Fixnum [ decode_compact_bits(target_bits).to_i(16), target_bits ] when String [ target_bits.to_i(16), encode_compact_bits(target_bits) ] end end |
- (Object) encode_base58(hex)
85 86 87 |
# File 'lib/bitcoin.rb', line 85 def encode_base58(hex) int_to_base58( hex[0...64].to_i(16) ) end |
- (Object) encode_compact_bits(target)
target bignum hex to compact bits (int)
120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/bitcoin.rb', line 120 def encode_compact_bits(target) # bignum to bytes (bn2mpi) without OpenSSL::BN mpi = [ target.to_i(16).to_s(16) ].pack("H*").unpack("C*") bytes = [ mpi.size+1, 0 ].pack("NC").unpack("C*") + mpi size = bytes.size - 4 nbits = size << 24 nbits |= (bytes[4] << 16) if size >= 1 nbits |= (bytes[5] << 8) if size >= 2 nbits |= (bytes[6] ) if size >= 3 nbits end |
- (Object) generate_address
156 157 158 159 |
# File 'lib/bitcoin.rb', line 156 def generate_address prvkey, pubkey = generate_key [ pubkey_to_address(pubkey), prvkey, pubkey, hash160(pubkey) ] end |
- (Object) generate_key
146 147 148 149 |
# File 'lib/bitcoin.rb', line 146 def generate_key key = bitcoin_elliptic_curve.generate_key inspect_key( key ) end |
- (Object) hash160(hex)
hash160 is a 20 bytes (160bits) rmd610-sha256 hexdigest.
33 34 35 36 |
# File 'lib/bitcoin.rb', line 33 def hash160(hex) bytes = [hex].pack("H*") Digest::RMD160.hexdigest Digest::SHA256.digest(bytes) end |
- (Object) hash160_from_address(address)
64 65 66 67 68 |
# File 'lib/bitcoin.rb', line 64 def hash160_from_address(address) return nil unless address_checksum?(address) a = base58_to_int(address).to_s(16) address_version == "00" ? a[0...40] : a[2...42] end |
- (Object) hash160_to_address(hex)
74 75 76 77 78 79 |
# File 'lib/bitcoin.rb', line 74 def hash160_to_address(hex) hex = address_version + hex addr = encode_base58(hex + checksum(hex)) addr = "1" + addr if address_version == "00" addr end |
- (Object) hash_mrkl_tree(tx)
175 176 177 178 179 180 181 182 183 |
# File 'lib/bitcoin.rb', line 175 def hash_mrkl_tree(tx) chunks = [ tx.dup ] while chunks.last.size >= 2 chunks << chunks.last.each_slice(2).map{|i| Bitcoin.bitcoin_mrkl( i[0], i[1] || i[0] ) } end chunks.flatten end |
- (Object) htb(h)
26 |
# File 'lib/bitcoin.rb', line 26 def htb(h); [h].pack("H*"); end |
- (Object) hth(h)
25 |
# File 'lib/bitcoin.rb', line 25 def hth(h); h.unpack("H*")[0]; end |
- (Object) inspect_key(key)
151 152 153 154 |
# File 'lib/bitcoin.rb', line 151 def inspect_key(key) [ key.private_key.to_hex.rjust(64, '0'), key.public_key.to_hex.rjust(130, '0') ] end |
- (Object) int_to_base58(int_val)
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/bitcoin.rb', line 89 def int_to_base58(int_val) alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" base58_val, base = '', alpha.size while(int_val >= base) mod = int_val % base base58_val = alpha[mod,1] + base58_val int_val = (int_val - mod)/base end alpha[int_val,1] + base58_val end |
- (Object) open_key(private_key, public_key)
196 197 198 199 200 201 |
# File 'lib/bitcoin.rb', line 196 def open_key(private_key, public_key) key = bitcoin_elliptic_curve key.private_key = ::OpenSSL::BN.from_hex(private_key) key.public_key = ::OpenSSL::PKey::EC::Point.from_hex(key.group, public_key) key end |
- (Object) pubkey_to_address(pubkey)
81 82 83 |
# File 'lib/bitcoin.rb', line 81 def pubkey_to_address(pubkey) hash160_to_address( hash160(pubkey) ) end |
- (Object) sha256(hex)
70 71 72 |
# File 'lib/bitcoin.rb', line 70 def sha256(hex) Digest::SHA256.hexdigest([hex].pack("H*")) end |
- (Object) sign_data(key, data)
186 187 188 |
# File 'lib/bitcoin.rb', line 186 def sign_data(key, data) key.dsa_sign_asn1(data) end |
- (Boolean) valid_address?(address)
TODO
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/bitcoin.rb', line 53 def valid_address?(address) # TODO if address_version == "00" return false if address[0] != "1" else a = base58_to_int(address).to_s(16) return false if a[0..1] != address_version end return false if !address_checksum?(address) true end |
- (Object) verify_signature(hash, signature, public_key)
190 191 192 193 194 |
# File 'lib/bitcoin.rb', line 190 def verify_signature(hash, signature, public_key) key = bitcoin_elliptic_curve key.public_key = ::OpenSSL::PKey::EC::Point.from_hex(key.group, public_key) key.dsa_verify_asn1(hash, signature) end |