Module: Ethereum::Utils

Extended by:
Utils
Includes:
Constant
Included in:
Utils
Defined in:
lib/ethereum/utils.rb

Constant Summary

Constants included from Constant

Constant::BYTE_EMPTY, Constant::BYTE_ONE, Constant::BYTE_ZERO, Constant::HASH_ZERO, Constant::INT_MAX, Constant::INT_MIN, Constant::PRIVKEY_ZERO, Constant::PRIVKEY_ZERO_HEX, Constant::PUBKEY_ZERO, Constant::TT256, Constant::TT32, Constant::TT64M1, Constant::UINT_MAX, Constant::UINT_MIN

Instance Method Summary collapse

Instance Method Details

#base58_check_to_bytes(s) ⇒ Object

Raises:



61
62
63
64
65
66
67
# File 'lib/ethereum/utils.rb', line 61

def base58_check_to_bytes(s)
  leadingzbytes = s.match(/\A1*/)[0]
  data = Constant::BYTE_ZERO * leadingzbytes.size + BaseConvert.convert(s, 58, 256)

  raise ChecksumError, "double sha256 checksum doesn't match" unless double_sha256(data[0...-4])[0,4] == data[-4..-1]
  data[1...-4]
end

#big_endian_to_int(s) ⇒ Object



88
89
90
# File 'lib/ethereum/utils.rb', line 88

def big_endian_to_int(s)
  RLP::Sedes.big_endian_int.deserialize s.sub(/\A(\x00)+/, '')
end

#bytearray_to_int(arr) ⇒ Object



136
137
138
139
140
# File 'lib/ethereum/utils.rb', line 136

def bytearray_to_int(arr)
  o = 0
  arr.each {|x| o = (o << 8) + x }
  o
end

#bytes_to_base58_check(bytes, magicbyte = 0) ⇒ Object



69
70
71
72
73
74
# File 'lib/ethereum/utils.rb', line 69

def bytes_to_base58_check(bytes, magicbyte=0)
  bs = "#{magicbyte.chr}#{bytes}"
  leadingzbytes = bs.match(/\A#{Constant::BYTE_ZERO}*/)[0]
  checksum = double_sha256(bs)[0,4]
  '1'*leadingzbytes.size + BaseConvert.convert("#{bs}#{checksum}", 256, 58)
end

#bytes_to_int_array(bytes) ⇒ Object



146
147
148
# File 'lib/ethereum/utils.rb', line 146

def bytes_to_int_array(bytes)
  bytes.unpack('C*')
end

#ceil32(x) ⇒ Object



76
77
78
# File 'lib/ethereum/utils.rb', line 76

def ceil32(x)
  x % 32 == 0 ? x : (x + 32 - x%32)
end

#coerce_addr_to_hex(x) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/ethereum/utils.rb', line 170

def coerce_addr_to_hex(x)
  if x.is_a?(Numeric)
    encode_hex zpad(int_to_big_endian(x), 20)
  elsif x.size == 40 || x.size == 0
    x
  else
    encode_hex zpad(x, 20)[-20..-1]
  end
end

#coerce_to_bytes(x) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/ethereum/utils.rb', line 160

def coerce_to_bytes(x)
  if x.is_a?(Numeric)
    int_to_big_endian x
  elsif x.size == 40
    decode_hex(x)
  else
    x
  end
end

#coerce_to_int(x) ⇒ Object



150
151
152
153
154
155
156
157
158
# File 'lib/ethereum/utils.rb', line 150

def coerce_to_int(x)
  if x.is_a?(Numeric)
    x
  elsif x.size == 40
    big_endian_to_int decode_hex(x)
  else
    big_endian_to_int x
  end
end

#decode_hex(s) ⇒ Object



84
85
86
# File 'lib/ethereum/utils.rb', line 84

def decode_hex(s)
  RLP::Utils.decode_hex s
end

#decode_int(v) ⇒ Object

Raises:

  • (ArgumentError)


131
132
133
134
# File 'lib/ethereum/utils.rb', line 131

def decode_int(v)
  raise ArgumentError, "No leading zero bytes allowed for integers" if v.size > 0 && (v[0] == Constant::BYTE_ZERO || v[0] == 0)
  big_endian_to_int v
end

#double_sha256(x) ⇒ Object



33
34
35
# File 'lib/ethereum/utils.rb', line 33

def double_sha256(x)
  sha256 sha256(x)
end

#encode_hex(b) ⇒ Object



80
81
82
# File 'lib/ethereum/utils.rb', line 80

def encode_hex(b)
  RLP::Utils.encode_hex b
end

#encode_int(n) ⇒ Object

Raises:

  • (ArgumentError)


126
127
128
129
# File 'lib/ethereum/utils.rb', line 126

def encode_int(n)
  raise ArgumentError, "Integer invalid or out of range: #{n}" unless n.is_a?(Integer) && n >= 0 && n <= UINT_MAX
  int_to_big_endian n
end

#hash160(x) ⇒ Object



41
42
43
# File 'lib/ethereum/utils.rb', line 41

def hash160(x)
  ripemd160 sha256(x)
end

#hash160_hex(x) ⇒ Object



45
46
47
# File 'lib/ethereum/utils.rb', line 45

def hash160_hex(x)
  encode_hex hash160(x)
end

#int_array_to_bytes(arr) ⇒ Object



142
143
144
# File 'lib/ethereum/utils.rb', line 142

def int_array_to_bytes(arr)
  arr.pack('C*')
end

#int_to_addr(x) ⇒ Object



122
123
124
# File 'lib/ethereum/utils.rb', line 122

def int_to_addr(x)
  zpad_int x, 20
end

#int_to_big_endian(n) ⇒ Object



92
93
94
# File 'lib/ethereum/utils.rb', line 92

def int_to_big_endian(n)
  RLP::Sedes.big_endian_int.serialize n
end

#keccak256(x) ⇒ Object

Not the keccak in sha3, although it’s underlying lib named SHA3



17
18
19
# File 'lib/ethereum/utils.rb', line 17

def keccak256(x)
  Digest::SHA3.new(256).digest(x)
end

#keccak256_rlp(x) ⇒ Object



25
26
27
# File 'lib/ethereum/utils.rb', line 25

def keccak256_rlp(x)
  keccak256 RLP.encode(x)
end

#keccak512(x) ⇒ Object



21
22
23
# File 'lib/ethereum/utils.rb', line 21

def keccak512(x)
  Digest::SHA3.new(512).digest(x)
end

#lpad(x, symbol, l) ⇒ Object



96
97
98
99
# File 'lib/ethereum/utils.rb', line 96

def lpad(x, symbol, l)
  return x if x.size >= l
  symbol * (l - x.size) + x
end

#mk_contract_address(sender, nonce) ⇒ Object



186
187
188
# File 'lib/ethereum/utils.rb', line 186

def mk_contract_address(sender, nonce)
  keccak256_rlp([normalize_address(sender), nonce])[12..-1]
end

#mod_exp(x, y, n) ⇒ Object



49
50
51
# File 'lib/ethereum/utils.rb', line 49

def mod_exp(x, y, n)
  x.to_bn.mod_exp(y, n).to_i
end

#mod_mul(x, y, n) ⇒ Object



53
54
55
# File 'lib/ethereum/utils.rb', line 53

def mod_mul(x, y, n)
  x.to_bn.mod_mul(y, n).to_i
end

#normalize_address(x, allow_blank: false) ⇒ Object

Raises:



180
181
182
183
184
# File 'lib/ethereum/utils.rb', line 180

def normalize_address(x, allow_blank: false)
  address = Address.new(x)
  raise ValueError, "address is blank" if !allow_blank && address.blank?
  address.to_bytes
end

#ripemd160(x) ⇒ Object



37
38
39
# File 'lib/ethereum/utils.rb', line 37

def ripemd160(x)
  Digest::RMD160.digest x
end

#rpad(x, symbol, l) ⇒ Object



101
102
103
104
# File 'lib/ethereum/utils.rb', line 101

def rpad(x, symbol, l)
  return x if x.size >= l
  x + symbol * (l - x.size)
end

#sha256(x) ⇒ Object



29
30
31
# File 'lib/ethereum/utils.rb', line 29

def sha256(x)
  Digest::SHA256.digest x
end

#to_signed(i) ⇒ Object



57
58
59
# File 'lib/ethereum/utils.rb', line 57

def to_signed(i)
  i > Constant::INT_MAX ? (i-Constant::TT256) : i
end

#zpad(x, l) ⇒ Object



106
107
108
# File 'lib/ethereum/utils.rb', line 106

def zpad(x, l)
  lpad x, BYTE_ZERO, l
end

#zpad_hex(s, l = 32) ⇒ Object



118
119
120
# File 'lib/ethereum/utils.rb', line 118

def zpad_hex(s, l=32)
  zpad decode_hex(s), l
end

#zpad_int(n, l = 32) ⇒ Object



114
115
116
# File 'lib/ethereum/utils.rb', line 114

def zpad_int(n, l=32)
  zpad encode_int(n), l
end

#zunpad(x) ⇒ Object



110
111
112
# File 'lib/ethereum/utils.rb', line 110

def zunpad(x)
  x.sub /\A\x00+/, ''
end