StateUpdate
Retrieves the state update for a specific block, including storage diffs, declared classes, deployed contracts, and nonces.
Method Signature
func (p *Provider) StateUpdate(
ctx context.Context,
blockID BlockID,
) (*StateUpdateOutput, error)Parameters
ctx(context.Context): Context for request cancellation and timeoutsblockID(BlockID): The identifier of the block (hash, number, or tag)
Returns
*StateUpdateOutput: The state changes that occurred in the blockerror: Error if the block is not found
Description
StateUpdate returns all state changes that occurred in a specific block, including:
- Storage Diffs: Changes to contract storage
- Declared Classes: New contract classes declared
- Deployed Contracts: New contract instances deployed
- Replaced Classes: Contract class upgrades
- Nonces: Account nonce updates
This is essential for indexing, analytics, and understanding blockchain state transitions.
Usage Example
package main
import (
"context"
"fmt"
"log"
"github.com/NethermindEth/starknet.go/rpc"
)
func main() {
client, err := rpc.NewProvider(context.Background(), "https://starknet-sepolia.public.blastapi.io/rpc/v0_7")
if err != nil {
log.Fatal(err)
}
// Get state update for latest block
blockID := rpc.BlockID{Tag: "latest"}
stateUpdate, err := client.StateUpdate(context.Background(), blockID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Block Hash: %s\n", stateUpdate.BlockHash)
fmt.Printf("New Root: %s\n", stateUpdate.NewRoot)
fmt.Printf("Old Root: %s\n", stateUpdate.OldRoot)
fmt.Printf("Storage Diffs: %d contracts\n", len(stateUpdate.StateDiff.StorageDiffs))
fmt.Printf("Declared Classes: %d\n", len(stateUpdate.StateDiff.DeclaredClasses))
fmt.Printf("Deployed Contracts: %d\n", len(stateUpdate.StateDiff.DeployedContracts))
fmt.Printf("Nonce Updates: %d\n", len(stateUpdate.StateDiff.Nonces))
// Example output:
// Block Hash: 0x1a2b3c4d...
// New Root: 0x5e6f7a8b...
// Old Root: 0x9c0d1e2f...
// Storage Diffs: 12 contracts
// Declared Classes: 2
// Deployed Contracts: 1
// Nonce Updates: 5
}StateUpdateOutput Structure
type StateUpdateOutput struct {
BlockHash *felt.Felt
NewRoot *felt.Felt
OldRoot *felt.Felt
StateDiff StateDiff
}
type StateDiff struct {
StorageDiffs []ContractStorageDiff
DeclaredClasses []DeclaredClass
DeployedContracts []DeployedContract
ReplacedClasses []ReplacedClass
Nonces []NonceUpdate
}
type ContractStorageDiff struct {
Address *felt.Felt
StorageEntries []StorageEntry
}
type StorageEntry struct {
Key *felt.Felt
Value *felt.Felt
}Detailed Usage
Tracking Storage Changes
stateUpdate, err := client.StateUpdate(ctx, blockID)
if err != nil {
log.Fatal(err)
}
// Iterate through storage diffs
for _, diff := range stateUpdate.StateDiff.StorageDiffs {
fmt.Printf("Contract: %s\n", diff.Address)
for _, entry := range diff.StorageEntries {
fmt.Printf(" Key: %s -> Value: %s\n", entry.Key, entry.Value)
}
}Monitoring Declared Classes
// Check for newly declared contract classes
for _, declaredClass := range stateUpdate.StateDiff.DeclaredClasses {
fmt.Printf("Declared Class Hash: %s\n", declaredClass.ClassHash)
fmt.Printf("Compiled Class Hash: %s\n", declaredClass.CompiledClassHash)
}Tracking Deployments
// Monitor new contract deployments
for _, deployed := range stateUpdate.StateDiff.DeployedContracts {
fmt.Printf("Deployed Contract: %s\n", deployed.Address)
fmt.Printf("Class Hash: %s\n", deployed.ClassHash)
}Nonce Updates
// Track account nonce changes
for _, nonceUpdate := range stateUpdate.StateDiff.Nonces {
fmt.Printf("Account: %s, New Nonce: %s\n",
nonceUpdate.ContractAddress,
nonceUpdate.Nonce)
}Use Cases
- Blockchain Indexing: Index all state changes for analytics
- Event Monitoring: Track contract deployments and upgrades
- State Verification: Verify state root transitions
- Audit Trails: Create complete audit logs of state changes
- Analytics: Analyze storage patterns and contract interactions
Error Handling
stateUpdate, err := client.StateUpdate(ctx, blockID)
if err != nil {
if errors.Is(err, rpc.ErrBlockNotFound) {
log.Println("Block not found")
return
}
log.Printf("RPC error: %v", err)
}Block ID Options
// Latest block
blockID := rpc.BlockID{Tag: "latest"}
// Pending block
blockID := rpc.BlockID{Tag: "pending"}
// Specific block number
blockID := rpc.BlockID{Number: 12345}
// Specific block hash
blockHash, _ := new(felt.Felt).SetString("0xabc...")
blockID := rpc.BlockID{Hash: blockHash}Related Methods
- BlockWithTxs - Get block with transactions
- Class - Get declared class details
- StorageAt - Get specific storage value
RPC Specification
- Method:
starknet_getStateUpdate - Version: RPC v0.9.0
- Returns: Complete state diff for the block
Performance Notes
- State updates for old blocks may be slow to retrieve
- Consider caching state updates for frequently accessed blocks
- Large state updates may take significant time to process
- Use specific block numbers instead of "latest" for consistency

