Class: Reth::Account

Inherits:
Object
  • Object
show all
Defined in:
lib/reth/account.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(keystore, password = nil, path = nil) ⇒ Account

Returns a new instance of Account.



59
60
61
62
63
64
65
66
67
# File 'lib/reth/account.rb', line 59

def initialize(keystore, password=nil, path=nil)
  @keystore = Hashie.symbolize_keys keystore
  @address = keystore[:address] ? Utils.decode_hex(keystore[:address]) : nil

  @path = path
  @locked = true

  unlock(password) if password
end

Instance Attribute Details

#addressObject

Returns the value of attribute address.



57
58
59
# File 'lib/reth/account.rb', line 57

def address
  @address
end

#keystoreObject

Returns the value of attribute keystore.



57
58
59
# File 'lib/reth/account.rb', line 57

def keystore
  @keystore
end

#pathObject

Returns the value of attribute path.



57
58
59
# File 'lib/reth/account.rb', line 57

def path
  @path
end

Class Method Details

.create(password, key = nil, uuid = nil, path = nil) ⇒ Object

Create a new account.

Note that this creates the account in memory and does not store it on disk.

Parameters:

  • password (String)

    used to encrypt the private key

  • key (String) (defaults to: nil)

    the private key, or 'nil` to generate a random one

  • uuid (String) (defaults to: nil)

    an optional id



34
35
36
37
38
39
40
41
# File 'lib/reth/account.rb', line 34

def create(password, key=nil, uuid=nil, path=nil)
  key ||= Utils.mk_random_privkey

  json = Keystore.make_json key, password
  json[:id] = uuid

  new json, password, path
end

.load(path, password = nil) ⇒ Object

Load an account from a keystore file.

Parameters:

  • path (String)

    full path to the keyfile

  • password (String) (defaults to: nil)

    the password to decrypt the key file or 'nil` to leave it encrypted

Raises:

  • (ValidationError)


50
51
52
53
54
# File 'lib/reth/account.rb', line 50

def load(path, password=nil)
  json = JSON.load File.read(path)
  raise ValidationError, 'Invalid keystore file' unless Keystore.validate(json)
  new json, password, path
end

.test_accountsObject



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/reth/account.rb', line 8

def test_accounts
  return @test_accounts if @test_accounts

  @test_accounts = 9.times.map do |i|
    privkey = (i+1).chr * 32
    address = Ethereum::PrivateKey.new(privkey).to_address
    ["0x#{Ethereum::Utils.encode_hex(address)}", privkey]
  end.to_h

  @test_accounts
end

.test_addressesObject



20
21
22
# File 'lib/reth/account.rb', line 20

def test_addresses
  @test_addresses ||= test_accounts.keys.map {|k| Ethereum::Utils.normalize_address(k) }
end

Instance Method Details

#dump(include_address = true, include_id = true) ⇒ Object

Dump the keystore for later disk storage.

The result inherits the entries ‘crypto` and `version` from `Keystore`, and adds `address` and `id` in accordance with the parameters `include_address` and `include_id`.

If address or id are not known, they are not added, even if requested.

Parameters:

  • include_address (Bool) (defaults to: true)

    flag denoting if the address should be included or not

  • include_id (Bool) (defaults to: true)

    flag denoting if the id should be included or not



83
84
85
86
87
88
89
90
91
92
# File 'lib/reth/account.rb', line 83

def dump(include_address=true, include_id=true)
  h = {}
  h[:crypto] = @keystore[:crypto]
  h[:version] = @keystore[:version]

  h[:address] = Utils.encode_hex address if include_address && address
  h[:id] = uuid if include_id && uuid

  JSON.dump(h)
end

#lockObject

Relock an unlocked account.

This method sets ‘privkey` to `nil` (unlike `address` which is preserved).



117
118
119
120
# File 'lib/reth/account.rb', line 117

def lock
  @privkey = nil
  @locked = true
end

#locked?Boolean

Returns:

  • (Boolean)


178
179
180
# File 'lib/reth/account.rb', line 178

def locked?
  @locked
end

#privkeyObject



122
123
124
# File 'lib/reth/account.rb', line 122

def privkey
  @locked ? nil : @privkey
end

#pubkeyObject



126
127
128
# File 'lib/reth/account.rb', line 126

def pubkey
  @locked ? nil : PrivateKey.new(@privkey).to_pubkey
end

#sign_tx(tx) ⇒ Object

Sign a Transaction with the private key of this account.

If the account is unlocked, this is equivalent to ‘tx.sign(account.privkey)`.

Parameters:

Raises:

  • (ValueError)

    if the account is locked



169
170
171
172
173
174
175
176
# File 'lib/reth/account.rb', line 169

def sign_tx(tx)
  if privkey
    logger.info "signing tx", tx: tx, account: self
    tx.sign privkey
  else
    raise ValueError, "Locked account cannot sign tx"
  end
end

#to_sObject



182
183
184
185
# File 'lib/reth/account.rb', line 182

def to_s
  addr = address ? Utils.encode_hex(address) : '?'
  "<Account(address=#{addr}, id=#{uuid})>"
end

#unlock(password) ⇒ Object

Unlock the account with a password.

If the account is already unlocked, nothing happens, even if the password is wrong.

password is wrong and the account is locked

Raises:

  • (ValueError)

    (originating from 'Keystore.decode_json`) if the



103
104
105
106
107
108
109
# File 'lib/reth/account.rb', line 103

def unlock(password)
  if @locked
    @privkey = Keystore.decode_json @keystore, password
    @locked = false
    address # get address such that it stays accessible after a subsequent lock
  end
end

#uuidObject

An optional unique identifier, formatted according to UUID version 4, or ‘nil` if the account does not have an id.



148
149
150
# File 'lib/reth/account.rb', line 148

def uuid
  @keystore[:id]
end

#uuid=(id) ⇒ Object



152
153
154
155
156
157
158
# File 'lib/reth/account.rb', line 152

def uuid=(id)
  if id
    @keystore[:id] = id
  else
    @keystore.delete :id
  end
end