Module: Eth::Chain

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

Overview

Encapsulates Chain IDs and utilities for EIP-155 compatibility. Ref: 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
CRONOS =

Chain ID for Cronos mainnet.

25.freeze
RSK =

Chain ID for Rootstock mainnet.

30.freeze
BNB =

Chain ID for BNB Smart Chain mainnet.

56.freeze
CLASSIC =

Chain ID for Ethereum Classic mainnet.

61.freeze
POA_NET =

Chain ID for POA Network mainnet.

99.freeze
XDAI =

Chain ID for xDAI mainnet (now Gnosis Chain).

100.freeze
GNOSIS =

Chain ID for Gnosis mainnet (formerly xDAI).

XDAI.freeze
MATIC =

Chain ID for the Matic mainnet (now Polygon).

137.freeze
POLYGON =

Chain ID for the Polygon mainnet (formerly Matic).

MATIC.freeze
FILECOIN =

Chain ID for Filecoin mainnet.

314.freeze
CRONOS_ZK =

Chain ID for the Cronos zkEVM chain.

388.freeze
REDSTONE =

Chain ID for Redstone Optimistic Rollup.

690.freeze
POLYGON_ZK =

Chain ID for the Polygon zkEVM.

1101.freeze
LISK =

Chain ID for the Lisk layer 2.

1135.freeze
MOONBEAM =

Chain ID for Moonbeam

1284.freeze
BASE =

Chain ID for Base mainnet.

8453.freeze
EVMOS =

Chain ID for the EVMOS mainnet.

9001.freeze
CELO =

Chain ID for the Celo layer 2.

42220.freeze
ARBITRUM =

Chain ID for Arbitrum One mainnet.

42161.freeze
AVALANCHE =

Chain ID for Avalance C-Chain mainnet.

43114.freeze
LINEA =

Chain ID for Linea mainnet.

59144.freeze
SCROLL =

Chain ID for the Scroll layer 2.

534352.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 Optimistm Kovan testnet.

69.freeze
XDAI_ARBITRUM =

Chain ID for Arbitrum xDAI testnet.

200.freeze
GOERLI_OPTIMISM =

Chain ID for Optimistic Goerli testnet.

420.freeze
MOONRIVER =

Chain ID for Moonriver testnet

1285.freeze
MOONBASE =

Chain ID for Moonbase alpha

1287.freeze
GARNET =

Chain ID for the Garnet Holesky testnet

17069.freeze
MUMBAI =

Chain ID for the Polygon Mumbai testnet.

80001.freeze
RINKEBY_ARBITRUM =

Chain ID for Arbitrum Rinkeby testnet.

421611.freeze
GOERLI_ARBITRUM =

Chain ID for Arbitrum Goerli testnet.

421613.freeze
HOODI =

Chain ID for Hoodi testnet.

560048.freeze
SEPOLIA =

Chain ID for Sepolia testnet.

11155111.freeze
HOLESOVICE =

Chain ID for Holesovice testnet.

11166111.freeze
HOLESKY =

Chain ID for Holesovice testnet.

HOLESOVICE
PRIVATE_GETH =

Chain ID for the geth private network preset.

1337.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ledger?(v) ⇒ Boolean

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

Parameters:

  • v (Integer)

    the signature’s v value.

Returns:

  • (Boolean)

    true if ledger’s legacy value.



172
173
174
# File 'lib/eth/chain.rb', line 172

def ledger?(v)
  [0, 1].include? v
end

.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.



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

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

.to_chain_id(v) ⇒ Integer

Converts 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.



231
232
233
234
235
236
# File 'lib/eth/chain.rb', line 231

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 = ETHEREUM) ⇒ 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: ETHEREUM)

    the chain id the signature was generated on.

Returns:

  • (Integer)

    the recovery id corresponding to v.

Raises:



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/eth/chain.rb', line 192

def to_recovery_id(v, chain_id = ETHEREUM)
  e = 0 + 2 * chain_id + 35
  i = 1 + 2 * chain_id + 35
  if ledger? v

    # some wallets are using a `v` of 0 or 1 (ledger)
    return v
  elsif 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.



217
218
219
220
221
222
223
224
# File 'lib/eth/chain.rb', line 217

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

#ledger?(v) ⇒ Boolean

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

Parameters:

  • v (Integer)

    the signature’s v value.

Returns:

  • (Boolean)

    true if ledger’s legacy value.



172
173
174
# File 'lib/eth/chain.rb', line 172

def ledger?(v)
  [0, 1].include? v
end

#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.



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

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

#to_chain_id(v) ⇒ Integer

Converts 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.



231
232
233
234
235
236
# File 'lib/eth/chain.rb', line 231

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 = ETHEREUM) ⇒ 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: ETHEREUM)

    the chain id the signature was generated on.

Returns:

  • (Integer)

    the recovery id corresponding to v.

Raises:



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/eth/chain.rb', line 192

def to_recovery_id(v, chain_id = ETHEREUM)
  e = 0 + 2 * chain_id + 35
  i = 1 + 2 * chain_id + 35
  if ledger? v

    # some wallets are using a `v` of 0 or 1 (ledger)
    return v
  elsif 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.



217
218
219
220
221
222
223
224
# File 'lib/eth/chain.rb', line 217

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