Skip to content

Call

Calls a contract function on Starknet without creating a transaction. This allows you to query contract state or execute view functions without paying gas fees or modifying the blockchain state.

Method Signature

func (provider *Provider) Call(
    ctx context.Context,
    request FunctionCall,
    blockID BlockID,
) ([]*felt.Felt, error)

Source: call.go

Parameters

  • ctx (context.Context): Context for request cancellation and timeout
  • request (FunctionCall): The function call request containing contract address, entry point selector, and calldata
  • blockID (BlockID): Block identifier to specify which block state to use for the call

Returns

  • []*felt.Felt: Array of felt values returned by the function
  • error: Error if the request fails

Type Definitions

FunctionCall

type FunctionCall struct {
    ContractAddress    *felt.Felt `json:"contract_address"`
    EntryPointSelector *felt.Felt `json:"entry_point_selector"`
    // Calldata The parameters passed to the function
    Calldata []*felt.Felt `json:"calldata"`
}

Source: types.go

BlockID

The blockID parameter specifies which block state to use for the call. 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

Usage Example

package main
 
import (
    "context"
    "fmt"
    "log"
    "os"
 
    "github.com/NethermindEth/juno/core/felt"
    "github.com/NethermindEth/starknet.go/rpc"
    "github.com/NethermindEth/starknet.go/utils"
    "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)
    }
 
    ctx := context.Background()
 
    // ETH contract address on Sepolia
    contractAddress, err := utils.HexToFelt("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7")
    if err != nil {
        log.Fatal(err)
    }
 
    // Get function selector for "symbol()"
    symbolSelector := utils.GetSelectorFromNameFelt("symbol")
 
    // Create function call request
    request := rpc.FunctionCall{
        ContractAddress:    contractAddress,
        EntryPointSelector: symbolSelector,
        Calldata:           []*felt.Felt{},
    }
 
    // Call the function
    result, err := provider.Call(ctx, request, rpc.WithBlockTag("latest"))
    if err != nil {
        log.Fatal(err)
    }
 
    fmt.Printf("Symbol: %s\n", result[0])
}

Error Handling

result, err := provider.Call(ctx, request, rpc.WithBlockTag("latest"))
if err != nil {
    if errors.Is(err, rpc.ErrContractNotFound) {
        log.Printf("Contract not found at address: %s", request.ContractAddress)
        return
    }
    if errors.Is(err, rpc.ErrEntrypointNotFound) {
        log.Printf("Entry point not found: %s", request.EntryPointSelector)
        return
    }
    if errors.Is(err, rpc.ErrContractError) {
        log.Printf("Contract execution error")
        return
    }
    if errors.Is(err, rpc.ErrBlockNotFound) {
        log.Printf("Block not found")
        return
    }
    log.Printf("Call failed: %v", err)
    return
}
 
fmt.Printf("Call result: %v\n", result)

Common Use Cases

  • Readin contract storage values without modifying state.
  • Gettin ERC20 token balances for accounts.
  • Executing view functions to retrieve computed values.