trilitech / tzgo

Golang library for the Tezos blockchain
MIT License
4 stars 2 forks source link

Error parsing BigMapIds #15

Closed tulpenhaendler closed 1 month ago

tulpenhaendler commented 2 months ago

The README shows that to get all the bigmaps for a given contract one would do the following:

import (
    "github.com/trilitech/tzgo/micheline"
    "github.com/trilitech/tzgo/rpc"
    "github.com/trilitech/tzgo/tezos"
)

// we use the hic et nunc NFT market on mainnet as example
addr := tezos.MustParseAddress("KT1Hkg5qeNhfwpKW4fXvq7HGZB9z2EnmCCA9")

// init RPC client
c, _ := rpc.NewClient("https://rpc.tzstats.com", nil)

// fetch the contract's script and most recent storage
script, _ := c.GetContractScript(ctx, addr)

// bigmap pointers as []int64
ids := script.BigmapsById()

// bigmap pointers as named map[string]int64 (names from type annotations)
named := script.BigmapsByName()

The methods BigmapsByIdand BigmapsByName dont actually exist, however inspired by the above, the following works:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "github.com/trilitech/tzgo/rpc"
    "github.com/trilitech/tzgo/tezos"
)

func main() {
    // we use the hic et nunc NFT market on mainnet as example
    addr := tezos.MustParseAddress("<contract>")

    // init RPC client
    c, _ := rpc.NewClient("http://127.0.0.1:8732", nil)

    // fetch the contract's script and most recent storage
    script, _ := c.GetContractScript(context.Background(), addr)

    // bigmap pointers as []int64
    ids := script.Bigmaps()
    b, _ := json.Marshal(ids)

    fmt.Println(string(b))

}

And for most contracts this works, however sometimes, as for example the contract KT1J1yVJEDkaYzJ7WuEomryEGWBNMGcUw1WA this returns a the correct bigmaps mixed into a lot of nonsense:

{"ledger":54254,"metadata":54253,"metadata_0":1,"metadata_1":2,
....
lots of garbage cleaned up for clarity ... 
....
,"metadata_998":999,"metadata_999":1000,"whitelist":54255}

Is there a different way to reliably fetch BigMap Ids?

tulpenhaendler commented 2 months ago

It also returns nothing for: https://better-call.dev/mainnet/KT1CSYNJ6dFcnsV4QJ6HnBFtdif8LJGPQiDM/storage

tulpenhaendler commented 2 months ago

for KT1F3MuqvT9Yz57TgCS3EkDcKNZe9HpiavUJ it returns only 6 of the 8 existing bigmaps, one of the returned ones also has a wrong bigMapId.

huancheng-trili commented 2 months ago

Hi @tulpenhaendler, thanks for reporting this. I'm taking a look at this issue, though it might take some time since the team didn't really pay much attention to other parts of TzGo since we took over this project and I personally have very little knowledge about michelson. Based on what I understand so far, here I try to address your comments:

The methods BigmapsByIdand BigmapsByName dont actually exist

They did exist previously, but the methods were updated about 2 years ago and the readme was not updated accordingly. script.Bigmaps is supposed to replace the two methods.

Is there a different way to reliably fetch BigMap Ids?

This should be the ideal way of fetching BigMap IDs:

ids := []int64{}
for k, v := range script.Bigmaps() {
    ids = append(ids, v)
}

since script.Bigmaps is supposed to return a mapping between map names and map IDs. I guess the current issue has something to do with parsing the micheline code. When everything is parsed and interpreted correctly, the returned mapping should give correct BigMap IDs.