# `Cartouche.Transaction.V3`
[🔗](https://github.com/zenhive/cartouche/blob/main/lib/cartouche/transaction/v3.ex#L1)

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

# `access_list`

```elixir
@type access_list() :: [{&lt;&lt;_::160&gt;&gt;, [&lt;&lt;_::256&gt;&gt;]}]
```

# `t`

```elixir
@type t() :: %Cartouche.Transaction.V3{
  access_list: access_list(),
  amount: integer(),
  blob_versioned_hashes: [&lt;&lt;_::256&gt;&gt;],
  chain_id: integer(),
  data: binary(),
  destination: &lt;&lt;_::160&gt;&gt; | 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: &lt;&lt;_::256&gt;&gt; | nil,
  signature_s: &lt;&lt;_::256&gt;&gt; | nil,
  signature_y_parity: boolean() | nil
}
```

# `add_signature`

```elixir
@spec add_signature(t(), &lt;&lt;_::512, _::_*8&gt;&gt;) :: t()
```

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

# `add_signature`

```elixir
@spec add_signature(t(), boolean(), &lt;&lt;_::256&gt;&gt;, &lt;&lt;_::256&gt;&gt;) :: t()
```

Adds explicit signature fields to a transaction.

# `decode`

```elixir
@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`

```elixir
@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`

```elixir
@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`

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

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

# `hash`

```elixir
@spec hash(t()) :: &lt;&lt;_::256&gt;&gt;
```

Hashes the typed transaction bytes.

# `new`

```elixir
@spec new(
  integer(),
  integer() | {integer(), :wei | :gwei} | nil,
  integer() | {integer(), :wei | :gwei} | nil,
  integer(),
  &lt;&lt;_::160&gt;&gt;,
  integer() | {integer(), :wei | :gwei},
  binary(),
  access_list(),
  integer() | {integer(), :wei | :gwei} | nil,
  [&lt;&lt;_::256&gt;&gt;],
  atom() | integer() | nil
) :: t()
```

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

# `recover_signer`

```elixir
@spec recover_signer(t()) :: {:ok, &lt;&lt;_::160&gt;&gt;} | {:error, String.t()}
```

Recovers the signer from a signed V3 transaction.

# `sign`

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

Signs a V3 transaction with the given signer process.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
