class Bitcoin::ExtPubkey
BIP-32 Extended public key
Attributes
chain_code[RW]
depth[RW]
number[RW]
parent_fingerprint[RW]
pubkey[RW]
ver[RW]
Public Class Methods
encode_base58(hex)
click to toggle source
from_base58(address)
click to toggle source
import pub key from Base58
private key address
# File lib/bitcoin/ext_key.rb, line 334 def self.from_base58(address) ExtPubkey.parse_from_payload(ExtPubkey.validate_base58(address)) end
parse_from_payload(payload)
click to toggle source
# File lib/bitcoin/ext_key.rb, line 314 def self.parse_from_payload(payload) buf = StringIO.new(payload) ext_pubkey = ExtPubkey.new ext_pubkey.ver = buf.read(4).bth # version raise ArgumentError, Errors::Messages::INVALID_BIP32_VERSION unless ExtPubkey.support_version?(ext_pubkey.ver) ext_pubkey.depth = buf.read(1).unpack1('C') ext_pubkey.parent_fingerprint = buf.read(4).bth ext_pubkey.number = buf.read(4).unpack1('N') if ext_pubkey.depth == 0 raise ArgumentError, Errors::Messages::INVALID_BIP32_FINGERPRINT unless ext_pubkey.parent_fingerprint == ExtKey::MASTER_FINGERPRINT raise ArgumentError, Errors::Messages::INVALID_BIP32_ZERO_INDEX if ext_pubkey.number > 0 end raise ArgumentError, Errors::Messages::INVALID_BIP32_ZERO_DEPTH if ext_pubkey.parent_fingerprint == ExtKey::MASTER_FINGERPRINT && ext_pubkey.depth > 0 ext_pubkey.chain_code = buf.read(32) ext_pubkey.pubkey = Bitcoin::Key.new(pubkey: buf.read(33).bth).pubkey ext_pubkey end
support_version?(version)
click to toggle source
check whether version
is supported version bytes.
# File lib/bitcoin/ext_key.rb, line 361 def self.support_version?(version) p = Bitcoin.chain_params [p.bip49_pubkey_p2wpkh_p2sh_version, p.bip84_pubkey_p2wpkh_version, p.extended_pubkey_version].include?(version) end
validate_base58(address)
click to toggle source
Validate address checksum and return payload. @param [String] BIP32 Base58
address @return [String] BIP32 payload with binary format
# File lib/bitcoin/ext_key.rb, line 341 def self.validate_base58(address) raw = Base58.decode(address) raise ArgumentError, Errors::Messages::INVALID_CHECKSUM unless Bitcoin.calc_checksum(raw[0...-8]) == raw[-8..-1] raw[0...-8].htb end
version_from_purpose(purpose)
click to toggle source
get version bytes from purpose' value.
# File lib/bitcoin/ext_key.rb, line 348 def self.version_from_purpose(purpose) v = purpose - Bitcoin::HARDENED_THRESHOLD case v when 49 Bitcoin.chain_params.bip49_pubkey_p2wpkh_p2sh_version when 84 Bitcoin.chain_params.bip84_pubkey_p2wpkh_version else Bitcoin.chain_params.extended_pubkey_version end end
Public Instance Methods
==(other)
click to toggle source
# File lib/bitcoin/ext_key.rb, line 310 def ==(other) to_payload == other.to_payload end
addr()
click to toggle source
get address
# File lib/bitcoin/ext_key.rb, line 227 def addr case version when Bitcoin.chain_params.bip49_pubkey_p2wpkh_p2sh_version key.to_nested_p2wpkh when Bitcoin.chain_params.bip84_pubkey_p2wpkh_version key.to_p2wpkh else key.to_p2pkh end end
derive(number)
click to toggle source
derive child key
# File lib/bitcoin/ext_key.rb, line 272 def derive(number) new_key = ExtPubkey.new new_key.depth = depth + 1 raise IndexError, 'Depth over 255.' if new_key.depth > Bitcoin::ExtKey::MAX_DEPTH new_key.number = number new_key.parent_fingerprint = fingerprint raise 'hardened key is not support' if number > (Bitcoin::HARDENED_THRESHOLD - 1) data = pub.htb << [number].pack('N') l = Bitcoin.hmac_sha512(chain_code, data) left = l[0..31].bth.to_i(16) raise 'invalid key' if left >= CURVE_ORDER p1 = Bitcoin::Key.new(priv_key: left.to_s(16), key_type: Bitcoin::Key::TYPES[:uncompressed]).to_point p2 = Bitcoin::Key.new(pubkey: pubkey, key_type: key_type).to_point new_key.pubkey = (p1 + p2).to_hex new_key.chain_code = l[32..-1] new_key.ver = version new_key end
fingerprint()
click to toggle source
get fingerprint
# File lib/bitcoin/ext_key.rb, line 250 def fingerprint identifier.slice(0..7) end
hardened?()
click to toggle source
whether hardened key.
# File lib/bitcoin/ext_key.rb, line 267 def hardened? number >= Bitcoin::HARDENED_THRESHOLD end
hash160()
click to toggle source
# File lib/bitcoin/ext_key.rb, line 222 def hash160 Bitcoin.hash160(pub) end
identifier()
click to toggle source
get key identifier
# File lib/bitcoin/ext_key.rb, line 245 def identifier Bitcoin.hash160(pub) end
key()
click to toggle source
get key object @return [Bitcoin::Key]
# File lib/bitcoin/ext_key.rb, line 240 def key Bitcoin::Key.new(pubkey: pubkey, key_type: key_type) end
key_type()
click to toggle source
get key type defined by BIP-178 using version.
# File lib/bitcoin/ext_key.rb, line 298 def key_type v = version case v when Bitcoin.chain_params.bip49_pubkey_p2wpkh_p2sh_version Bitcoin::Key::TYPES[:p2wpkh_p2sh] when Bitcoin.chain_params.bip84_pubkey_p2wpkh_version Bitcoin::Key::TYPES[:p2wpkh] when Bitcoin.chain_params.extended_pubkey_version Bitcoin::Key::TYPES[:compressed] end end
pub()
click to toggle source
# File lib/bitcoin/ext_key.rb, line 218 def pub pubkey end
to_base58()
click to toggle source
Base58
encoded extended pubkey
# File lib/bitcoin/ext_key.rb, line 255 def to_base58 ExtPubkey.encode_base58(to_hex) end
to_payload()
click to toggle source
serialize extended pubkey
# File lib/bitcoin/ext_key.rb, line 213 def to_payload version.htb << [depth].pack('C') << parent_fingerprint.htb << [number].pack('N') << chain_code << pub.htb end
version()
click to toggle source
get version bytes using serialization format
# File lib/bitcoin/ext_key.rb, line 292 def version return ExtPubkey.version_from_purpose(number) if depth == 1 ver ? ver : Bitcoin.chain_params.extended_pubkey_version end