// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.

// Package structs contains RPC wrappers for Types contract.
package structs

import (
	"crypto/elliptic"
	"errors"
	"fmt"
	"git.marketally.com/tutus-one/tutus-chain/pkg/crypto/keys"
	"git.marketally.com/tutus-one/tutus-chain/pkg/rpcclient/unwrap"
	"git.marketally.com/tutus-one/tutus-chain/pkg/smartcontract"
	"git.marketally.com/tutus-one/tutus-chain/pkg/tutusrpc/result"
	"git.marketally.com/tutus-one/tutus-chain/pkg/util"
	"git.marketally.com/tutus-one/tutus-chain/pkg/vm/stackitem"
	"math/big"
	"unicode/utf8"
)

// 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
	PrimaryIndex       *big.Int
	NextConsensus      util.Uint160
	TransactionsLength *big.Int
}

// 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
}

// 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 provided contract hash and the given Invoker.
func NewReader(invoker Invoker, hash util.Uint160) *ContractReader {
	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.
// NULL item is returned as nil pointer without error.
func itemToLedgerBlock(item stackitem.Item, err error) (*LedgerBlock, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(LedgerBlock)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *LedgerBlock is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&LedgerBlock{})

// Ensure *LedgerBlock is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&LedgerBlock{})

// FromStackItem retrieves fields of LedgerBlock from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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) != 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.PrimaryIndex, err = arr[index].TryInteger()
	if err != nil {
		return fmt.Errorf("field PrimaryIndex: %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
}

// ToStackItem creates [stackitem.Item] representing LedgerBlock.
// It implements [stackitem.Convertible] interface.
func (res *LedgerBlock) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 10)
	)
	itm, err = stackitem.NewByteArray(res.Hash.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Hash: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Version), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Version: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.PrevHash.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field PrevHash: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.MerkleRoot.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field MerkleRoot: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Timestamp), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Timestamp: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Nonce), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Nonce: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Index), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Index: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.PrimaryIndex), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field PrimaryIndex: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.NextConsensus.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field NextConsensus: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.TransactionsLength), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field TransactionsLength: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing LedgerBlock.
// It implements [smartcontract.Convertible] interface so that LedgerBlock
// could be used with invokers.
func (res *LedgerBlock) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 10)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Hash)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Hash: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Version)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Version: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.PrevHash)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field PrevHash: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.MerkleRoot)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field MerkleRoot: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Timestamp)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Timestamp: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Nonce)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Nonce: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Index)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Index: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.PrimaryIndex)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field PrimaryIndex: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.NextConsensus)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field NextConsensus: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.TransactionsLength)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field TransactionsLength: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToLedgerTransaction converts stack item into *LedgerTransaction.
// NULL item is returned as nil pointer without error.
func itemToLedgerTransaction(item stackitem.Item, err error) (*LedgerTransaction, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(LedgerTransaction)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *LedgerTransaction is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&LedgerTransaction{})

// Ensure *LedgerTransaction is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&LedgerTransaction{})

// FromStackItem retrieves fields of LedgerTransaction from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing LedgerTransaction.
// It implements [stackitem.Convertible] interface.
func (res *LedgerTransaction) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 8)
	)
	itm, err = stackitem.NewByteArray(res.Hash.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Hash: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Version), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Version: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Nonce), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Nonce: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.Sender.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Sender: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.SysFee), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field SysFee: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.NetFee), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field NetFee: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.ValidUntilBlock), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field ValidUntilBlock: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.Script), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Script: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing LedgerTransaction.
// It implements [smartcontract.Convertible] interface so that LedgerTransaction
// could be used with invokers.
func (res *LedgerTransaction) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 8)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Hash)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Hash: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Version)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Version: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Nonce)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Nonce: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Sender)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Sender: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.SysFee)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field SysFee: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.NetFee)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field NetFee: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.ValidUntilBlock)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field ValidUntilBlock: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Script)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Script: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementABI converts stack item into *ManagementABI.
// NULL item is returned as nil pointer without error.
func itemToManagementABI(item stackitem.Item, err error) (*ManagementABI, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementABI)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementABI is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementABI{})

// Ensure *ManagementABI is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementABI{})

// FromStackItem retrieves fields of ManagementABI from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementABI.
// It implements [stackitem.Convertible] interface.
func (res *ManagementABI) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 2)
	)
	itm, err = func(in []*ManagementMethod) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := v.ToStackItem()
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Methods)
	if err != nil {
		return nil, fmt.Errorf("field Methods: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []*ManagementEvent) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := v.ToStackItem()
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Events)
	if err != nil {
		return nil, fmt.Errorf("field Events: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementABI.
// It implements [smartcontract.Convertible] interface so that ManagementABI
// could be used with invokers.
func (res *ManagementABI) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 2)
	)
	prm, err = func(in []*ManagementMethod) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := v.ToSCParameter()
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Methods)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Methods: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []*ManagementEvent) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := v.ToSCParameter()
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Events)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Events: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementContract converts stack item into *ManagementContract.
// NULL item is returned as nil pointer without error.
func itemToManagementContract(item stackitem.Item, err error) (*ManagementContract, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementContract)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementContract is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementContract{})

// Ensure *ManagementContract is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementContract{})

// FromStackItem retrieves fields of ManagementContract from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementContract.
// It implements [stackitem.Convertible] interface.
func (res *ManagementContract) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 5)
	)
	itm, err = (*stackitem.BigInteger)(res.ID), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field ID: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.UpdateCounter), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field UpdateCounter: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.Hash.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Hash: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.NEF), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field NEF: %w", err)
	}
	items = append(items, itm)

	itm, err = res.Manifest.ToStackItem()
	if err != nil {
		return nil, fmt.Errorf("field Manifest: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementContract.
// It implements [smartcontract.Convertible] interface so that ManagementContract
// could be used with invokers.
func (res *ManagementContract) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 5)
	)
	prm, err = smartcontract.NewParameterFromValue(res.ID)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field ID: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.UpdateCounter)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field UpdateCounter: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Hash)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Hash: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.NEF)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field NEF: %w", err)
	}
	prms = append(prms, prm)

	prm, err = res.Manifest.ToSCParameter()
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Manifest: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementEvent converts stack item into *ManagementEvent.
// NULL item is returned as nil pointer without error.
func itemToManagementEvent(item stackitem.Item, err error) (*ManagementEvent, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementEvent)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementEvent is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementEvent{})

// Ensure *ManagementEvent is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementEvent{})

// FromStackItem retrieves fields of ManagementEvent from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementEvent.
// It implements [stackitem.Convertible] interface.
func (res *ManagementEvent) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 2)
	)
	itm, err = stackitem.NewByteArray([]byte(res.Name)), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Name: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []*ManagementParameter) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := v.ToStackItem()
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Params)
	if err != nil {
		return nil, fmt.Errorf("field Params: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementEvent.
// It implements [smartcontract.Convertible] interface so that ManagementEvent
// could be used with invokers.
func (res *ManagementEvent) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 2)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Name)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Name: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []*ManagementParameter) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := v.ToSCParameter()
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Params)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Params: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementGroup converts stack item into *ManagementGroup.
// NULL item is returned as nil pointer without error.
func itemToManagementGroup(item stackitem.Item, err error) (*ManagementGroup, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementGroup)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementGroup is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementGroup{})

// Ensure *ManagementGroup is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementGroup{})

// FromStackItem retrieves fields of ManagementGroup from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementGroup.
// It implements [stackitem.Convertible] interface.
func (res *ManagementGroup) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 2)
	)
	itm, err = stackitem.NewByteArray(res.PublicKey.Bytes()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field PublicKey: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.Signature), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Signature: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementGroup.
// It implements [smartcontract.Convertible] interface so that ManagementGroup
// could be used with invokers.
func (res *ManagementGroup) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 2)
	)
	prm, err = smartcontract.NewParameterFromValue(res.PublicKey)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field PublicKey: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Signature)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Signature: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementManifest converts stack item into *ManagementManifest.
// NULL item is returned as nil pointer without error.
func itemToManagementManifest(item stackitem.Item, err error) (*ManagementManifest, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementManifest)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementManifest is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementManifest{})

// Ensure *ManagementManifest is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementManifest{})

// FromStackItem retrieves fields of ManagementManifest from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementManifest.
// It implements [stackitem.Convertible] interface.
func (res *ManagementManifest) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 8)
	)
	itm, err = stackitem.NewByteArray([]byte(res.Name)), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Name: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []*ManagementGroup) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := v.ToStackItem()
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Groups)
	if err != nil {
		return nil, fmt.Errorf("field Groups: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in map[string]string) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var m = stackitem.NewMap()
		for k, v := range in {
			iKey, err := stackitem.NewByteArray([]byte(k)), error(nil)
			if err != nil {
				return nil, fmt.Errorf("key %v: %w", k, err)
			}
			iVal, err := stackitem.NewByteArray([]byte(v)), error(nil)
			if err != nil {
				return nil, fmt.Errorf("key %v, wrong value: %w", k, err)
			}
			m.Add(iKey, iVal)
		}
		return m, nil
	}(res.Features)
	if err != nil {
		return nil, fmt.Errorf("field Features: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []string) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := stackitem.NewByteArray([]byte(v)), error(nil)
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.SupportedStandards)
	if err != nil {
		return nil, fmt.Errorf("field SupportedStandards: %w", err)
	}
	items = append(items, itm)

	itm, err = res.ABI.ToStackItem()
	if err != nil {
		return nil, fmt.Errorf("field ABI: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []*ManagementPermission) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := v.ToStackItem()
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Permissions)
	if err != nil {
		return nil, fmt.Errorf("field Permissions: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []util.Uint160) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := stackitem.NewByteArray(v.BytesBE()), error(nil)
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Trusts)
	if err != nil {
		return nil, fmt.Errorf("field Trusts: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.TryMake(res.Extra)
	if err != nil {
		return nil, fmt.Errorf("field Extra: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementManifest.
// It implements [smartcontract.Convertible] interface so that ManagementManifest
// could be used with invokers.
func (res *ManagementManifest) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 8)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Name)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Name: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []*ManagementGroup) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := v.ToSCParameter()
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Groups)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Groups: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in map[string]string) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.ParameterPair, 0, len(in))
		for k, v := range in {
			iKey, err := smartcontract.NewParameterFromValue(k)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("key %v: %w", k, err)
			}
			iVal, err := smartcontract.NewParameterFromValue(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("key %v, wrong value: %w", k, err)
			}
			prms = append(prms, smartcontract.ParameterPair{Key: iKey, Value: iVal})
		}
		return smartcontract.Parameter{Type: smartcontract.MapType, Value: prms}, nil
	}(res.Features)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Features: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []string) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := smartcontract.NewParameterFromValue(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.SupportedStandards)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field SupportedStandards: %w", err)
	}
	prms = append(prms, prm)

	prm, err = res.ABI.ToSCParameter()
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field ABI: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []*ManagementPermission) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := v.ToSCParameter()
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Permissions)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Permissions: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []util.Uint160) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := smartcontract.NewParameterFromValue(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Trusts)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Trusts: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Extra)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Extra: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementMethod converts stack item into *ManagementMethod.
// NULL item is returned as nil pointer without error.
func itemToManagementMethod(item stackitem.Item, err error) (*ManagementMethod, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementMethod)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementMethod is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementMethod{})

// Ensure *ManagementMethod is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementMethod{})

// FromStackItem retrieves fields of ManagementMethod from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementMethod.
// It implements [stackitem.Convertible] interface.
func (res *ManagementMethod) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 5)
	)
	itm, err = stackitem.NewByteArray([]byte(res.Name)), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Name: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []*ManagementParameter) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := v.ToStackItem()
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Params)
	if err != nil {
		return nil, fmt.Errorf("field Params: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.ReturnType), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field ReturnType: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Offset), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Offset: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewBool(res.Safe), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Safe: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementMethod.
// It implements [smartcontract.Convertible] interface so that ManagementMethod
// could be used with invokers.
func (res *ManagementMethod) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 5)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Name)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Name: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []*ManagementParameter) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := v.ToSCParameter()
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Params)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Params: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.ReturnType)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field ReturnType: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Offset)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Offset: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Safe)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Safe: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementParameter converts stack item into *ManagementParameter.
// NULL item is returned as nil pointer without error.
func itemToManagementParameter(item stackitem.Item, err error) (*ManagementParameter, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementParameter)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementParameter is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementParameter{})

// Ensure *ManagementParameter is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementParameter{})

// FromStackItem retrieves fields of ManagementParameter from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementParameter.
// It implements [stackitem.Convertible] interface.
func (res *ManagementParameter) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 2)
	)
	itm, err = stackitem.NewByteArray([]byte(res.Name)), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Name: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Type), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Type: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementParameter.
// It implements [smartcontract.Convertible] interface so that ManagementParameter
// could be used with invokers.
func (res *ManagementParameter) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 2)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Name)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Name: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Type)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Type: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToManagementPermission converts stack item into *ManagementPermission.
// NULL item is returned as nil pointer without error.
func itemToManagementPermission(item stackitem.Item, err error) (*ManagementPermission, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(ManagementPermission)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *ManagementPermission is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&ManagementPermission{})

// Ensure *ManagementPermission is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&ManagementPermission{})

// FromStackItem retrieves fields of ManagementPermission from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing ManagementPermission.
// It implements [stackitem.Convertible] interface.
func (res *ManagementPermission) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 2)
	)
	itm, err = stackitem.NewByteArray(res.Contract.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Contract: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []string) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := stackitem.NewByteArray([]byte(v)), error(nil)
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.Methods)
	if err != nil {
		return nil, fmt.Errorf("field Methods: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing ManagementPermission.
// It implements [smartcontract.Convertible] interface so that ManagementPermission
// could be used with invokers.
func (res *ManagementPermission) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 2)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Contract)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Contract: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []string) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := smartcontract.NewParameterFromValue(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.Methods)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Methods: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}

// itemToStructsInternal converts stack item into *StructsInternal.
// NULL item is returned as nil pointer without error.
func itemToStructsInternal(item stackitem.Item, err error) (*StructsInternal, error) {
	if err != nil {
		return nil, err
	}
	_, null := item.(stackitem.Null)
	if null {
		return nil, nil
	}
	var res = new(StructsInternal)
	err = res.FromStackItem(item)
	return res, err
}

// Ensure *StructsInternal is a proper [stackitem.Convertible].
var _ = stackitem.Convertible(&StructsInternal{})

// Ensure *StructsInternal is a proper [smartcontract.Convertible].
var _ = smartcontract.Convertible(&StructsInternal{})

// FromStackItem retrieves fields of StructsInternal from the given
// [stackitem.Item] or returns an error if it's not possible to do to so.
// It implements [stackitem.Convertible] interface.
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
}

// ToStackItem creates [stackitem.Item] representing StructsInternal.
// It implements [stackitem.Convertible] interface.
func (res *StructsInternal) ToStackItem() (stackitem.Item, error) {
	if res == nil {
		return stackitem.Null{}, nil
	}

	var (
		err   error
		itm   stackitem.Item
		items = make([]stackitem.Item, 0, 14)
	)
	itm, err = stackitem.NewBool(res.Bool), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Bool: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.Int), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Int: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.Bytes), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Bytes: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray([]byte(res.String)), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field String: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.H160.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field H160: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.H256.BytesBE()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field H256: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.PK.Bytes()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field PK: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.PubKey.Bytes()), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field PubKey: %w", err)
	}
	items = append(items, itm)

	itm, err = stackitem.NewByteArray(res.Sign), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field Sign: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in [][]byte) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := stackitem.NewByteArray(v), error(nil)
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.ArrOfBytes)
	if err != nil {
		return nil, fmt.Errorf("field ArrOfBytes: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in []util.Uint160) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var items = make([]stackitem.Item, 0, len(in))
		for i, v := range in {
			itm, err := stackitem.NewByteArray(v.BytesBE()), error(nil)
			if err != nil {
				return nil, fmt.Errorf("item %d: %w", i, err)
			}
			items = append(items, itm)
		}
		return stackitem.NewArray(items), nil
	}(res.ArrOfH160)
	if err != nil {
		return nil, fmt.Errorf("field ArrOfH160: %w", err)
	}
	items = append(items, itm)

	itm, err = func(in map[*big.Int]keys.PublicKeys) (stackitem.Item, error) {
		if in == nil {
			return stackitem.Null{}, nil
		}

		var m = stackitem.NewMap()
		for k, v := range in {
			iKey, err := (*stackitem.BigInteger)(k), error(nil)
			if err != nil {
				return nil, fmt.Errorf("key %v: %w", k, err)
			}
			iVal, err := func(in keys.PublicKeys) (stackitem.Item, error) {
				if in == nil {
					return stackitem.Null{}, nil
				}

				var items = make([]stackitem.Item, 0, len(in))
				for i, v := range in {
					itm, err := stackitem.NewByteArray(v.Bytes()), error(nil)
					if err != nil {
						return nil, fmt.Errorf("item %d: %w", i, err)
					}
					items = append(items, itm)
				}
				return stackitem.NewArray(items), nil
			}(v)
			if err != nil {
				return nil, fmt.Errorf("key %v, wrong value: %w", k, err)
			}
			m.Add(iKey, iVal)
		}
		return m, nil
	}(res.Map)
	if err != nil {
		return nil, fmt.Errorf("field Map: %w", err)
	}
	items = append(items, itm)

	itm, err = res.Struct.ToStackItem()
	if err != nil {
		return nil, fmt.Errorf("field Struct: %w", err)
	}
	items = append(items, itm)

	itm, err = (*stackitem.BigInteger)(res.UnexportedField), error(nil)
	if err != nil {
		return nil, fmt.Errorf("field UnexportedField: %w", err)
	}
	items = append(items, itm)

	return stackitem.NewStruct(items), nil
}

// ToSCParameter creates [smartcontract.Parameter] representing StructsInternal.
// It implements [smartcontract.Convertible] interface so that StructsInternal
// could be used with invokers.
func (res *StructsInternal) ToSCParameter() (smartcontract.Parameter, error) {
	if res == nil {
		return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
	}

	var (
		err  error
		prm  smartcontract.Parameter
		prms = make([]smartcontract.Parameter, 0, 14)
	)
	prm, err = smartcontract.NewParameterFromValue(res.Bool)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Bool: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Int)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Int: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Bytes)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Bytes: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.String)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field String: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.H160)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field H160: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.H256)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field H256: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.PK)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field PK: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.PubKey)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field PubKey: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.Sign)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Sign: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in [][]byte) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := smartcontract.NewParameterFromValue(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.ArrOfBytes)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field ArrOfBytes: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in []util.Uint160) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.Parameter, 0, len(in))
		for i, v := range in {
			prm, err := smartcontract.NewParameterFromValue(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
			}
			prms = append(prms, prm)
		}
		return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
	}(res.ArrOfH160)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field ArrOfH160: %w", err)
	}
	prms = append(prms, prm)

	prm, err = func(in map[*big.Int]keys.PublicKeys) (smartcontract.Parameter, error) {
		if in == nil {
			return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
		}

		var prms = make([]smartcontract.ParameterPair, 0, len(in))
		for k, v := range in {
			iKey, err := smartcontract.NewParameterFromValue(k)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("key %v: %w", k, err)
			}
			iVal, err := func(in keys.PublicKeys) (smartcontract.Parameter, error) {
				if in == nil {
					return smartcontract.Parameter{Type: smartcontract.AnyType}, nil
				}

				var prms = make([]smartcontract.Parameter, 0, len(in))
				for i, v := range in {
					prm, err := smartcontract.NewParameterFromValue(v)
					if err != nil {
						return smartcontract.Parameter{}, fmt.Errorf("item %d: %w", i, err)
					}
					prms = append(prms, prm)
				}
				return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
			}(v)
			if err != nil {
				return smartcontract.Parameter{}, fmt.Errorf("key %v, wrong value: %w", k, err)
			}
			prms = append(prms, smartcontract.ParameterPair{Key: iKey, Value: iVal})
		}
		return smartcontract.Parameter{Type: smartcontract.MapType, Value: prms}, nil
	}(res.Map)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Map: %w", err)
	}
	prms = append(prms, prm)

	prm, err = res.Struct.ToSCParameter()
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field Struct: %w", err)
	}
	prms = append(prms, prm)

	prm, err = smartcontract.NewParameterFromValue(res.UnexportedField)
	if err != nil {
		return smartcontract.Parameter{}, fmt.Errorf("field UnexportedField: %w", err)
	}
	prms = append(prms, prm)

	return smartcontract.Parameter{Type: smartcontract.ArrayType, Value: prms}, nil
}
