Docs

state_getStorage - Neuroweb RPC Method

Read a storage value by key on Neuroweb. Query account balances, pallet state, and any on-chain data using SCALE-encoded storage keys for decentralized knowledge graphs (DKG), verifiable AI, supply chain audits, and knowledge mining.

Returns the SCALE-encoded storage value for a given key on Neuroweb. Storage keys are constructed by hashing the pallet name and storage item name (and any map keys) using the hashing algorithms specified in the runtime metadata. This is the fundamental method for reading any on-chain state.

Why Neuroweb? Build on the decentralized AI blockchain powering 125M+ Knowledge Assets with MIT-awarded technology with OriginTrail DKG V8 with 500-1000x scalability, 40% of US imports secured, EVM compatibility, and Best Decentralized AI Project (MIT).

When to Use This Method

state_getStorage is essential for AI developers, knowledge graph builders, and teams requiring verifiable AI solutions:

  • Low-Level State Access -- Read the raw SCALE-encoded value stored under a known key on Neuroweb
  • Metadata-Aware Tooling -- Pair runtime metadata with raw storage reads when building custom indexers, explorers, or debugging tools
  • Historical State Queries -- Read storage values at a specific block hash to analyze state changes over time
  • Pallet Storage Inspection -- Inspect pallet state directly when higher-level client helpers are unavailable or too opinionated

Code Examples

Common Use Cases

1. Raw Storage Watcher

Query and track changes for a specific storage key over time:

JavaScript
import { ApiPromise, WsProvider } from '@polkadot/api';

async function monitorStorageKey(api, storageKey, intervalMs = 12000) {
  let previousValue = null;

  setInterval(async () => {
    const current = await api.rpc.state.getStorage(storageKey);
    const raw = current?.toHex() ?? null;

    if (previousValue !== null && raw !== previousValue) {
      console.log(`Storage value changed: ${previousValue} -> ${raw}`);
    }

    previousValue = raw;
  }, intervalMs);
}

2. Metadata-Aware Decode

Use a higher-level library to decode the value after you confirm the raw storage key:

JavaScript
async function decodeAccountStorage(api, address) {
  const storageKey = api.query.system.account.key(address);
  const raw = await api.rpc.state.getStorage(storageKey);
  const decoded = await api.query.system.account(address);

  return {
    storageKey: storageKey.toHex(),
    raw: raw?.toHex() ?? null,
    decoded: decoded.toJSON()
  };
}

3. Historical State Comparison

Compare storage values between two blocks to detect state transitions:

JavaScript
async function compareStateAtBlocks(api, storageQuery, params, blockHashA, blockHashB) {
  const [apiAtA, apiAtB] = await Promise.all([
    api.at(blockHashA),
    api.at(blockHashB)
  ]);

  // Navigate the nested query path (e.g., 'system.account')
  const parts = storageQuery.split('.');
  let queryA = apiAtA.query;
  let queryB = apiAtB.query;
  for (const part of parts) {
    queryA = queryA[part];
    queryB = queryB[part];
  }

  const [valueA, valueB] = await Promise.all([
    queryA(...params),
    queryB(...params)
  ]);

  const jsonA = valueA.toJSON();
  const jsonB = valueB.toJSON();

  console.log(`Block A: ${JSON.stringify(jsonA, null, 2)}`);
  console.log(`Block B: ${JSON.stringify(jsonB, null, 2)}`);

  return { before: jsonA, after: jsonB };
}

// Example: compare account state between two blocks
// compareStateAtBlocks(api, 'system.account', ['5GrwvaEF...'], blockHashOld, blockHashNew);

Storage Key Construction

For developers who need to construct storage keys manually (without a high-level library):

Storage TypeKey StructureExample
Valuexxhash128(Pallet) + xxhash128(Item)Timestamp.Now
Mapxxhash128(Pallet) + xxhash128(Item) + hasher(Key)System.Account(accountId)
Double Mapxxhash128(Pallet) + xxhash128(Item) + hasher1(Key1) + hasher2(Key2)Staking.ErasStakers(era, validatorId)

Common hashers used in Substrate:

  • Blake2_128Concat -- 16-byte Blake2b hash followed by the raw key (allows key enumeration)
  • Twox64Concat -- 8-byte xxhash followed by the raw key (faster, for trusted keys)
  • Identity -- Raw key with no hashing (used for already-unique keys)

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32603State not availableThe requested block's state may be pruned or unavailable on this node -- use an archive node for deep historical queries
-32602Invalid paramsVerify the storage key is a valid hex string with 0x prefix
-32005Rate limit exceededReduce request frequency or implement client-side rate limiting
null resultNo value at keyThis is not an error -- the storage key has no value (default state). Verify the key is correctly constructed

Important: Historical-state availability depends on the node's pruning configuration. Archive nodes retain full history, while pruned/full nodes may not serve older state.

  • state_getKeysPaged -- Enumerate storage keys matching a prefix (useful for iterating map entries)
  • state_queryStorageAt -- Query multiple storage keys at a specific block in a single request
  • state_getMetadata -- Get runtime metadata including storage definitions, types, and hashing algorithms
  • state_call -- Call runtime APIs for computed state that is not directly in storage
  • state_subscribeStorage -- Subscribe to storage changes in real time via WebSocket