> ## Documentation Index
> Fetch the complete documentation index at: https://hedera-0c6e0218-add-json-rpc-release-notes.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a HookStore Transaction

The `HookStoreTransaction` enables efficient, low-overhead management of an EVM Hook's persistent storage. This transaction allows hook owners to add, update, or remove key/value pairs in the hook's storage without executing the hook's bytecode—significantly more cost-effective and faster than using a `ContractCall`.

***

## Transaction Properties

| Field               | Description                                                                                                                                                    |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Hook ID**         | The unique identifier of the EVM Hook whose storage is being updated, including the owning entity (Account or Contract) and the hook's 64-bit ID.              |
| **Storage Updates** | A list of updates to the hook's persistent storage. Supports direct slot updates (`EvmHookStorageSlot`) or Solidity mapping updates (`EvmHookMappingEntries`). |

***

## When to Use This Transaction

Use `HookStoreTransaction` when you need to:

* Initialize storage slots on a newly created hook
* Update configuration variables (e.g., whitelist, passcode hash) in an existing hook's storage
* Delete storage entries by setting their value to an empty byte array

***

## Transaction Signing Requirements

The signing requirements depend on if an `adminKey` was set when the hook was created:

* **If the hook has an `adminKey`**: Either the Admin Key OR the hook owner (account or contract that owns the hook) must sign the transaction
* **If the hook does NOT have an `adminKey`**: The hook owner (account or contract that owns the hook) must sign the transaction
* **In all cases**: The account paying the transaction fee must also sign

***

## Methods

| Method                         | Type                         | Description                                                                                                                               |
| :----------------------------- | :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
| `setHookId(<HookId>)`          | `HookId`                     | **Required.** Sets the unique identifier of the EVM Hook whose storage is being updated.                                                  |
| `addStorageUpdate(<update>)`   | `EvmHookStorageUpdate`       | **Optional.** Adds a single storage update (slot or mapping entry) to the transaction.                                                    |
| `setStorageUpdates(<updates>)` | `list<EvmHookStorageUpdate>` | **Optional.** Sets the full list of storage updates for the transaction.                                                                  |
| `getHookId()`                  | `HookId`                     | Returns the hook ID for this transaction. In JavaScript, use the `.hookId` property accessor instead of calling `getHookId()`.            |
| `getStorageUpdates()`          | `list<EvmHookStorageUpdate>` | Returns the list of storage updates. In JavaScript, use the `.storageUpdates` property accessor instead of calling `getStorageUpdates()`. |

<Note>
  `EvmHookStorageUpdate` is an abstract class with two concrete implementations: `EvmHookStorageSlot` for direct slot updates and `EvmHookMappingEntries` for updating entries within a Solidity mapping. See [Create and Manage Hooks](/hedera/sdks-and-apis/sdks/accounts-and-hbar/create-and-manage-hooks) for full property details on both types.
</Note>

***

## Examples

### Example 1: Updating a Hook's Storage Slot

This example demonstrates how to update a single storage slot on a hook with ID `1002` owned by `accountId`.

<CodeGroup>
  ```java Java theme={null}
  import com.hedera.hashgraph.sdk.HookStoreTransaction;
  import com.hedera.hashgraph.sdk.HookId;
  import com.hedera.hashgraph.sdk.HookEntityId;
  import com.hedera.hashgraph.sdk.EvmHookStorageUpdate;

  // Assume these variables are defined:
  // AccountId accountId = AccountId.fromString("0.0.1000");
  // PrivateKey adminKey = PrivateKey.fromString("..."); // The hook's admin key

  // 1. Define the target hook ID
  HookId hookIdObj = new HookId(new HookEntityId(accountId), 1002L);

  // 2. Define the new storage update (slot 0x01 → value 0x02)
  byte[] key = new byte[32];
  key[0] = 0x01;
  byte[] value = new byte[32];
  value[0] = 0x02;

  EvmHookStorageUpdate.EvmHookStorageSlot storageUpdate =
      new EvmHookStorageUpdate.EvmHookStorageSlot(key, value);

  // 3. Create and execute the HookStoreTransaction
  HookStoreTransaction hookStoreTx = new HookStoreTransaction()
      .setHookId(hookIdObj)
      .addStorageUpdate(storageUpdate)
      .freezeWith(client)
      .sign(adminKey); // Must be signed by the hook's admin key

  TransactionResponse result = hookStoreTx.execute(client);
  System.out.println("HookStoreTransaction executed with ID: " + result.transactionId);
  ```

  ```javascript JavaScript theme={null}
  import {
      HookStoreTransaction,
      HookId,
      HookEntityId,
      EvmHookStorageSlot,
      Long,
  } from "@hiero-ledger/sdk";

  // Assume these variables are defined:
  // const accountId = AccountId.fromString("0.0.1000");
  // const adminKey = PrivateKey.fromString("..."); // The hook's admin key

  // 1. Define the target hook ID
  const hookIdObj = new HookId()
      .setEntityId(new HookEntityId().setAccountId(accountId))
      .setHookId(Long.fromInt(1002));

  // 2. Define the new storage update (slot 0x01 → value 0x02)
  const storageUpdate = new EvmHookStorageSlot()
      .setKey(new Uint8Array([0x01, ...new Array(31).fill(0)]))
      .setValue(new Uint8Array([0x02, ...new Array(31).fill(0)]));

  // 3. Create and execute the HookStoreTransaction
  const hookStoreTx = new HookStoreTransaction()
      .setHookId(hookIdObj)
      .addStorageUpdate(storageUpdate)
      .freezeWith(client)
      .sign(adminKey); // Must be signed by the hook's admin key

  const result = await hookStoreTx.execute(client);
  console.log(`HookStoreTransaction executed with ID: ${result.transactionId}`);
  ```

  ```go Go theme={null}
  import (
      "fmt"
      "encoding/hex"

      hedera "github.com/hiero-ledger/hiero-sdk-go/v2/sdk"
  )

  // Assume these variables are defined:
  // var client *client.Client // e.g., client.ClientForTestnet()
  // var accountID account.AccountID // e.g., account.AccountID{Shard: 0, Realm: 0, Account: 1000}
  // var adminKey *crypto.PrivateKey // The hook's admin key

  // 1. Define the target hook ID
  hookID := hedera.NewHookId(
      *hedera.NewHookEntityIdWithAccountId(accountID),
      1002,
  )

  // 2. Define the new storage update
  // We are updating storage slot 0x01 with a new value (0x02)
  key, _ := hex.DecodeString("0100000000000000000000000000000000000000000000000000000000000000")
  value, _ := hex.DecodeString("0200000000000000000000000000000000000000000000000000000000000000")

  storageSlot := hedera.NewEvmHookStorageSlot().
      SetKey(key).
      SetValue(value)

  // 3. Create and execute the HookStoreTransaction
  hookStoreTx := hedera.NewHookStoreTransaction().
      SetHookId(*hookID).
      AddStorageUpdate(storageSlot).
      FreezeWith(client)

  // Must be signed by the hook's admin key
  response, err := hookStoreTx.Sign(adminKey).Execute(client)
  if err != nil {
      // Handle error
  }

  // Get the receipt
  receipt, err := response.GetReceipt(client)
  if err != nil {
      // Handle error
  }

  fmt.Printf("HookStoreTransaction executed with status: %v\n", receipt.Status)
  ```
</CodeGroup>

***

### Example 2: Updating a Solidity Mapping Entry

This example demonstrates how to update an entry within a Solidity mapping stored in the hook's storage. This requires calculating the storage slot key based on the mapping key and the mapping's storage slot.

<CodeGroup>
  ```java Java theme={null}
  import com.hedera.hashgraph.sdk.HookStoreTransaction;
  import com.hedera.hashgraph.sdk.HookId;
  import com.hedera.hashgraph.sdk.HookEntityId;
  import com.hedera.hashgraph.sdk.EvmHookStorageUpdate;
  import com.hedera.hashgraph.sdk.EvmHookMappingEntry;
  import java.util.List;

  // Assume these variables are defined:
  // AccountId accountId = AccountId.fromString("0.0.1000");
  // PrivateKey adminKey = PrivateKey.fromString("..."); // The hook's admin key

  // 1. Define the target hook ID
  HookId hookIdObj = new HookId(new HookEntityId(accountId), 1002L);

  // 2. Define the mapping update
  // We are updating a mapping at Solidity storage slot 0x02.
  // The mapping key is an address (0x...1234) and the new value is a boolean (true).

  // Mapping Key (e.g., an address)
  byte[] mappingKey = new byte[32];
  mappingKey[31] = 0x34;
  mappingKey[30] = 0x12;

  // Mapping Slot (Solidity slot 2)
  byte[] mappingSlot = new byte[32];
  mappingSlot[31] = 0x02;

  // New Value (e.g., a boolean 'true' which is 1)
  byte[] newValue = new byte[32];
  newValue[31] = 0x01;

  // Create the mapping entry
  EvmHookMappingEntry mappingEntry = EvmHookMappingEntry.ofKey(mappingKey, newValue);

  // Create the mapping update
  EvmHookStorageUpdate.EvmHookMappingEntries storageUpdate =
      new EvmHookStorageUpdate.EvmHookMappingEntries(
          mappingSlot,
          List.of(mappingEntry)
      );

  // 3. Create and execute the HookStoreTransaction
  HookStoreTransaction hookStoreTx = new HookStoreTransaction()
      .setHookId(hookIdObj)
      .addStorageUpdate(storageUpdate)
      .freezeWith(client)
      .sign(adminKey); // Must be signed by the hook's admin key

  TransactionResponse result = hookStoreTx.execute(client);
  System.out.println("HookStoreTransaction executed with ID: " + result.transactionId);
  ```

  ```javascript JavaScript theme={null}
  import {
      HookStoreTransaction,
      HookId,
      HookEntityId,
      EvmHookMappingEntries,
      EvmHookMappingEntry,
      Long,
  } from "@hiero-ledger/sdk";

  // Assume these variables are defined:
  // const accountId = AccountId.fromString("0.0.1000");
  // const adminKey = PrivateKey.fromString("..."); // The hook's admin key

  // 1. Define the target hook ID
  const hookIdObj = new HookId()
      .setEntityId(new HookEntityId().setAccountId(accountId))
      .setHookId(Long.fromInt(1002));

  // 2. Define the mapping update
  // We are updating a mapping at Solidity storage slot 0x02.
  // The mapping key is an address (0x...1234) and the new value is a boolean (true).

  // Mapping Key (e.g., an address)
  const mappingKey = new Uint8Array(32).fill(0);
  mappingKey[31] = 0x34;
  mappingKey[30] = 0x12;

  // Mapping Slot (Solidity slot 2)
  const mappingSlot = new Uint8Array(32).fill(0);
  mappingSlot[31] = 0x02;

  // New Value (e.g., a boolean 'true' which is 1)
  const newValue = new Uint8Array(32).fill(0);
  newValue[31] = 0x01;

  // Create the mapping entry
  const mappingEntry = new EvmHookMappingEntry()
      .setKey(mappingKey)
      .setValue(newValue);

  // Create the mapping update
  const storageUpdate = new EvmHookMappingEntries()
      .setMappingSlot(mappingSlot)
      .setEntries([mappingEntry]);

  // 3. Create and execute the HookStoreTransaction
  const hookStoreTx = new HookStoreTransaction()
      .setHookId(hookIdObj)
      .addStorageUpdate(storageUpdate)
      .freezeWith(client)
      .sign(adminKey); // Must be signed by the hook's admin key

  const result = await hookStoreTx.execute(client);
  console.log(`HookStoreTransaction executed with ID: ${result.transactionId}`);
  ```

  ```go Go theme={null}
  import (
      "fmt"

      hedera "github.com/hiero-ledger/hiero-sdk-go/v2/sdk"
  )

  // Assume these variables are defined:
  // var client *client.Client // e.g., client.ClientForTestnet()
  // var accountID account.AccountID // e.g., account.AccountID{Shard: 0, Realm: 0, Account: 1000}
  // var adminKey *crypto.PrivateKey // The hook's admin key

  // 1. Define the target hook ID
  hookID := hedera.NewHookId(
      *hedera.NewHookEntityIdWithAccountId(accountID),
      1002,
  )

  // 2. Define the mapping update
  // We are updating a mapping at Solidity storage slot 0x02.
  // The mapping key is an address (0x...1234) and the new value is a boolean (true).

  // Mapping Key (e.g., an address)
  mappingKey := make([]byte, 32)
  mappingKey[31] = 0x34
  mappingKey[30] = 0x12

  // Mapping Slot (Solidity slot 2)
  mappingSlot := make([]byte, 32)
  mappingSlot[31] = 0x02

  // New Value (e.g., a boolean 'true' which is 1)
  mappingValue := make([]byte, 32)
  mappingValue[31] = 0x01

  // Create the mapping entry
  mappingEntry := hedera.NewEvmHookMappingEntryWithKey(mappingKey, mappingValue)

  mappingEntries := hedera.NewEvmHookMappingEntries().
      SetMappingSlot(mappingSlot).
      AddMappingEntry(*mappingEntry)

  // 3. Create and execute the HookStoreTransaction
  hookStoreTx := hedera.NewHookStoreTransaction().
      SetHookId(*hookID).
      AddStorageUpdate(mappingEntries).
      FreezeWith(client)

  // Must be signed by the hook's admin key
  response, err := hookStoreTx.Sign(adminKey).Execute(client)
  if err != nil {
      // Handle error
  }

  // Get the receipt
  receipt, err := response.GetReceipt(client)
  if err != nil {
      // Handle error
  }

  fmt.Printf("HookStoreTransaction executed with status: %v\n", receipt.Status)
  ```
</CodeGroup>
