class Bitcoin::Wallet::MasterKey
HD Wallet
master seed
Attributes
encrypted[RW]
mnemonic[RW]
salt[RW]
seed[R]
Public Class Methods
generate()
click to toggle source
generate new master key. @return Bitcoin::Wallet::MasterKey
# File lib/bitcoin/wallet/master_key.rb, line 25 def self.generate entropy = SecureRandom.hex(32) mnemonic = Bitcoin::Mnemonic.new('english') self.recover_from_words(mnemonic.to_mnemonic(entropy)) end
new(seed, salt: '', encrypted: false, mnemonic: nil)
click to toggle source
# File lib/bitcoin/wallet/master_key.rb, line 16 def initialize(seed, salt: '', encrypted: false, mnemonic: nil) @mnemonic = mnemonic @seed = seed @encrypted = encrypted @salt = salt end
parse_from_payload(payload)
click to toggle source
parse master key raw data @param [String] payload raw data @return [Bitcoin::Wallet::MasterKey]
# File lib/bitcoin/wallet/master_key.rb, line 43 def self.parse_from_payload(payload) flag, payload = unpack_var_int(payload) raise 'encrypted flag is invalid.' unless [0, 1].include?(flag) salt, payload = unpack_var_string(payload) salt = '' unless salt seed, payload = unpack_var_string(payload) self.new(seed.bth, salt: salt.bth, encrypted: flag == 1) end
recover_from_words(words)
click to toggle source
recover master key from mnemonic word list. @param [Array] words the mnemonic word list. @return Bitcoin::Wallet::MasterKey
# File lib/bitcoin/wallet/master_key.rb, line 34 def self.recover_from_words(words) mnemonic = Bitcoin::Mnemonic.new('english') seed = mnemonic.to_seed(words) self.new(seed, mnemonic: words) end
Public Instance Methods
decrypt(passphrase)
click to toggle source
decrypt seed
# File lib/bitcoin/wallet/master_key.rb, line 89 def decrypt(passphrase) raise 'The wallet is not encrypted.' unless encrypted dec = OpenSSL::Cipher.new('AES-256-CBC') dec.decrypt dec.key, dec.iv = key_iv(dec, passphrase) decrypted_data = '' decrypted_data << dec.update(seed) decrypted_data << dec.final @seed = decrypted_data @encrypted = false @salt = '' end
derive(path)
click to toggle source
derive child key using derivation path. @return [Bitcoin::ExtKey]
# File lib/bitcoin/wallet/master_key.rb, line 68 def derive(path) derived_key = key parse_key_path(path).each{|num| derived_key = derived_key.derive(num)} derived_key end
encrypt(passphrase)
click to toggle source
encrypt seed
# File lib/bitcoin/wallet/master_key.rb, line 75 def encrypt(passphrase) raise 'The wallet is already encrypted.' if encrypted @salt = SecureRandom.hex(16) enc = OpenSSL::Cipher.new('AES-256-CBC') enc.encrypt enc.key, enc.iv = key_iv(enc, passphrase) encrypted_data = '' encrypted_data << enc.update(seed) encrypted_data << enc.final @seed = encrypted_data @encrypted = true end
key()
click to toggle source
get master key @return [Bitcoin::ExtKey] the master key
# File lib/bitcoin/wallet/master_key.rb, line 61 def key raise 'seed is encrypted. please decrypt the seed.' if encrypted Bitcoin::ExtKey.generate_master(seed) end
to_payload()
click to toggle source
generate payload with following format
- encrypted(false:0, true:1)][salt(var str)][seed(var str)
# File lib/bitcoin/wallet/master_key.rb, line 54 def to_payload flg = encrypted ? 1 : 0 pack_var_int(flg) << [salt, seed].map{|v|pack_var_string(v.htb)}.join end
Private Instance Methods
key_iv(enc, passphrase)
click to toggle source
# File lib/bitcoin/wallet/master_key.rb, line 104 def key_iv(enc, passphrase) key_iv = OpenSSL::PKCS5.pbkdf2_hmac_sha1(passphrase, salt, 2000, enc.key_len + enc.iv_len) [key_iv[0, enc.key_len], key_iv[enc.key_len, enc.iv_len]] end