Class: Ethereum::SpecialContract::ECRecover

Inherits:
Object
  • Object
show all
Defined in:
lib/ethereum/special_contract.rb

Instance Method Summary collapse

Instance Method Details

#call(ext, msg) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ethereum/special_contract.rb', line 7

def call(ext, msg)
  gas_cost = Opcodes::GECRECOVER
  return 0, 0, [] if msg.gas < gas_cost

  message_hash_ints = [0] * 32
  msg.data.extract_copy(message_hash_ints, 0, 0, 32)
  message_hash = Utils.int_array_to_bytes message_hash_ints

  v = msg.data.extract32(32)
  r = msg.data.extract32(64)
  s = msg.data.extract32(96)

  if r >= Secp256k1::N || s >= Secp256k1::N || v < 27 || v > 28
    return 1, msg.gas - gas_cost, []
  end

  signature_ints = [0] * 64
  msg.data.extract_copy signature_ints, 0, 64, 32  # r
  msg.data.extract_copy signature_ints, 32, 96, 32 # s
  signature = Utils.int_array_to_bytes signature_ints

  pub = nil
  begin
    pub = Secp256k1.recover_pubkey(message_hash, [v,r,s])
  rescue
    return 1, msg.gas - gas_cost, []
  end

  pubhash = Utils.keccak256(pub[1..-1])[-20..-1]
  o = Utils.bytes_to_int_array Utils.zpad(pubhash, 32)

  return 1, msg.gas - gas_cost, o
end