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

Represents a V4 or EIP-7702 set-code transaction.

EIP-7702 transactions use transaction type `0x04` and extend the EIP-1559
field set with an authorization list. Each authorization entry is a
`{chain_id, address, nonce, y_parity, r, s}` tuple signed over
`0x05 || rlp([chain_id, address, nonce])`.

## Examples

    iex> use Cartouche.Hex
    iex> authorization = {
    ...>   1,
    ...>   ~h[0x0000000000000000000000000000000000000002],
    ...>   7,
    ...>   false,
    ...>   <<1::256>>,
    ...>   <<2::256>>
    ...> }
    iex> transaction =
    ...>   Cartouche.Transaction.V4.new(
    ...>     1,
    ...>     {1, :gwei},
    ...>     {100, :gwei},
    ...>     100_000,
    ...>     ~h[0x0000000000000000000000000000000000000001],
    ...>     {2, :wei},
    ...>     <<1, 2, 3>>,
    ...>     [],
    ...>     [authorization],
    ...>     :mainnet
    ...>   )
    ...>   |> Cartouche.Transaction.V4.add_signature(<<3::256, 4::256, 0>>)
    iex> {:ok, decoded} = transaction |> Cartouche.Transaction.V4.encode() |> Cartouche.Transaction.V4.decode()
    iex> decoded == transaction
    true

# `authorization`

```elixir
@type authorization() ::
  {non_neg_integer(), &lt;&lt;_::160&gt;&gt;, non_neg_integer(), boolean(), &lt;&lt;_::256&gt;&gt;,
   &lt;&lt;_::256&gt;&gt;}
```

# `authorization_input`

```elixir
@type authorization_input() ::
  authorization()
  | {non_neg_integer(), &lt;&lt;_::160&gt;&gt;, non_neg_integer(), nil, nil, nil}
```

# `t`

```elixir
@type t() :: %Cartouche.Transaction.V4{
  access_list: [{&lt;&lt;_::160&gt;&gt;, [&lt;&lt;_::256&gt;&gt;]}],
  amount: non_neg_integer(),
  authorization_list: [authorization()],
  chain_id: non_neg_integer(),
  data: binary(),
  destination: &lt;&lt;_::160&gt;&gt;,
  gas_limit: non_neg_integer(),
  max_fee_per_gas: non_neg_integer() | nil,
  max_priority_fee_per_gas: non_neg_integer() | nil,
  nonce: non_neg_integer(),
  signature_r: &lt;&lt;_::256&gt;&gt; | nil,
  signature_s: &lt;&lt;_::256&gt;&gt; | nil,
  signature_y_parity: boolean() | nil
}
```

# `tx_input`

```elixir
@type tx_input() ::
  t()
  | %Cartouche.Transaction.V4{
      access_list: list() | nil,
      amount: non_neg_integer() | nil,
      authorization_list: list() | nil,
      chain_id: non_neg_integer() | nil,
      data: binary() | nil,
      destination: &lt;&lt;_::160&gt;&gt; | nil,
      gas_limit: non_neg_integer() | nil,
      max_fee_per_gas: non_neg_integer() | nil,
      max_priority_fee_per_gas: non_neg_integer() | nil,
      nonce: non_neg_integer() | nil,
      signature_r: nil,
      signature_s: nil,
      signature_y_parity: nil
    }
```

# `unsigned_authorization`

```elixir
@type unsigned_authorization() :: {non_neg_integer(), &lt;&lt;_::160&gt;&gt;, non_neg_integer()}
```

# `add_authorization_signature`

```elixir
@spec add_authorization_signature(authorization_input(), &lt;&lt;_::520, _::_*8&gt;&gt;) ::
  authorization()
```

Adds an authorization signature from a packed binary (`r <> s <> v`).

# `add_signature`

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

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

# `authorization_hash`

```elixir
@spec authorization_hash(unsigned_authorization() | authorization()) :: &lt;&lt;_::256&gt;&gt;
```

Returns the EIP-7702 authorization signing hash.

# `authorization_signing_payload`

```elixir
@spec authorization_signing_payload(unsigned_authorization() | authorization()) ::
  binary()
```

Returns the EIP-7702 authorization signing payload.

# `decode`

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

Decode an RLP-encoded EIP-7702 transaction.

# `encode`

```elixir
@spec encode(tx_input()) :: binary()
```

Build an RLP-encoded EIP-7702 transaction.

# `get_authorization_signature`

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

Returns a packed authorization signature (`r <> s <> y_parity`).

# `get_signature`

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

Recovers a packed outer transaction signature (`r <> s <> y_parity`).

# `hash`

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

Returns the transaction hash for signed or unsigned encoded bytes.

# `new`

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

Constructs an unsigned EIP-7702 transaction.

# `recover_authority`

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

Recovers the EOA that signed an authorization tuple.

# `recover_signer`

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

Recovers the signer from a signed EIP-7702 transaction.

# `sign`

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

Signs the outer EIP-7702 transaction.

# `sign_authorization`

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

Signs an EIP-7702 authorization tuple.

# `signing_payload`

```elixir
@spec signing_payload(t()) :: binary()
```

Returns the outer transaction signing payload.

---

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