Cartouche.Transaction.V3 (Cartouche v0.2.2)

Copy Markdown View Source

Represents a V3 or EIP-4844 blob transaction.

This module encodes the execution-layer transaction envelope only. Blob sidecars (blobs, KZG commitments, and KZG proofs) are propagated separately and are not part of the canonical signed transaction bytes.

Examples

iex> tx =
...>   Cartouche.Transaction.V3.new(
...>     1,
...>     {1, :gwei},
...>     {100, :gwei},
...>     100_000,
...>     <<1::160>>,
...>     {2, :wei},
...>     <<1, 2, 3>>,
...>     [],
...>     {1, :wei},
...>     [<<1, 0::248>>],
...>     :goerli
...>   )
...> tx = Cartouche.Transaction.V3.add_signature(tx, true, <<0x01::256>>, <<0x02::256>>)
iex> {:ok, decoded} = tx |> Cartouche.Transaction.V3.encode() |> Cartouche.Transaction.V3.decode()
iex> decoded == tx
true

Summary

Functions

Adds a signature to a transaction from a packed binary (r <> s <> v).

Adds explicit signature fields to a transaction.

Decode an EIP-4844 blob transaction envelope.

Build an EIP-2718 typed RLP-encoded blob transaction.

Decodes an EIP-4844 (type 3) blob transaction object as returned in the transactions array of eth_getBlockByNumber / eth_getBlockByHash when include_transaction_details: true is requested.

Recovers a signature from a transaction, if it has been signed.

Hashes the typed transaction bytes.

Recovers the signer from a signed V3 transaction.

Signs a V3 transaction with the given signer process.

Types

access_list()

@type access_list() :: [{<<_::160>>, [<<_::256>>]}]

t()

@type t() :: %Cartouche.Transaction.V3{
  access_list: access_list(),
  amount: integer(),
  blob_versioned_hashes: [<<_::256>>],
  chain_id: integer(),
  data: binary(),
  destination: <<_::160>> | nil,
  gas_limit: integer(),
  max_fee_per_blob_gas: integer(),
  max_fee_per_gas: integer(),
  max_priority_fee_per_gas: integer(),
  nonce: integer(),
  signature_r: <<_::256>> | nil,
  signature_s: <<_::256>> | nil,
  signature_y_parity: boolean() | nil
}

Functions

add_signature(transaction, arg)

@spec add_signature(t(), <<_::512, _::_*8>>) :: t()

Adds a signature to a transaction from a packed binary (r <> s <> v).

add_signature(transaction, v, r, s)

@spec add_signature(t(), boolean(), <<_::256>>, <<_::256>>) :: t()

Adds explicit signature fields to a transaction.

decode(arg1)

@spec decode(binary()) :: {:ok, t()} | {:error, String.t()}

Decode an EIP-4844 blob transaction envelope.

Accepts both signed transaction bytes and unsigned signing preimages. Unsigned payloads omit signature_y_parity, signature_r, and signature_s; the decoded struct sets those fields to nil.

encode(transaction)

@spec encode(t()) :: binary()

Build an EIP-2718 typed RLP-encoded blob transaction.

If any signature field is nil, the encoded payload omits signature_y_parity, signature_r, and signature_s and can be used as the signing preimage.

from_json(params)

@spec from_json(map()) :: t() | no_return()

Decodes an EIP-4844 (type 3) blob transaction object as returned in the transactions array of eth_getBlockByNumber / eth_getBlockByHash when include_transaction_details: true is requested.

Mirrors Cartouche.Transaction.V2.from_json/1 plus maxFeePerBlobGas and blobVersionedHashes (the blob sidecar — blobs/commitments/proofs — is propagated separately and is not part of the block JSON).

Examples

iex> use Cartouche.Hex
iex> %{
...>   "type" => "0x3",
...>   "chainId" => "0x1",
...>   "nonce" => "0x1",
...>   "maxPriorityFeePerGas" => "0x3b9aca00",
...>   "maxFeePerGas" => "0x174876e800",
...>   "gas" => "0x186a0",
...>   "to" => "0x0000000000000000000000000000000000000001",
...>   "value" => "0x2",
...>   "input" => "0x010203",
...>   "accessList" => [],
...>   "maxFeePerBlobGas" => "0x1",
...>   "blobVersionedHashes" => [
...>     "0x0100000000000000000000000000000000000000000000000000000000000000"
...>   ],
...>   "yParity" => "0x1",
...>   "r" => "0x1",
...>   "s" => "0x2"
...> }
...> |> Cartouche.Transaction.V3.from_json()
...> |> Map.take([:chain_id, :destination, :max_fee_per_blob_gas, :blob_versioned_hashes, :signature_y_parity])
%{
  chain_id: 1,
  destination: ~h[0x0000000000000000000000000000000000000001],
  max_fee_per_blob_gas: 1,
  blob_versioned_hashes: [
    ~h[0x0100000000000000000000000000000000000000000000000000000000000000]
  ],
  signature_y_parity: true
}

get_signature(v3)

@spec get_signature(t()) :: {:ok, binary()} | {:error, String.t()}

Recovers a signature from a transaction, if it has been signed.

hash(transaction)

@spec hash(t()) :: <<_::256>>

Hashes the typed transaction bytes.

new(nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes, chain_id \\ nil)

@spec new(
  integer(),
  integer() | {integer(), :wei | :gwei} | nil,
  integer() | {integer(), :wei | :gwei} | nil,
  integer(),
  <<_::160>>,
  integer() | {integer(), :wei | :gwei},
  binary(),
  access_list(),
  integer() | {integer(), :wei | :gwei} | nil,
  [<<_::256>>],
  atom() | integer() | nil
) :: t()

Constructs a new V3 (EIP-4844) Ethereum transaction.

recover_signer(transaction)

@spec recover_signer(t()) :: {:ok, <<_::160>>} | {:error, String.t()}

Recovers the signer from a signed V3 transaction.

sign(transaction, signer \\ Default)

@spec sign(t(), GenServer.name()) :: {:ok, t()} | {:error, String.t()}

Signs a V3 transaction with the given signer process.