Module: Eth::Util

Extended by:
Util
Included in:
Util
Defined in:
lib/eth/util.rb

Overview

Defines handy tools for the Eth gem for convenience.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.big_endian_to_int(str) ⇒ Integer

Converts a big endian to an interger.

Parameters:

  • str (String)

    big endian to be converted.

Returns:

  • (Integer)

    an unpacked integer number.



149
150
151
# File 'lib/eth/util.rb', line 149

def big_endian_to_int(str)
  str.unpack("H*").first.to_i(16)
end

.bin_to_hex(bin) ⇒ String

Unpacks a binary string to a hexa-decimal string.

Parameters:

  • bin (String)

    a binary string to be unpacked.

Returns:

  • (String)

    a hexa-decimal string.

Raises:

  • (TypeError)

    if value is not a string.



51
52
53
54
# File 'lib/eth/util.rb', line 51

def bin_to_hex(bin)
  raise TypeError, "Value must be an instance of String" unless bin.instance_of? String
  hex = bin.unpack("H*").first
end

.bin_to_prefixed_hex(bin) ⇒ String

Unpacks a binary string to a prefixed hexa-decimal string.

Parameters:

  • bin (String)

    a binary string to be unpacked.

Returns:

  • (String)

    a prefixed hexa-decimal string.



92
93
94
# File 'lib/eth/util.rb', line 92

def bin_to_prefixed_hex(bin)
  prefix_hex bin_to_hex bin
end

.bytes?(str) ⇒ Boolean

Checks if a string is a byte-string.

Parameters:

  • str (String)

    a string to check.

Returns:

  • (Boolean)

    true if it’s an ASCII-8bit encoded byte-string.



173
174
175
# File 'lib/eth/util.rb', line 173

def bytes?(str)
  str && str.instance_of?(String) && str.encoding.name == Constant::BINARY_ENCODING
end

.bytes_to_str(bin) ⇒ String

Converts bytes to a binary string.

Parameters:

  • bin (Object)

    bytes to be converted.

Returns:

  • (String)

    a packed binary string.



165
166
167
# File 'lib/eth/util.rb', line 165

def bytes_to_str(bin)
  bin.unpack("U*").pack("U*")
end

.ceil32(num) ⇒ Integer

Ceil and integer to the next multiple of 32 bytes.

Parameters:

  • num (Integer)

    the number to ciel up.

Returns:

  • (Integer)

    the ceiled to 32 integer.



197
198
199
# File 'lib/eth/util.rb', line 197

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

.deserialize_big_endian_to_int(str) ⇒ Integer

Deserializes big endian data string to integer.

Parameters:

  • str (String)

    serialized big endian integer string.

Returns:

  • (Integer)

    an deserialized unsigned integer.



141
142
143
# File 'lib/eth/util.rb', line 141

def deserialize_big_endian_to_int(str)
  Rlp::Sedes.big_endian_int.deserialize str.sub(/\A(\x00)+/, "")
end

.hex?(str) ⇒ String

Checks if a string is hex-adecimal.

Parameters:

  • str (String)

    a string to be checked.

Returns:

  • (String)

    a match if true; nil if not.



100
101
102
103
104
# File 'lib/eth/util.rb', line 100

def hex?(str)
  return false unless str.is_a? String
  str = remove_hex_prefix str
  str.match /\A[0-9a-fA-F]*\z/
end

.hex_to_bin(hex) ⇒ String

Packs a hexa-decimal string into a binary string. Also works with 0x-prefixed strings.

Parameters:

  • hex (String)

    a hexa-decimal string to be packed.

Returns:

  • (String)

    a packed binary string.

Raises:

  • (TypeError)

    if value is not a string or string is not hex.



62
63
64
65
66
67
68
# File 'lib/eth/util.rb', line 62

def hex_to_bin(hex)
  raise TypeError, "Value must be an instance of String" unless hex.instance_of? String
  hex = remove_hex_prefix hex
  raise TypeError, "Non-hexadecimal digit found" unless hex? hex
  hex = "0#{hex}" if hex.size % 2 != 0
  bin = [hex].pack("H*")
end

.int_to_big_endian(num) ⇒ String

Converts an integer to big endian.

Parameters:

  • num (Integer)

    integer to be converted.

Returns:

  • (String)

    packed, big-endian integer string.



131
132
133
134
135
# File 'lib/eth/util.rb', line 131

def int_to_big_endian(num)
  hex = num.to_s(16) unless hex? num
  hex = "0#{hex}" if hex.size.odd?
  hex_to_bin hex
end

.keccak256(str) ⇒ String

Hashes a string with the Keccak-256 algorithm.

Parameters:

  • str (String)

    a string to be hashed.

Returns:

  • (String)

    a Keccak-256 hash of the given string.



42
43
44
# File 'lib/eth/util.rb', line 42

def keccak256(str)
  Digest::Keccak.new(256).digest str
end

.list?(item) ⇒ Boolean

Checks if the given item is a list.

Parameters:

  • item (Object)

    the item to check.

Returns:

  • (Boolean)

    true if it’s a list.



189
190
191
# File 'lib/eth/util.rb', line 189

def list?(item)
  !primitive?(item) && item.respond_to?(:each)
end

.lpad(str, sym, len) ⇒ String

Left-pad a number with a symbol.

Parameters:

  • str (String)

    a serialized string to be padded.

  • sym (String)

    a symbol used for left-padding.

  • len (Integer)

    number of symbols for the final string.

Returns:

  • (String)

    a left-padded serialized string of wanted size.



207
208
209
210
# File 'lib/eth/util.rb', line 207

def lpad(str, sym, len)
  return str if str.size >= len
  sym * (len - str.size) + str
end

.prefix_hex(hex) ⇒ String

Prefixes a hexa-decimal string with 0x.

Parameters:

  • hex (String)

    a hex-string to be prefixed.

Returns:

  • (String)

    a prefixed hex-string.



74
75
76
77
# File 'lib/eth/util.rb', line 74

def prefix_hex(hex)
  return hex if prefixed? hex
  return "0x#{hex}"
end

.prefixed?(hex) ⇒ String

Checks if a string is prefixed with 0x.

Parameters:

  • hex (String)

    a string to be checked.

Returns:

  • (String)

    a match if true; nil if not.



110
111
112
# File 'lib/eth/util.rb', line 110

def prefixed?(hex)
  hex.match /\A0x/
end

.primitive?(item) ⇒ Boolean

Checks if the given item is a string primitive.

Parameters:

  • item (Object)

    the item to check.

Returns:

  • (Boolean)

    true if it’s a string primitive.



181
182
183
# File 'lib/eth/util.rb', line 181

def primitive?(item)
  item.instance_of?(String)
end

.public_key_to_address(str) ⇒ Eth::Address

Generates an Ethereum address from a given compressed or uncompressed binary or hexadecimal public key string.

Parameters:

  • str (String)

    the public key to be converted.

Returns:



31
32
33
34
35
36
# File 'lib/eth/util.rb', line 31

def public_key_to_address(str)
  str = hex_to_bin str if hex? str
  str = Secp256k1::PublicKey.from_data(str).uncompressed
  bytes = keccak256(str[1..-1])[-20..-1]
  Address.new bin_to_prefixed_hex bytes
end

.remove_hex_prefix(hex) ⇒ String

Removes the 0x prefix of a hexa-decimal string.

Parameters:

  • hex (String)

    a prefixed hex-string.

Returns:

  • (String)

    an unprefixed hex-string.



83
84
85
86
# File 'lib/eth/util.rb', line 83

def remove_hex_prefix(hex)
  return hex[2..-1] if prefixed? hex
  return hex
end

.serialize_int_to_big_endian(num) ⇒ String

Serializes an unsigned integer to big endian.

Parameters:

  • num (Integer)

    unsigned integer to be serialized.

Returns:

  • (String)

    serialized big endian integer string.

Raises:

  • (ArgumentError)

    if unsigned integer is out of bounds.



119
120
121
122
123
124
125
# File 'lib/eth/util.rb', line 119

def serialize_int_to_big_endian(num)
  num = num.to_i(16) if hex? num
  unless num.is_a? Integer and num >= 0 and num <= Constant::UINT_MAX
    raise ArgumentError, "Integer invalid or out of range: #{num}"
  end
  Rlp::Sedes.big_endian_int.serialize num
end

.str_to_bytes(str) ⇒ Object

Converts a binary string to bytes.

Parameters:

  • str (String)

    binary string to be converted.

Returns:

  • (Object)

    the string bytes.



157
158
159
# File 'lib/eth/util.rb', line 157

def str_to_bytes(str)
  bytes?(str) ? str : str.b
end

.zpad(str, len) ⇒ String

Left-pad a serialized string with zeros.

Parameters:

  • str (String)

    a serialized string to be padded.

  • len (Integer)

    number of symbols for the final string.

Returns:

  • (String)

    a zero-padded serialized string of wanted size.



217
218
219
# File 'lib/eth/util.rb', line 217

def zpad(str, len)
  lpad str, Constant::BYTE_ZERO, len
end

.zpad_hex(hex, len = 32) ⇒ String

Left-pad a hex number with zeros.

Parameters:

  • hex (String)

    a hex-string to be padded.

  • len (Integer) (defaults to: 32)

    number of symbols for the final string.

Returns:

  • (String)

    a zero-padded serialized string of wanted size.



226
227
228
# File 'lib/eth/util.rb', line 226

def zpad_hex(hex, len = 32)
  zpad hex_to_bin(hex), len
end

.zpad_int(num, len = 32) ⇒ String

Left-pad an unsigned integer with zeros.

Parameters:

  • num (Integer)

    an unsigned integer to be padded.

  • len (Integer) (defaults to: 32)

    number of symbols for the final string.

Returns:

  • (String)

    a zero-padded serialized string of wanted size.



235
236
237
# File 'lib/eth/util.rb', line 235

def zpad_int(num, len = 32)
  zpad serialize_int_to_big_endian(num), len
end

Instance Method Details

#big_endian_to_int(str) ⇒ Integer

Converts a big endian to an interger.

Parameters:

  • str (String)

    big endian to be converted.

Returns:

  • (Integer)

    an unpacked integer number.



149
150
151
# File 'lib/eth/util.rb', line 149

def big_endian_to_int(str)
  str.unpack("H*").first.to_i(16)
end

#bin_to_hex(bin) ⇒ String

Unpacks a binary string to a hexa-decimal string.

Parameters:

  • bin (String)

    a binary string to be unpacked.

Returns:

  • (String)

    a hexa-decimal string.

Raises:

  • (TypeError)

    if value is not a string.



51
52
53
54
# File 'lib/eth/util.rb', line 51

def bin_to_hex(bin)
  raise TypeError, "Value must be an instance of String" unless bin.instance_of? String
  hex = bin.unpack("H*").first
end

#bin_to_prefixed_hex(bin) ⇒ String

Unpacks a binary string to a prefixed hexa-decimal string.

Parameters:

  • bin (String)

    a binary string to be unpacked.

Returns:

  • (String)

    a prefixed hexa-decimal string.



92
93
94
# File 'lib/eth/util.rb', line 92

def bin_to_prefixed_hex(bin)
  prefix_hex bin_to_hex bin
end

#bytes?(str) ⇒ Boolean

Checks if a string is a byte-string.

Parameters:

  • str (String)

    a string to check.

Returns:

  • (Boolean)

    true if it’s an ASCII-8bit encoded byte-string.



173
174
175
# File 'lib/eth/util.rb', line 173

def bytes?(str)
  str && str.instance_of?(String) && str.encoding.name == Constant::BINARY_ENCODING
end

#bytes_to_str(bin) ⇒ String

Converts bytes to a binary string.

Parameters:

  • bin (Object)

    bytes to be converted.

Returns:

  • (String)

    a packed binary string.



165
166
167
# File 'lib/eth/util.rb', line 165

def bytes_to_str(bin)
  bin.unpack("U*").pack("U*")
end

#ceil32(num) ⇒ Integer

Ceil and integer to the next multiple of 32 bytes.

Parameters:

  • num (Integer)

    the number to ciel up.

Returns:

  • (Integer)

    the ceiled to 32 integer.



197
198
199
# File 'lib/eth/util.rb', line 197

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

#deserialize_big_endian_to_int(str) ⇒ Integer

Deserializes big endian data string to integer.

Parameters:

  • str (String)

    serialized big endian integer string.

Returns:

  • (Integer)

    an deserialized unsigned integer.



141
142
143
# File 'lib/eth/util.rb', line 141

def deserialize_big_endian_to_int(str)
  Rlp::Sedes.big_endian_int.deserialize str.sub(/\A(\x00)+/, "")
end

#hex?(str) ⇒ String

Checks if a string is hex-adecimal.

Parameters:

  • str (String)

    a string to be checked.

Returns:

  • (String)

    a match if true; nil if not.



100
101
102
103
104
# File 'lib/eth/util.rb', line 100

def hex?(str)
  return false unless str.is_a? String
  str = remove_hex_prefix str
  str.match /\A[0-9a-fA-F]*\z/
end

#hex_to_bin(hex) ⇒ String

Packs a hexa-decimal string into a binary string. Also works with 0x-prefixed strings.

Parameters:

  • hex (String)

    a hexa-decimal string to be packed.

Returns:

  • (String)

    a packed binary string.

Raises:

  • (TypeError)

    if value is not a string or string is not hex.



62
63
64
65
66
67
68
# File 'lib/eth/util.rb', line 62

def hex_to_bin(hex)
  raise TypeError, "Value must be an instance of String" unless hex.instance_of? String
  hex = remove_hex_prefix hex
  raise TypeError, "Non-hexadecimal digit found" unless hex? hex
  hex = "0#{hex}" if hex.size % 2 != 0
  bin = [hex].pack("H*")
end

#int_to_big_endian(num) ⇒ String

Converts an integer to big endian.

Parameters:

  • num (Integer)

    integer to be converted.

Returns:

  • (String)

    packed, big-endian integer string.



131
132
133
134
135
# File 'lib/eth/util.rb', line 131

def int_to_big_endian(num)
  hex = num.to_s(16) unless hex? num
  hex = "0#{hex}" if hex.size.odd?
  hex_to_bin hex
end

#keccak256(str) ⇒ String

Hashes a string with the Keccak-256 algorithm.

Parameters:

  • str (String)

    a string to be hashed.

Returns:

  • (String)

    a Keccak-256 hash of the given string.



42
43
44
# File 'lib/eth/util.rb', line 42

def keccak256(str)
  Digest::Keccak.new(256).digest str
end

#list?(item) ⇒ Boolean

Checks if the given item is a list.

Parameters:

  • item (Object)

    the item to check.

Returns:

  • (Boolean)

    true if it’s a list.



189
190
191
# File 'lib/eth/util.rb', line 189

def list?(item)
  !primitive?(item) && item.respond_to?(:each)
end

#lpad(str, sym, len) ⇒ String

Left-pad a number with a symbol.

Parameters:

  • str (String)

    a serialized string to be padded.

  • sym (String)

    a symbol used for left-padding.

  • len (Integer)

    number of symbols for the final string.

Returns:

  • (String)

    a left-padded serialized string of wanted size.



207
208
209
210
# File 'lib/eth/util.rb', line 207

def lpad(str, sym, len)
  return str if str.size >= len
  sym * (len - str.size) + str
end

#prefix_hex(hex) ⇒ String

Prefixes a hexa-decimal string with 0x.

Parameters:

  • hex (String)

    a hex-string to be prefixed.

Returns:

  • (String)

    a prefixed hex-string.



74
75
76
77
# File 'lib/eth/util.rb', line 74

def prefix_hex(hex)
  return hex if prefixed? hex
  return "0x#{hex}"
end

#prefixed?(hex) ⇒ String

Checks if a string is prefixed with 0x.

Parameters:

  • hex (String)

    a string to be checked.

Returns:

  • (String)

    a match if true; nil if not.



110
111
112
# File 'lib/eth/util.rb', line 110

def prefixed?(hex)
  hex.match /\A0x/
end

#primitive?(item) ⇒ Boolean

Checks if the given item is a string primitive.

Parameters:

  • item (Object)

    the item to check.

Returns:

  • (Boolean)

    true if it’s a string primitive.



181
182
183
# File 'lib/eth/util.rb', line 181

def primitive?(item)
  item.instance_of?(String)
end

#public_key_to_address(str) ⇒ Eth::Address

Generates an Ethereum address from a given compressed or uncompressed binary or hexadecimal public key string.

Parameters:

  • str (String)

    the public key to be converted.

Returns:



31
32
33
34
35
36
# File 'lib/eth/util.rb', line 31

def public_key_to_address(str)
  str = hex_to_bin str if hex? str
  str = Secp256k1::PublicKey.from_data(str).uncompressed
  bytes = keccak256(str[1..-1])[-20..-1]
  Address.new bin_to_prefixed_hex bytes
end

#remove_hex_prefix(hex) ⇒ String

Removes the 0x prefix of a hexa-decimal string.

Parameters:

  • hex (String)

    a prefixed hex-string.

Returns:

  • (String)

    an unprefixed hex-string.



83
84
85
86
# File 'lib/eth/util.rb', line 83

def remove_hex_prefix(hex)
  return hex[2..-1] if prefixed? hex
  return hex
end

#serialize_int_to_big_endian(num) ⇒ String

Serializes an unsigned integer to big endian.

Parameters:

  • num (Integer)

    unsigned integer to be serialized.

Returns:

  • (String)

    serialized big endian integer string.

Raises:

  • (ArgumentError)

    if unsigned integer is out of bounds.



119
120
121
122
123
124
125
# File 'lib/eth/util.rb', line 119

def serialize_int_to_big_endian(num)
  num = num.to_i(16) if hex? num
  unless num.is_a? Integer and num >= 0 and num <= Constant::UINT_MAX
    raise ArgumentError, "Integer invalid or out of range: #{num}"
  end
  Rlp::Sedes.big_endian_int.serialize num
end

#str_to_bytes(str) ⇒ Object

Converts a binary string to bytes.

Parameters:

  • str (String)

    binary string to be converted.

Returns:

  • (Object)

    the string bytes.



157
158
159
# File 'lib/eth/util.rb', line 157

def str_to_bytes(str)
  bytes?(str) ? str : str.b
end

#zpad(str, len) ⇒ String

Left-pad a serialized string with zeros.

Parameters:

  • str (String)

    a serialized string to be padded.

  • len (Integer)

    number of symbols for the final string.

Returns:

  • (String)

    a zero-padded serialized string of wanted size.



217
218
219
# File 'lib/eth/util.rb', line 217

def zpad(str, len)
  lpad str, Constant::BYTE_ZERO, len
end

#zpad_hex(hex, len = 32) ⇒ String

Left-pad a hex number with zeros.

Parameters:

  • hex (String)

    a hex-string to be padded.

  • len (Integer) (defaults to: 32)

    number of symbols for the final string.

Returns:

  • (String)

    a zero-padded serialized string of wanted size.



226
227
228
# File 'lib/eth/util.rb', line 226

def zpad_hex(hex, len = 32)
  zpad hex_to_bin(hex), len
end

#zpad_int(num, len = 32) ⇒ String

Left-pad an unsigned integer with zeros.

Parameters:

  • num (Integer)

    an unsigned integer to be padded.

  • len (Integer) (defaults to: 32)

    number of symbols for the final string.

Returns:

  • (String)

    a zero-padded serialized string of wanted size.



235
236
237
# File 'lib/eth/util.rb', line 235

def zpad_int(num, len = 32)
  zpad serialize_int_to_big_endian(num), len
end