Class: Bitcoin::Wallet::SimpleKeyStore

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin/wallet/keystore.rb

Overview

JSON-file-based keystore used by the Wallet.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ SimpleKeyStore

Initialize keystore.

config

Hash of settings (=> “/foo/bar.json”)



15
16
17
18
19
20
# File 'lib/bitcoin/wallet/keystore.rb', line 15

def initialize config
  @config = Hash[config.map{|k,v|[k.to_sym,v]}]
  @config[:file].sub!("~", ENV["HOME"])  if @config[:file].is_a?(String)
  @keys = []
  load_keys
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



11
12
13
# File 'lib/bitcoin/wallet/keystore.rb', line 11

def config
  @config
end

Instance Method Details

#add_key(key) ⇒ Object

Add a key which can consist only of addr and label.

Raises:

  • (ArgumentError)


56
57
58
59
60
61
62
63
64
# File 'lib/bitcoin/wallet/keystore.rb', line 56

def add_key key
  label = key[:label]
  raise ArgumentError, "Label #{label} already in use"  if label && find_key(label)
  addr = key[:addr]
  raise ArgumentError, "Address #{addr} is invalid"  if addr && !Bitcoin.valid_address?(addr)
  @keys << key
  save_keys
  key
end

#delete(name) ⇒ Object

Delete key for given label, addr or pubkey.



81
82
83
84
85
# File 'lib/bitcoin/wallet/keystore.rb', line 81

def delete(name)
  key = find_key(name)
  @keys.delete(key)
  save_keys
end

#export(name) ⇒ Object

Export key for given name to base58 format. (See Bitcoin::Key#to_base58)



89
90
91
# File 'lib/bitcoin/wallet/keystore.rb', line 89

def export(name)
  find_key(name)[:key].to_base58 rescue nil
end

#flag_key(name, flag, value) ⇒ Object



73
74
75
76
77
78
# File 'lib/bitcoin/wallet/keystore.rb', line 73

def flag_key(name, flag, value)
  find_key(name, true) do |key|
    key[flag.to_sym] = value
  end
  save_keys
end

#import(base58, label = nil) ⇒ Object

Import key from given base58 string. (See Bitcoin::Key.from_base58)

Raises:

  • (ArgumentError)


95
96
97
98
99
100
101
102
# File 'lib/bitcoin/wallet/keystore.rb', line 95

def import(base58, label = nil)
  raise ArgumentError, "Label #{label} already in use"  if label && find_key(label)
  key = Bitcoin::Key.from_base58(base58)
  raise ArgumentError, "Address #{key.addr} already in use"  if label && find_key(key.addr)
  @keys << {:label => label, :addr => key.addr, :key => key}
  save_keys
  key
end

#key(name) ⇒ Object

Get key for given label, addr or pubkey.



42
43
44
# File 'lib/bitcoin/wallet/keystore.rb', line 42

def key(name)
  find_key(name)
end

#keys(need = nil) ⇒ Object

List all stored keys.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/bitcoin/wallet/keystore.rb', line 23

def keys(need = nil)
  @keys.select do |key|
    next !(key[:hidden] && key[:hidden] == "true")  unless need
    case need
    when :label
      !!key[:label]
    when :pub
      !!key[:key].pub
    when :priv
      !!key[:key].priv
    when :hidden
      !!key[:hidden]
    when :mine
      !!key[:mine]
    end
  end
end

#label_key(name, label) ⇒ Object



66
67
68
69
70
71
# File 'lib/bitcoin/wallet/keystore.rb', line 66

def label_key(name, label)
  find_key(name) do |key|
    key[:label] = label
  end
  save_keys
end

#load_keysObject

Load keys from file. If file is empty this will generate a new key and store it, creating the file.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/bitcoin/wallet/keystore.rb', line 107

def load_keys
  loader = proc{|keys|
    keys.map!{|k| Hash[k.map{|k,v| [k.to_sym, v] }]}
    keys.map do |key|
      key[:key] = Bitcoin::Key.new(key[:priv], key[:pub])
      key[:priv], key[:pub] = nil
      @keys << key
    end
  }
  if @config[:file].is_a?(StringIO)
    json = JSON.load(@config[:file].read)
    loader.call(json)
  elsif File.exist?(@config[:file])
    json = JSON.load(File.read(@config[:file]))
    loader.call(json)
  else
    new_key; save_keys
  end
end

#new_key(label = nil) ⇒ Object

Generate and store a new key.

Raises:

  • (ArgumentError)


47
48
49
50
51
52
53
# File 'lib/bitcoin/wallet/keystore.rb', line 47

def new_key(label = nil)
  raise ArgumentError, "Label #{label} already in use"  if label && find_key(label)
  key = Bitcoin::Key.generate
  @keys << {:label => label, :addr => key.addr, :key => key}
  save_keys
  key
end

#save_keysObject

Save keys to file.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/bitcoin/wallet/keystore.rb', line 128

def save_keys
  dumper = proc{|file|
    keys = @keys.map do |key|
      key = key.dup
      if key[:key]
        key[:priv] = key[:key].priv
        key[:pub] = key[:key].pub
        key.delete(:key)
      end
      key
    end
    file.write(JSON.pretty_generate(keys))
  }

  if @config[:file].is_a?(StringIO)
    @config[:file].reopen
    dumper.call(@config[:file])
    @config[:file].rewind
  else
    File.open(@config[:file], 'w'){|file| dumper.call(file) }
  end
end