[#42] Add ResolveContractHash method

Signed-off-by: Pavel Pogodaev <p.pogodaev@yadro.com>
This commit is contained in:
Pavel Pogodaev 2023-07-10 09:56:37 +03:00
parent 998fe1a7ab
commit b9afe7a2f9
2 changed files with 127 additions and 0 deletions

View file

@ -10,6 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -116,3 +117,46 @@ func (n *NNS) ResolveContainerDomain(domain container.Domain) (cid.ID, error) {
return cid.ID{}, errNotFound
}
// ResolveContractHash looks up for NNS TXT records for the given container domain
// by calling `resolve` method of NNS contract. Returns the first record which represents
// valid contract hash 20 bytes long unsigned integer. Otherwise, returns an error.
//
// ResolveContractHash MUST NOT be called before successful Dial.
//
// See also https://docs.neo.org/docs/en-us/reference/nns.html.
func (n *NNS) ResolveContractHash(domain container.Domain) (util.Uint160, error) {
item, err := unwrap.Item(n.invoker.Call(n.nnsContract, "resolve",
domain.Name()+"."+domain.Zone(), int64(nns.TXT),
))
if err != nil {
return util.Uint160{}, fmt.Errorf("contract invocation: %w", err)
}
if _, ok := item.(stackitem.Null); !ok {
arr, ok := item.Value().([]stackitem.Item)
if !ok {
// unexpected for types from stackitem package
return util.Uint160{}, errors.New("invalid cast to stack item slice")
}
for i := range arr {
recordValue, err := arr[i].TryBytes()
if err != nil {
return util.Uint160{}, fmt.Errorf("convert array item to byte slice: %w", err)
}
strRecordValue := string(recordValue)
scriptHash, err := address.StringToUint160(strRecordValue)
if err == nil {
return scriptHash, nil
}
scriptHash, err = util.Uint160DecodeStringLE(strRecordValue)
if err == nil {
return scriptHash, nil
}
}
}
return util.Uint160{}, errNotFound
}