Skip to main content
Version: 0.9.1

Read Contract Storage

import (
"context"
"blockwatch.cc/tzgo/tezos"
"blockwatch.cc/tzpro-go/tzpro"
)

// use default Mainnet client
client := tzpro.DefaultClient
ctx := context.Background()
addr := tezos.MustParseAddress("KT1Puc9St8wdNoGtLiD2WXaHbWU7styaxYhD")

// read storage from API
params := tzpro.NewContractParams()
raw, err := client.GetContractStorage(ctx, addr, params)

// access individual properties with correct type
tokenAddress, ok := raw.GetAddress("tokenAddress")
tokenPool, ok := raw.GetBig("tokenPool")
xtzPool, ok := raw.GetBig("xtzPool")

Decode contract data into Go types

import (
"context"
"blockwatch.cc/tzgo/tezos"
"blockwatch.cc/tzpro-go/tzpro"
)

// use default Mainnet client
client := tzpro.DefaultClient
ctx := context.Background()
addr := tezos.MustParseAddress("KT1Puc9St8wdNoGtLiD2WXaHbWU7styaxYhD")

// read storage from API
raw, err := client.GetContractStorage(ctx, addr, tzpro.NewContractParams())

// decode into Go struct
type DexterStorage struct {
Accounts int64 `json:"accounts"`
SelfIsUpdatingTokenPool bool `json:"selfIsUpdatingTokenPool"`
FreezeBaker bool `json:"freezeBaker"`
LqtTotal *big.Int `json:"lqtTotal"`
Manager tezos.Address `json:"manager"`
TokenAddress tezos.Address `json:"tokenAddress"`
TokenPool *big.Int `json:"tokenPool"`
XtzPool *big.Int `json:"xtzPool"`
}

dexterPool := &DexterStorage{}
err := raw.Unmarshal(dexterPool)

List Bigmap Values

import (
"context"
"blockwatch.cc/tzpro-go/tzpro"
)

type HicNFT struct {
TokenId int `json:"token_id,string"`
TokenInfo map[string]string `json:"token_info"`
}

client := tzpro.DefaultClient
ctx := context.Background()
params := tzpro.NewContractParams().
WithUnpack().
WithLimit(500)

for {
// fetch next batch from the explorer API
nfts, err := client.GetBigmapValues(ctx, 514, params)
if err != nil {
return err
}

// stop when result is empty
if len(nfts) == 0 {
break
}
for _, v := range nfts {
var nft HicNFT
if err := v.Unmarshal(&nft); err != nil {
return err
}
// handle the value
}
}

Decode Bigmaps Client-side

Extending the example above, we now use TzGo's Micheline features to decode annotated bigmap data into native Go structs. For efficiency reasons the API only sends binary (hex-encoded) content for smart contract storage. The SDK lets you decodes this into native Micheline primitives or native Go structs for further processing as shown in the example below.

import (
"context"
"blockwatch.cc/tzpro-go/tzpro"
)

type HicNFT struct {
TokenId int `json:"token_id,string"`
TokenInfo map[string]string `json:"token_info"`
}

client := tzpro.DefaultClient
ctx := context.Background()

// fetch bigmap info with prim (required for key/value types)
params := tzpro.NewContractParams().WithPrim()
info, err := client.GetBigmap(ctx, 514, params))
keyType := info.MakeKeyType()
valType := info.MakeValueType()

// create a new query object
q := client.NewBigmapValueQuery()

// add filters and configure the query to list all active keys
q.WithFilter(tzpro.FilterModeEqual, "bigmap_id", 514).
WithColumns("row_id", "key_hash", "key", "value").
WithLimit(1000).
WithOrder(tzpro.OrderDesc)

// execute the query
list, err := q.Run(ctx)

// walk rows
for _, row := range list.Rows {
// unpack to Micheline primitives and tag types (we ignore errors here)
key, _ := row.DecodeKey(keyType)
val, _ := row.DecodeValue(valType)

// unpack into Go type
var nft HicNFT
err = val.Unmarshal(&nft)

// or access individual named values
i, ok := val.GetInt64("token_id")
}