Skip to content

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 timeout
  • blockID (BlockID): Block identifier (number, hash, or tag like "latest" or "pending")

Returns

  • *StateUpdateOutput: The state changes that occurred in the block
  • error: 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 built

    Source: 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.