Skip to main content
Serializes BrandedStorageKey to string format for use as JavaScript Map keys or persistent storage.

Signature

    Parameters

    • key (BrandedStorageKey) - Storage key to serialize

    Returns

    string - String format: "address:slot" with lowercase hex address (no 0x prefix) and decimal slot

    Format

    <address>:<slot>
    
    • address: Lowercase 40-character hex string (no 0x prefix)
    • slot: Decimal string representation of bigint slot number

    Examples

    Basic Usage

      Various Slot Numbers

      import * as State from 'tevm/State';
      
      const addr = Address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
      
      // Slot 0
      const key0 = State.StorageKey(addr, 0n);
      console.log(State.StorageKey.toString(key0));
      // "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:0"
      
      // Slot 42
      const key42 = State.StorageKey(addr, 42n);
      console.log(State.StorageKey.toString(key42));
      // "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:42"
      
      // Large slot (computed mapping slot)
      const largeSlot = 123456789012345678901234567890n;
      const keyLarge = State.StorageKey(addr, largeSlot);
      console.log(State.StorageKey.toString(keyLarge));
      // "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:123456789012345678901234567890"
      

      Map Keys

      import * as State from 'tevm/State';
      
      // Use string keys in Map
      const storage = new Map<string, bigint>();
      
      const key1 = State.StorageKey(contractAddr, 0n);
      const key2 = State.StorageKey(contractAddr, 1n);
      
      // Serialize for map keys
      storage.set(State.StorageKey.toString(key1), 1000000000n);
      storage.set(State.StorageKey.toString(key2), 2000000000n);
      
      // Retrieve values
      const value1 = storage.get(State.StorageKey.toString(key1)); // 1000000000n
      const value2 = storage.get(State.StorageKey.toString(key2)); // 2000000000n
      

      Persistent Storage

      import * as State from 'tevm/State';
      import * as fs from 'fs/promises';
      
      // Serialize storage to JSON
      async function saveStorage(
        storage: Map<BrandedStorageKey, bigint>,
        filePath: string
      ): Promise<void> {
        const entries = Array(storage.entries()).map(([key, value]) => ({
          key: State.StorageKey.toString(key),
          value: value.toString()
        }));
      
        await fs.writeFile(filePath, JSON.stringify(entries, null, 2));
      }
      
      // Example usage
      const storage = new Map<BrandedStorageKey, bigint>();
      storage.set(State.StorageKey(contractAddr, 0n), 1000n);
      storage.set(State.StorageKey(contractAddr, 1n), 2000n);
      
      await saveStorage(storage, './storage.json');
      
      // storage.json:
      // [
      //   {
      //     "key": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:0",
      //     "value": "1000"
      //   },
      //   {
      //     "key": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:1",
      //     "value": "2000"
      //   }
      // ]
      

      Database Keys

      import * as State from 'tevm/State';
      
      class StorageDatabase {
        async set(key: BrandedStorageKey, value: bigint): Promise<void> {
          const keyStr = State.StorageKey.toString(key);
          await db.put(`storage:${keyStr}`, value.toString());
        }
      
        async get(key: BrandedStorageKey): Promise<bigint | null> {
          const keyStr = State.StorageKey.toString(key);
          const value = await db.get(`storage:${keyStr}`);
          return value ? BigInt(value) : null;
        }
      
        async delete(key: BrandedStorageKey): Promise<void> {
          const keyStr = State.StorageKey.toString(key);
          await db.delete(`storage:${keyStr}`);
        }
      }
      

      Logging and Debugging

      import * as State from 'tevm/State';
      
      function logStorageChange(
        key: BrandedStorageKey,
        oldValue: bigint,
        newValue: bigint
      ): void {
        const keyStr = State.StorageKey.toString(key);
        console.log(`Storage changed: ${keyStr}`);
        console.log(`  Old: ${oldValue}`);
        console.log(`  New: ${newValue}`);
      }
      
      const key = State.StorageKey(contractAddr, 0n);
      logStorageChange(key, 1000n, 2000n);
      // Storage changed: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48:0
      //   Old: 1000
      //   New: 2000
      

      Round-Trip Conversion

      import * as State from 'tevm/State';
      
      // Serialize
      const originalKey = State.StorageKey(contractAddr, 42n);
      const keyStr = State.StorageKey.toString(originalKey);
      
      // Deserialize
      const parsedKey = State.StorageKey(keyStr);
      
      // Verify equality
      console.log(State.StorageKey.equals(originalKey, parsedKey)); // true
      

      Performance Considerations

      String serialization is fast but creates new string objects:
      import * as State from 'tevm/State';
      
      // Cache serialized keys if used frequently
      const keyCache = new Map<BrandedStorageKey, string>();
      
      function getCachedKeyString(key: BrandedStorageKey): string {
        let cached = keyCache.get(key);
        if (!cached) {
          cached = State.StorageKey.toString(key);
          keyCache.set(key, cached);
        }
        return cached;
      }
      
      // Use cached version
      const key = State.StorageKey(contractAddr, 0n);
      const keyStr1 = getCachedKeyString(key); // Serializes
      const keyStr2 = getCachedKeyString(key); // Returns cached
      console.log(keyStr1 === keyStr2); // true (same string object)