Transaction signing, signing hashes, and sender recovery.
Example
iex> alias EEVM.Transaction.{FeeMarket, Signer}
iex> tx = %FeeMarket{max_priority_fee_per_gas: 1, max_fee_per_gas: 10, gas_limit: 21_000, to: 0xB0B}
iex> private_key = :binary.copy(<<0x46>>, 32)
iex> {:ok, signed} = Signer.sign(tx, private_key, EEVM.Config.new(:cancun, chain_id: 5))
iex> signed.chain_id
5
iex> {:ok, sender} = Signer.recover_sender(signed, 5)
iex> EEVM.hex(<<sender::160>>)
"0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f"
Summary
Functions
Returns the address of the secp256k1 private_key: the last 20 bytes of
the keccak256 hash of its uncompressed public key (Yellow Paper,
Appendix F).
Recover the authority (signer) of an EIP-7702 authorization tuple.
Recover the sender address, as an integer, from a transaction signed for
chain chain_id.
Signs tx with the 32-byte secp256k1 private_key for config's chain.
Compute the signing hash for a transaction.
Functions
@spec address(<<_::256>>) :: {:ok, EEVM.Transaction.address()} | {:error, :invalid_private_key}
Returns the address of the secp256k1 private_key: the last 20 bytes of
the keccak256 hash of its uncompressed public key (Yellow Paper,
Appendix F).
Returns {:error, :invalid_private_key} when the key is zero or not below
the curve order.
Example
iex> # The private key from the EIP-155 example.
iex> {:ok, address} = EEVM.Transaction.Signer.address(:binary.copy(<<0x46>>, 32))
iex> EEVM.hex(<<address::160>>)
"0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f"
@spec recover_authority(EEVM.Transaction.Authorization.t()) :: {:ok, EEVM.Transaction.address()} | {:error, atom()}
Recover the authority (signer) of an EIP-7702 authorization tuple.
The signed message is keccak256(0x05 || rlp([chain_id, address, nonce])).
Signatures with y_parity outside 0..1, r outside 1..n-1, or a
high s (EIP-2) are rejected with {:error, :invalid_signature}.
@spec recover_sender(EEVM.Transaction.t(), non_neg_integer()) :: {:ok, EEVM.Transaction.address()} | {:error, atom()}
Recover the sender address, as an integer, from a transaction signed for
chain chain_id.
A transaction signed for another chain fails with
{:error, :invalid_chain_id}, so it can't be replayed across chains: a
typed transaction's chain_id, or the chain id an EIP-155 legacy v
encodes, must equal chain_id. A pre-EIP-155 legacy transaction (v of
27 or 28) names no chain and is valid on any. Other legacy v values
fail with {:error, :invalid_v}.
@spec sign(EEVM.Transaction.t(), <<_::256>>, EEVM.Config.t()) :: {:ok, EEVM.Transaction.t()} | {:error, :invalid_private_key}
Signs tx with the 32-byte secp256k1 private_key for config's chain.
A legacy transaction is signed with EIP-155 replay protection, so its v
becomes chain_id * 2 + 35 + y_parity. A typed transaction whose
chain_id is nil takes the config's; one that already has a chain_id
keeps it. Any existing signature is replaced. Signatures are low-s
(EIP-2).
Returns {:ok, signed_tx}, or {:error, :invalid_private_key} when the
key is zero or not below the curve order. Raises ArgumentError naming
the field when a field has the wrong type, such as a hex string for to.
@spec signing_hash(EEVM.Transaction.t(), non_neg_integer()) :: binary()
Compute the signing hash for a transaction.
Raises ArgumentError naming the field when a field has the wrong type,
such as a hex string for to.