mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-27 05:42:56 +00:00
b4c0fcfaad
It helps us to keep the index clean and ordered. When some new RPC binding test should be added, we don't need to search for a suitable place for it. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
1633 lines
39 KiB
Text
1633 lines
39 KiB
Text
// Package structs contains RPC wrappers for Types contract.
|
|
package structs
|
|
|
|
import (
|
|
"crypto/elliptic"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
"math/big"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// Hash contains contract hash.
|
|
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
|
|
|
|
// LedgerBlock is a contract-specific ledger.Block type used by its methods.
|
|
type LedgerBlock struct {
|
|
Hash util.Uint256
|
|
Version *big.Int
|
|
PrevHash util.Uint256
|
|
MerkleRoot util.Uint256
|
|
Timestamp *big.Int
|
|
Nonce *big.Int
|
|
Index *big.Int
|
|
NextConsensus util.Uint160
|
|
TransactionsLength *big.Int
|
|
}
|
|
|
|
// LedgerBlockSR is a contract-specific ledger.BlockSR type used by its methods.
|
|
type LedgerBlockSR struct {
|
|
Hash util.Uint256
|
|
Version *big.Int
|
|
PrevHash util.Uint256
|
|
MerkleRoot util.Uint256
|
|
Timestamp *big.Int
|
|
Nonce *big.Int
|
|
Index *big.Int
|
|
NextConsensus util.Uint160
|
|
TransactionsLength *big.Int
|
|
PrevStateRoot util.Uint256
|
|
}
|
|
|
|
// LedgerTransaction is a contract-specific ledger.Transaction type used by its methods.
|
|
type LedgerTransaction struct {
|
|
Hash util.Uint256
|
|
Version *big.Int
|
|
Nonce *big.Int
|
|
Sender util.Uint160
|
|
SysFee *big.Int
|
|
NetFee *big.Int
|
|
ValidUntilBlock *big.Int
|
|
Script []byte
|
|
}
|
|
|
|
// LedgerTransactionSigner is a contract-specific ledger.TransactionSigner type used by its methods.
|
|
type LedgerTransactionSigner struct {
|
|
Account util.Uint160
|
|
Scopes *big.Int
|
|
AllowedContracts []util.Uint160
|
|
AllowedGroups keys.PublicKeys
|
|
Rules []*LedgerWitnessRule
|
|
}
|
|
|
|
// LedgerWitnessCondition is a contract-specific ledger.WitnessCondition type used by its methods.
|
|
type LedgerWitnessCondition struct {
|
|
Type *big.Int
|
|
Value any
|
|
}
|
|
|
|
// LedgerWitnessRule is a contract-specific ledger.WitnessRule type used by its methods.
|
|
type LedgerWitnessRule struct {
|
|
Action *big.Int
|
|
Condition *LedgerWitnessCondition
|
|
}
|
|
|
|
// ManagementABI is a contract-specific management.ABI type used by its methods.
|
|
type ManagementABI struct {
|
|
Methods []*ManagementMethod
|
|
Events []*ManagementEvent
|
|
}
|
|
|
|
// ManagementContract is a contract-specific management.Contract type used by its methods.
|
|
type ManagementContract struct {
|
|
ID *big.Int
|
|
UpdateCounter *big.Int
|
|
Hash util.Uint160
|
|
NEF []byte
|
|
Manifest *ManagementManifest
|
|
}
|
|
|
|
// ManagementEvent is a contract-specific management.Event type used by its methods.
|
|
type ManagementEvent struct {
|
|
Name string
|
|
Params []*ManagementParameter
|
|
}
|
|
|
|
// ManagementGroup is a contract-specific management.Group type used by its methods.
|
|
type ManagementGroup struct {
|
|
PublicKey *keys.PublicKey
|
|
Signature []byte
|
|
}
|
|
|
|
// ManagementManifest is a contract-specific management.Manifest type used by its methods.
|
|
type ManagementManifest struct {
|
|
Name string
|
|
Groups []*ManagementGroup
|
|
Features map[string]string
|
|
SupportedStandards []string
|
|
ABI *ManagementABI
|
|
Permissions []*ManagementPermission
|
|
Trusts []util.Uint160
|
|
Extra any
|
|
}
|
|
|
|
// ManagementMethod is a contract-specific management.Method type used by its methods.
|
|
type ManagementMethod struct {
|
|
Name string
|
|
Params []*ManagementParameter
|
|
ReturnType *big.Int
|
|
Offset *big.Int
|
|
Safe bool
|
|
}
|
|
|
|
// ManagementParameter is a contract-specific management.Parameter type used by its methods.
|
|
type ManagementParameter struct {
|
|
Name string
|
|
Type *big.Int
|
|
}
|
|
|
|
// ManagementPermission is a contract-specific management.Permission type used by its methods.
|
|
type ManagementPermission struct {
|
|
Contract util.Uint160
|
|
Methods []string
|
|
}
|
|
|
|
// StructsInternal is a contract-specific structs.Internal type used by its methods.
|
|
type StructsInternal struct {
|
|
Bool bool
|
|
Int *big.Int
|
|
Bytes []byte
|
|
String string
|
|
H160 util.Uint160
|
|
H256 util.Uint256
|
|
PK *keys.PublicKey
|
|
PubKey *keys.PublicKey
|
|
Sign []byte
|
|
ArrOfBytes [][]byte
|
|
ArrOfH160 []util.Uint160
|
|
Map map[*big.Int]keys.PublicKeys
|
|
Struct *StructsInternal
|
|
UnexportedField *big.Int
|
|
}
|
|
|
|
// Invoker is used by ContractReader to call various safe methods.
|
|
type Invoker interface {
|
|
Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
|
|
}
|
|
|
|
// ContractReader implements safe contract methods.
|
|
type ContractReader struct {
|
|
invoker Invoker
|
|
hash util.Uint160
|
|
}
|
|
|
|
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
|
func NewReader(invoker Invoker) *ContractReader {
|
|
var hash = Hash
|
|
return &ContractReader{invoker, hash}
|
|
}
|
|
|
|
// Block invokes `block` method of contract.
|
|
func (c *ContractReader) Block(b *LedgerBlock) (*LedgerBlock, error) {
|
|
return itemToLedgerBlock(unwrap.Item(c.invoker.Call(c.hash, "block", b)))
|
|
}
|
|
|
|
// Contract invokes `contract` method of contract.
|
|
func (c *ContractReader) Contract(mc *ManagementContract) (*ManagementContract, error) {
|
|
return itemToManagementContract(unwrap.Item(c.invoker.Call(c.hash, "contract", mc)))
|
|
}
|
|
|
|
// Struct invokes `struct` method of contract.
|
|
func (c *ContractReader) Struct(s *StructsInternal) (*StructsInternal, error) {
|
|
return itemToStructsInternal(unwrap.Item(c.invoker.Call(c.hash, "struct", s)))
|
|
}
|
|
|
|
// Transaction invokes `transaction` method of contract.
|
|
func (c *ContractReader) Transaction(t *LedgerTransaction) (*LedgerTransaction, error) {
|
|
return itemToLedgerTransaction(unwrap.Item(c.invoker.Call(c.hash, "transaction", t)))
|
|
}
|
|
|
|
// itemToLedgerBlock converts stack item into *LedgerBlock.
|
|
func itemToLedgerBlock(item stackitem.Item, err error) (*LedgerBlock, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(LedgerBlock)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of LedgerBlock from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *LedgerBlock) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 9 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Version, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Version: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.PrevHash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field PrevHash: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.MerkleRoot, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field MerkleRoot: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Timestamp, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Timestamp: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Nonce, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Nonce: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Index, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Index: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.NextConsensus, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field NextConsensus: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.TransactionsLength, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field TransactionsLength: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToLedgerBlockSR converts stack item into *LedgerBlockSR.
|
|
func itemToLedgerBlockSR(item stackitem.Item, err error) (*LedgerBlockSR, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(LedgerBlockSR)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of LedgerBlockSR from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *LedgerBlockSR) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 10 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Version, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Version: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.PrevHash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field PrevHash: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.MerkleRoot, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field MerkleRoot: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Timestamp, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Timestamp: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Nonce, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Nonce: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Index, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Index: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.NextConsensus, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field NextConsensus: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.TransactionsLength, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field TransactionsLength: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.PrevStateRoot, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field PrevStateRoot: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToLedgerTransaction converts stack item into *LedgerTransaction.
|
|
func itemToLedgerTransaction(item stackitem.Item, err error) (*LedgerTransaction, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(LedgerTransaction)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of LedgerTransaction from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *LedgerTransaction) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 8 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Version, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Version: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Nonce, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Nonce: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Sender, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Sender: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.SysFee, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field SysFee: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.NetFee, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field NetFee: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.ValidUntilBlock, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field ValidUntilBlock: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Script, err = arr[index].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("field Script: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToLedgerTransactionSigner converts stack item into *LedgerTransactionSigner.
|
|
func itemToLedgerTransactionSigner(item stackitem.Item, err error) (*LedgerTransactionSigner, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(LedgerTransactionSigner)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of LedgerTransactionSigner from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *LedgerTransactionSigner) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 5 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Account, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Account: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Scopes, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Scopes: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.AllowedContracts, err = func (item stackitem.Item) ([]util.Uint160, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]util.Uint160, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field AllowedContracts: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.AllowedGroups, err = func (item stackitem.Item) (keys.PublicKeys, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make(keys.PublicKeys, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k, nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field AllowedGroups: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Rules, err = func (item stackitem.Item) ([]*LedgerWitnessRule, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*LedgerWitnessRule, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToLedgerWitnessRule(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Rules: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToLedgerWitnessCondition converts stack item into *LedgerWitnessCondition.
|
|
func itemToLedgerWitnessCondition(item stackitem.Item, err error) (*LedgerWitnessCondition, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(LedgerWitnessCondition)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of LedgerWitnessCondition from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *LedgerWitnessCondition) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Type, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Type: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Value, err = arr[index].Value(), error(nil)
|
|
if err != nil {
|
|
return fmt.Errorf("field Value: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToLedgerWitnessRule converts stack item into *LedgerWitnessRule.
|
|
func itemToLedgerWitnessRule(item stackitem.Item, err error) (*LedgerWitnessRule, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(LedgerWitnessRule)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of LedgerWitnessRule from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *LedgerWitnessRule) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Action, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Action: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Condition, err = itemToLedgerWitnessCondition(arr[index], nil)
|
|
if err != nil {
|
|
return fmt.Errorf("field Condition: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementABI converts stack item into *ManagementABI.
|
|
func itemToManagementABI(item stackitem.Item, err error) (*ManagementABI, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementABI)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementABI from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementABI) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Methods, err = func (item stackitem.Item) ([]*ManagementMethod, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*ManagementMethod, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToManagementMethod(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Methods: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Events, err = func (item stackitem.Item) ([]*ManagementEvent, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*ManagementEvent, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToManagementEvent(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Events: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementContract converts stack item into *ManagementContract.
|
|
func itemToManagementContract(item stackitem.Item, err error) (*ManagementContract, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementContract)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementContract from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementContract) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 5 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.ID, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field ID: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.UpdateCounter, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field UpdateCounter: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Hash, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Hash: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.NEF, err = arr[index].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("field NEF: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Manifest, err = itemToManagementManifest(arr[index], nil)
|
|
if err != nil {
|
|
return fmt.Errorf("field Manifest: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementEvent converts stack item into *ManagementEvent.
|
|
func itemToManagementEvent(item stackitem.Item, err error) (*ManagementEvent, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementEvent)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementEvent from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementEvent) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Name, err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Name: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Params, err = func (item stackitem.Item) ([]*ManagementParameter, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*ManagementParameter, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToManagementParameter(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Params: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementGroup converts stack item into *ManagementGroup.
|
|
func itemToManagementGroup(item stackitem.Item, err error) (*ManagementGroup, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementGroup)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementGroup from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementGroup) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.PublicKey, err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field PublicKey: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Signature, err = arr[index].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("field Signature: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementManifest converts stack item into *ManagementManifest.
|
|
func itemToManagementManifest(item stackitem.Item, err error) (*ManagementManifest, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementManifest)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementManifest from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementManifest) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 8 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Name, err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Name: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Groups, err = func (item stackitem.Item) ([]*ManagementGroup, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*ManagementGroup, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToManagementGroup(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Groups: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Features, err = func (item stackitem.Item) (map[string]string, error) {
|
|
m, ok := item.Value().([]stackitem.MapElement)
|
|
if !ok {
|
|
return nil, fmt.Errorf("%s is not a map", item.Type().String())
|
|
}
|
|
res := make(map[string]string)
|
|
for i := range m {
|
|
k, err := func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (m[i].Key)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("key %d: %w", i, err)
|
|
}
|
|
v, err := func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (m[i].Value)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("value %d: %w", i, err)
|
|
}
|
|
res[k] = v
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Features: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.SupportedStandards, err = func (item stackitem.Item) ([]string, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]string, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field SupportedStandards: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.ABI, err = itemToManagementABI(arr[index], nil)
|
|
if err != nil {
|
|
return fmt.Errorf("field ABI: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Permissions, err = func (item stackitem.Item) ([]*ManagementPermission, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*ManagementPermission, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToManagementPermission(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Permissions: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Trusts, err = func (item stackitem.Item) ([]util.Uint160, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]util.Uint160, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Trusts: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Extra, err = arr[index].Value(), error(nil)
|
|
if err != nil {
|
|
return fmt.Errorf("field Extra: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementMethod converts stack item into *ManagementMethod.
|
|
func itemToManagementMethod(item stackitem.Item, err error) (*ManagementMethod, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementMethod)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementMethod from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementMethod) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 5 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Name, err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Name: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Params, err = func (item stackitem.Item) ([]*ManagementParameter, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]*ManagementParameter, len(arr))
|
|
for i := range res {
|
|
res[i], err = itemToManagementParameter(arr[i], nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Params: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.ReturnType, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field ReturnType: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Offset, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Offset: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Safe, err = arr[index].TryBool()
|
|
if err != nil {
|
|
return fmt.Errorf("field Safe: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementParameter converts stack item into *ManagementParameter.
|
|
func itemToManagementParameter(item stackitem.Item, err error) (*ManagementParameter, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementParameter)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementParameter from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementParameter) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Name, err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Name: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Type, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Type: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToManagementPermission converts stack item into *ManagementPermission.
|
|
func itemToManagementPermission(item stackitem.Item, err error) (*ManagementPermission, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(ManagementPermission)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of ManagementPermission from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *ManagementPermission) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 2 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Contract, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Contract: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Methods, err = func (item stackitem.Item) ([]string, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]string, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Methods: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// itemToStructsInternal converts stack item into *StructsInternal.
|
|
func itemToStructsInternal(item stackitem.Item, err error) (*StructsInternal, error) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var res = new(StructsInternal)
|
|
err = res.FromStackItem(item)
|
|
return res, err
|
|
}
|
|
|
|
// FromStackItem retrieves fields of StructsInternal from the given
|
|
// [stackitem.Item] or returns an error if it's not possible to do to so.
|
|
func (res *StructsInternal) FromStackItem(item stackitem.Item) error {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return errors.New("not an array")
|
|
}
|
|
if len(arr) != 14 {
|
|
return errors.New("wrong number of structure elements")
|
|
}
|
|
|
|
var (
|
|
index = -1
|
|
err error
|
|
)
|
|
index++
|
|
res.Bool, err = arr[index].TryBool()
|
|
if err != nil {
|
|
return fmt.Errorf("field Bool: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Int, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field Int: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Bytes, err = arr[index].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("field Bytes: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.String, err = func (item stackitem.Item) (string, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if !utf8.Valid(b) {
|
|
return "", errors.New("not a UTF-8 string")
|
|
}
|
|
return string(b), nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field String: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.H160, err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field H160: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.H256, err = func (item stackitem.Item) (util.Uint256, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
u, err := util.Uint256DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint256{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field H256: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.PK, err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field PK: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.PubKey, err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field PubKey: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Sign, err = arr[index].TryBytes()
|
|
if err != nil {
|
|
return fmt.Errorf("field Sign: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.ArrOfBytes, err = func (item stackitem.Item) ([][]byte, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([][]byte, len(arr))
|
|
for i := range res {
|
|
res[i], err = arr[i].TryBytes()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field ArrOfBytes: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.ArrOfH160, err = func (item stackitem.Item) ([]util.Uint160, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make([]util.Uint160, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (util.Uint160, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
u, err := util.Uint160DecodeBytesBE(b)
|
|
if err != nil {
|
|
return util.Uint160{}, err
|
|
}
|
|
return u, nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field ArrOfH160: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Map, err = func (item stackitem.Item) (map[*big.Int]keys.PublicKeys, error) {
|
|
m, ok := item.Value().([]stackitem.MapElement)
|
|
if !ok {
|
|
return nil, fmt.Errorf("%s is not a map", item.Type().String())
|
|
}
|
|
res := make(map[*big.Int]keys.PublicKeys)
|
|
for i := range m {
|
|
k, err := m[i].Key.TryInteger()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("key %d: %w", i, err)
|
|
}
|
|
v, err := func (item stackitem.Item) (keys.PublicKeys, error) {
|
|
arr, ok := item.Value().([]stackitem.Item)
|
|
if !ok {
|
|
return nil, errors.New("not an array")
|
|
}
|
|
res := make(keys.PublicKeys, len(arr))
|
|
for i := range res {
|
|
res[i], err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
|
b, err := item.TryBytes()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k, nil
|
|
} (arr[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("item %d: %w", i, err)
|
|
}
|
|
}
|
|
return res, nil
|
|
} (m[i].Value)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("value %d: %w", i, err)
|
|
}
|
|
res[k] = v
|
|
}
|
|
return res, nil
|
|
} (arr[index])
|
|
if err != nil {
|
|
return fmt.Errorf("field Map: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.Struct, err = itemToStructsInternal(arr[index], nil)
|
|
if err != nil {
|
|
return fmt.Errorf("field Struct: %w", err)
|
|
}
|
|
|
|
index++
|
|
res.UnexportedField, err = arr[index].TryInteger()
|
|
if err != nil {
|
|
return fmt.Errorf("field UnexportedField: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|