Docs
Centrifuge

state_getKeys - JSON-RPC Method

Get storage keys matching a prefix in Centrifuge via JSON-RPC. Query multiple storage entries efficiently.

Description

Returns storage keys that match a given prefix. This JSON-RPC method is useful for discovering all storage entries under a specific module or querying multiple related storage items. Be cautious with broad prefixes as they may return large result sets.

Request Parameters

Request
prefixstring

Hex-encoded storage key prefix to match

blockHashstring

Block hash to query at. If omitted, uses the latest block

Response Body

Response
resultarray

Array of hex-encoded storage keys matching the prefix

Request Example

JSON
{
  "jsonrpc": "2.0",
  "method": "state_getKeys",
  "params": [
    "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9"
  ],
  "id": 1
}

Code Examples

Python
import requests
import json
from substrateinterface import SubstrateInterface

def get_storage_keys(prefix, block_hash=None):
    url = "https://api-centrifuge.n.dwellir.com"
    headers = {
        "Content-Type": "application/json"
    }
    
    params = [prefix, block_hash] if block_hash else [prefix]
    
    payload = {
        "jsonrpc": "2.0",
        "method": "state_getKeys",
        "params": params,
        "id": 1
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    return response.json()["result"]

# Example: Get all validator preferences keys
def get_validator_keys():
    # Staking.Validators storage prefix
    prefix = "0x5f3e4907f716ac89b6347d15ececedca9320c2dc4f5d7af5b320b04e2d1a3ff3"
    keys = get_storage_keys(prefix)
    
    print(f"Found {len(keys)} validator preference entries")
    
    for key in keys:
        # Extract validator account from key
        validator_account = key[-64:]
        print(f"Validator: 0x{validator_account}")
    
    return keys

# Example: Query all keys under a module
def get_module_keys(module_prefix):
    keys = get_storage_keys(module_prefix)
    
    # Group keys by storage item
    storage_items = {}
    for key in keys:
        # Storage keys typically have a fixed prefix per item
        item_prefix = key[:66]  # First 33 bytes (66 hex chars)
        if item_prefix not in storage_items:
            storage_items[item_prefix] = []
        storage_items[item_prefix].append(key)
    
    return storage_items
JavaScript
const getStorageKeys = async (prefix, blockHash = null) => {
  const params = blockHash ? [prefix, blockHash] : [prefix];
  
  const response = await fetch('https://api-centrifuge.n.dwellir.com', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'state_getKeys',
      params: params,
      id: 1
    })
  });
  
  const data = await response.json();
  return data.result;
};

// Get all account keys (System.Account storage)
const accountPrefix = '0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9';
const accountKeys = await getStorageKeys(accountPrefix);
console.log(`Found ${accountKeys.length} accounts`);

// Extract account addresses from keys
accountKeys.forEach(key => {
  // The account address is the last 32 bytes of the key
  const addressHex = key.slice(-64);
  console.log('Account key:', key);
  console.log('Address portion:', addressHex);
});
TypeScript
import { ApiPromise, WsProvider } from '@polkadot/api';

async function queryStorageKeys() {
  const provider = new WsProvider('wss://api-centrifuge.n.dwellir.com');
  const api = await ApiPromise.create({ provider });
  
  // Method 1: Using high-level API to get keys
  const accountKeys = await api.query.system.account.keys();
  console.log('Account addresses:', accountKeys.map(k => k.toHuman()));
  
  // Method 2: Using low-level RPC for custom prefixes
  const prefix = api.query.system.account.keyPrefix();
  const keys = await api.rpc.state.getKeys(prefix);
  console.log(`Found ${keys.length} account storage keys`);
  
  // Method 3: Get keys for a specific map entry
  const validatorKeys = await api.query.staking.validators.keys();
  console.log('Active validators:', validatorKeys.length);
  
  // Process keys to extract data
  for (const key of keys) {
    // Decode the storage key
    const keyHex = key.toHex();
    console.log('Storage key:', keyHex);
    
    // Get the value for this key
    const value = await api.rpc.state.getStorage(key);
    console.log('Storage value:', value.toHex());
  }
  
  await api.disconnect();
}

// Advanced: Query keys with pagination
async function getKeysPagedExample() {
  const api = await ApiPromise.create({ 
    provider: new WsProvider('wss://api-centrifuge.n.dwellir.com') 
  });
  
  const prefix = api.query.system.account.keyPrefix();
  const pageSize = 100;
  let startKey = prefix;
  let allKeys = [];
  
  while (true) {
    // Note: state_getKeysPaged is used for pagination
    const keys = await api.rpc.state.getKeysPaged(prefix, pageSize, startKey);
    
    if (keys.length === 0) break;
    
    allKeys = allKeys.concat(keys);
    startKey = keys[keys.length - 1];
    
    console.log(`Fetched ${keys.length} keys, total: ${allKeys.length}`);
    
    if (keys.length < pageSize) break;
  }
  
  console.log(`Total keys found: ${allKeys.length}`);
  await api.disconnect();
}

Common Storage Prefixes

ModuleStorage ItemPrefix (example)
SystemAccount0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9
BalancesTotalIssuance0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80
StakingValidators0x5f3e4907f716ac89b6347d15ececedca9320c2dc4f5d7af5b320b04e2d1a3ff3
SessionNextKeys0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609

Batch Query Example

JavaScript
// Efficiently query multiple storage values
async function batchQueryStorage(api, keys) {
  // Get all values in a single call
  const values = await api.rpc.state.queryStorageAt(keys);
  
  const results = {};
  keys.forEach((key, index) => {
    results[key.toString()] = values[index];
  });
  
  return results;
}

// Example usage
const keys = await getStorageKeys(accountPrefix);
const values = await batchQueryStorage(api, keys.slice(0, 10));
console.log('Batch query results:', values);

Use Cases

  1. Account Discovery: Find all accounts with balances
  2. Validator Enumeration: List all validators in the network
  3. Storage Analysis: Analyze storage usage by module
  4. Migration Scripts: Iterate over storage for upgrades
  5. Indexing: Build indexes of on-chain data

Notes

  • Large prefixes may return many keys - use pagination when available
  • Keys are returned in lexicographical order
  • The prefix must be hex-encoded
  • Consider using state_getKeysPaged for large datasets
  • Storage keys include both the storage prefix and the key data