StateUpdate
Retrieves the complete state changes that occurred in a specific block. This includes storage updates, newly declared contract classes, deployed contract instances, replaced classes, and nonce updates. StateUpdate is essential for blockchain indexing, analytics, state verification, and understanding how the blockchain state transitions from one block to the next.
Method Signature
func (provider *Provider) StateUpdate(
ctx context.Context,
blockID BlockID,
) (*StateUpdateOutput, error)Source: block.go
Parameters
ctx(context.Context): Context for request cancellation and timeoutblockID(BlockID): Block identifier (number, hash, or tag like "latest" or "pending")
Returns
*StateUpdateOutput: The state changes that occurred in the blockerror: Error if the request fails
Type Definitions
BlockID
The blockID parameter specifies which block to retrieve. You can identify a block in three ways:
type BlockID struct {
Number *uint64 `json:"block_number,omitempty"`
Hash *felt.Felt `json:"block_hash,omitempty"`
Tag BlockTag `json:"tag,omitempty"`
}Source: types_block.go
There are helper functions for creating BlockID. So Instead of manually creating the BlockID struct, use these convenience functions.
-
By Block Number - Get a specific block by its height
blockID := rpc.WithBlockNumber(123456)Source: block.go
-
By Block Hash - Get a specific block by its hash
hash, _ := new(felt.Felt).SetString("0x1234...") blockID := rpc.WithBlockHash(hash)Source: block.go
-
By Block Tag - Get a dynamic block reference
blockID := rpc.WithBlockTag("latest") // Latest accepted block blockID := rpc.WithBlockTag("pending") // Block currently being builtSource: block.go
StateUpdateOutput
type StateUpdateOutput struct {
BlockHash *felt.Felt `json:"block_hash"`
NewRoot *felt.Felt `json:"new_root"`
PreConfirmedStateUpdate
}Source: types.go
The state update includes:
- 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
Usage Example
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/NethermindEth/starknet.go/rpc"
"github.com/joho/godotenv"
)
func main() {
// Load environment variables from .env file
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
// Get RPC URL from environment variable
rpcURL := os.Getenv("STARKNET_RPC_URL")
if rpcURL == "" {
log.Fatal("STARKNET_RPC_URL not found in .env file")
}
// Initialize provider
provider, err := rpc.NewProvider(context.Background(), rpcURL)
if err != nil {
log.Fatal(err)
}
// Get state update for latest block
blockID := rpc.WithBlockTag("latest")
stateUpdate, err := provider.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))
}Error Handling
stateUpdate, err := provider.StateUpdate(ctx, blockID)
if err != nil {
switch {
case errors.Is(err, rpc.ErrBlockNotFound):
log.Printf("Block not found")
default:
log.Printf("Failed to get state update: %v", err)
}
return
}
fmt.Printf("Successfully retrieved state update\n")Common Use Cases
- Indexing all state changes for analytics and querying. See example.
- Tracking contract deployments, upgrades, and storage changes.
- Verifying state root transitions and state consistency.
- Creating complete audit logs of all state modifications in each block.

