Module: Klay::Chain

Extended by:
Chain
Included in:
Chain
Defined in:
lib/klay/chain.rb

Overview

Encapsulates Eth::Chain IDs and utilities for EIP-155 compatibility. Ref: https://eips.ethereum.org/EIPS/eip-155

Defined Under Namespace

Classes: ReplayProtectionError

Constant Summary collapse

ETHEREUM =

Chain ID for Ethereum mainnet.

1.freeze
EXPANSE =

Chain ID for Expanse mainnet.

2.freeze
OPTIMISM =

Chain ID for Optimistic Ethereum mainnet.

10.freeze
CLASSIC =

Chain ID for Ethereum Classic mainnet.

61.freeze
POA_NET =

Chain ID for POA Network mainnet.

99.freeze
XDAI =

Chain ID for Gnosis mainnet.

100.freeze
ARBITRUM =

Chain ID for Arbitrum mainnet.

42161.freeze
MORDEN =

Chain ID for Morden (Ethereum) testnet.

2.freeze
ROPSTEN =

Chain ID for Ropsten testnet.

3.freeze
RINKEBY =

Chain ID for Rinkeby testnet.

4.freeze
GOERLI =

Chain ID for Goerli testnet.

5.freeze
KOTTI =

Chain ID for Kotti testnet.

6.freeze
KOVAN =

Chain ID for Kovan testnet.

42.freeze
MORDEN_CLASSIC =

Chain ID for Morden (Classic) testnet.

62.freeze
MORDOR =

Chain ID for Mordor testnet.

63.freeze
KOVAN_OPTIMISM =

Chain ID for Optimistik Kovan testnet.

69.freeze
XDAI_ARBITRUM =

Chain ID for Arbitrum xDAI testnet.

200.freeze
GOERLI_OPTIMISM =

Chain ID for Optimistic Goerli testnet.

420.freeze
BAOBAB =

Chain ID for Klaytn testnet (Baobab)

1001
CYPRESS =

Chain ID for Klaytn mainmet (Cypress)

8217
RINKEBY_ARBITRUM =

Chain ID for Arbitrum Rinkeby testnet.

421611.freeze
SEPOLIA =

Chain ID for Sepolia testnet.

11155111.freeze
PRIVATE_GETH =

Chain ID for the geth private network preset.

1337.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.is_legacy?(v) ⇒ Boolean

Indicates wether the given v indicates a legacy chain value without EIP-155 replay protection.

Parameters:

  • v (Integer)

    the signature's v value.

Returns:

  • (Boolean)

    true if legacy value.



100
101
102
# File 'lib/klay/chain.rb', line 100

def is_legacy?(v)
  [27, 28].include? v
end

.to_chain_id(v) ⇒ Integer

Converst a v value into a chain ID. This does not work for legacy signatures with v < 36 that do not conform with EIP-155.

Parameters:

  • v (Integer)

    the signature's v value.

Returns:

  • (Integer)

    the chain id as per EIP-155 or nil if there is no replay protection.



150
151
152
153
154
155
# File 'lib/klay/chain.rb', line 150

def to_chain_id(v)
  return nil if v < 36
  chain_id = (v - 35) / 2
  return nil if chain_id < 1
  return chain_id
end

.to_recovery_id(v, chain_id = CYPRESS) ⇒ Integer

Convert a given v value to an ECDSA recovery id for the given EIP-155 chain ID.

Parameters:

  • v (Integer)

    the signature's v value.

  • chain_id (Integer) (defaults to: CYPRESS)

    the chain id the signature was generated on.

Returns:

  • (Integer)

    the recovery id corresponding to v.

Raises:



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/klay/chain.rb', line 111

def to_recovery_id(v, chain_id = CYPRESS)
  e = 0 + 2 * chain_id + 35
  i = 1 + 2 * chain_id + 35
  if [0, 1].include? v

    # some wallets are using a `v` of 0 or 1 (ledger)
    return v
  elsif is_legacy? v

    # this is the pre-EIP-155 legacy case
    return v - 27
  elsif [e, i].include? v

    # this is the EIP-155 case
    return v - 35 - 2 * chain_id
  else
    raise ReplayProtectionError, "Invalid v #{v} value for chain ID #{chain_id}. Invalid chain ID?"
  end
end

.to_v(recovery_id, chain_id = nil) ⇒ Integer

Converts a recovery ID into the expected v on a given chain.

Parameters:

  • recovery_id (Integer)

    signature recovery id.

  • chain_id (Integer) (defaults to: nil)

    the chain id the signature was generated on.

Returns:

  • (Integer)

    the signature's v value.



136
137
138
139
140
141
142
143
# File 'lib/klay/chain.rb', line 136

def to_v(recovery_id, chain_id = nil)
  if chain_id.nil? or chain_id < 1
    v = 27 + recovery_id
  else
    v = 2 * chain_id + 35 + recovery_id
  end
  return v
end

Instance Method Details

#is_legacy?(v) ⇒ Boolean

Indicates wether the given v indicates a legacy chain value without EIP-155 replay protection.

Parameters:

  • v (Integer)

    the signature's v value.

Returns:

  • (Boolean)

    true if legacy value.



100
101
102
# File 'lib/klay/chain.rb', line 100

def is_legacy?(v)
  [27, 28].include? v
end

#to_chain_id(v) ⇒ Integer

Converst a v value into a chain ID. This does not work for legacy signatures with v < 36 that do not conform with EIP-155.

Parameters:

  • v (Integer)

    the signature's v value.

Returns:

  • (Integer)

    the chain id as per EIP-155 or nil if there is no replay protection.



150
151
152
153
154
155
# File 'lib/klay/chain.rb', line 150

def to_chain_id(v)
  return nil if v < 36
  chain_id = (v - 35) / 2
  return nil if chain_id < 1
  return chain_id
end

#to_recovery_id(v, chain_id = CYPRESS) ⇒ Integer

Convert a given v value to an ECDSA recovery id for the given EIP-155 chain ID.

Parameters:

  • v (Integer)

    the signature's v value.

  • chain_id (Integer) (defaults to: CYPRESS)

    the chain id the signature was generated on.

Returns:

  • (Integer)

    the recovery id corresponding to v.

Raises:



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/klay/chain.rb', line 111

def to_recovery_id(v, chain_id = CYPRESS)
  e = 0 + 2 * chain_id + 35
  i = 1 + 2 * chain_id + 35
  if [0, 1].include? v

    # some wallets are using a `v` of 0 or 1 (ledger)
    return v
  elsif is_legacy? v

    # this is the pre-EIP-155 legacy case
    return v - 27
  elsif [e, i].include? v

    # this is the EIP-155 case
    return v - 35 - 2 * chain_id
  else
    raise ReplayProtectionError, "Invalid v #{v} value for chain ID #{chain_id}. Invalid chain ID?"
  end
end

#to_v(recovery_id, chain_id = nil) ⇒ Integer

Converts a recovery ID into the expected v on a given chain.

Parameters:

  • recovery_id (Integer)

    signature recovery id.

  • chain_id (Integer) (defaults to: nil)

    the chain id the signature was generated on.

Returns:

  • (Integer)

    the signature's v value.



136
137
138
139
140
141
142
143
# File 'lib/klay/chain.rb', line 136

def to_v(recovery_id, chain_id = nil)
  if chain_id.nil? or chain_id < 1
    v = 27 + recovery_id
  else
    v = 2 * chain_id + 35 + recovery_id
  end
  return v
end