github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/compiler/native_test.go (about)

     1  package compiler_test
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/nspcc-dev/neo-go/pkg/compiler"
    13  	"github.com/nspcc-dev/neo-go/pkg/config"
    14  	"github.com/nspcc-dev/neo-go/pkg/config/limits"
    15  	"github.com/nspcc-dev/neo-go/pkg/core/interop"
    16  	"github.com/nspcc-dev/neo-go/pkg/core/native"
    17  	"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
    18  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
    19  	"github.com/nspcc-dev/neo-go/pkg/interop/native/crypto"
    20  	"github.com/nspcc-dev/neo-go/pkg/interop/native/gas"
    21  	"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
    22  	"github.com/nspcc-dev/neo-go/pkg/interop/native/management"
    23  	"github.com/nspcc-dev/neo-go/pkg/interop/native/neo"
    24  	"github.com/nspcc-dev/neo-go/pkg/interop/native/notary"
    25  	"github.com/nspcc-dev/neo-go/pkg/interop/native/oracle"
    26  	"github.com/nspcc-dev/neo-go/pkg/interop/native/policy"
    27  	"github.com/nspcc-dev/neo-go/pkg/interop/native/roles"
    28  	"github.com/nspcc-dev/neo-go/pkg/interop/native/std"
    29  	"github.com/nspcc-dev/neo-go/pkg/interop/storage"
    30  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
    31  	"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
    32  	"github.com/nspcc-dev/neo-go/pkg/vm"
    33  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
    34  	"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
    35  	"github.com/stretchr/testify/require"
    36  )
    37  
    38  func TestContractHashes(t *testing.T) {
    39  	cfg := config.ProtocolConfiguration{P2PSigExtensions: true}
    40  	cs := native.NewContracts(cfg)
    41  	require.Equalf(t, []byte(neo.Hash), cs.NEO.Hash.BytesBE(), "%q", string(cs.NEO.Hash.BytesBE()))
    42  	require.Equalf(t, []byte(gas.Hash), cs.GAS.Hash.BytesBE(), "%q", string(cs.GAS.Hash.BytesBE()))
    43  	require.Equalf(t, []byte(oracle.Hash), cs.Oracle.Hash.BytesBE(), "%q", string(cs.Oracle.Hash.BytesBE()))
    44  	require.Equalf(t, []byte(roles.Hash), cs.Designate.Hash.BytesBE(), "%q", string(cs.Designate.Hash.BytesBE()))
    45  	require.Equalf(t, []byte(policy.Hash), cs.Policy.Hash.BytesBE(), "%q", string(cs.Policy.Hash.BytesBE()))
    46  	require.Equalf(t, []byte(ledger.Hash), cs.Ledger.Hash.BytesBE(), "%q", string(cs.Ledger.Hash.BytesBE()))
    47  	require.Equalf(t, []byte(management.Hash), cs.Management.Hash.BytesBE(), "%q", string(cs.Management.Hash.BytesBE()))
    48  	require.Equalf(t, []byte(notary.Hash), cs.Notary.Hash.BytesBE(), "%q", string(cs.Notary.Hash.BytesBE()))
    49  	require.Equalf(t, []byte(crypto.Hash), cs.Crypto.Hash.BytesBE(), "%q", string(cs.Crypto.Hash.BytesBE()))
    50  	require.Equalf(t, []byte(std.Hash), cs.Std.Hash.BytesBE(), "%q", string(cs.Std.Hash.BytesBE()))
    51  }
    52  
    53  func TestContractParameterTypes(t *testing.T) {
    54  	require.EqualValues(t, management.AnyType, smartcontract.AnyType)
    55  	require.EqualValues(t, management.BoolType, smartcontract.BoolType)
    56  	require.EqualValues(t, management.IntegerType, smartcontract.IntegerType)
    57  	require.EqualValues(t, management.ByteArrayType, smartcontract.ByteArrayType)
    58  	require.EqualValues(t, management.StringType, smartcontract.StringType)
    59  	require.EqualValues(t, management.Hash160Type, smartcontract.Hash160Type)
    60  	require.EqualValues(t, management.Hash256Type, smartcontract.Hash256Type)
    61  	require.EqualValues(t, management.PublicKeyType, smartcontract.PublicKeyType)
    62  	require.EqualValues(t, management.SignatureType, smartcontract.SignatureType)
    63  	require.EqualValues(t, management.ArrayType, smartcontract.ArrayType)
    64  	require.EqualValues(t, management.MapType, smartcontract.MapType)
    65  	require.EqualValues(t, management.InteropInterfaceType, smartcontract.InteropInterfaceType)
    66  	require.EqualValues(t, management.VoidType, smartcontract.VoidType)
    67  }
    68  
    69  func TestRoleManagementRole(t *testing.T) {
    70  	require.EqualValues(t, noderoles.Oracle, roles.Oracle)
    71  	require.EqualValues(t, noderoles.StateValidator, roles.StateValidator)
    72  	require.EqualValues(t, noderoles.NeoFSAlphabet, roles.NeoFSAlphabet)
    73  	require.EqualValues(t, noderoles.P2PNotary, roles.P2PNotary)
    74  }
    75  
    76  func TestCryptoLibNamedCurve(t *testing.T) {
    77  	require.EqualValues(t, native.Secp256k1Sha256, crypto.Secp256k1Sha256)
    78  	require.EqualValues(t, native.Secp256r1Sha256, crypto.Secp256r1Sha256)
    79  	require.EqualValues(t, native.Secp256k1Keccak256, crypto.Secp256k1Keccak256)
    80  	require.EqualValues(t, native.Secp256r1Keccak256, crypto.Secp256r1Keccak256)
    81  }
    82  
    83  func TestOracleContractValues(t *testing.T) {
    84  	require.EqualValues(t, oracle.Success, transaction.Success)
    85  	require.EqualValues(t, oracle.ProtocolNotSupported, transaction.ProtocolNotSupported)
    86  	require.EqualValues(t, oracle.ConsensusUnreachable, transaction.ConsensusUnreachable)
    87  	require.EqualValues(t, oracle.NotFound, transaction.NotFound)
    88  	require.EqualValues(t, oracle.Timeout, transaction.Timeout)
    89  	require.EqualValues(t, oracle.Forbidden, transaction.Forbidden)
    90  	require.EqualValues(t, oracle.ResponseTooLarge, transaction.ResponseTooLarge)
    91  	require.EqualValues(t, oracle.InsufficientFunds, transaction.InsufficientFunds)
    92  	require.EqualValues(t, oracle.Error, transaction.Error)
    93  
    94  	require.EqualValues(t, oracle.MinimumResponseGas, native.MinimumResponseGas)
    95  }
    96  
    97  func TestLedgerTransactionWitnessScope(t *testing.T) {
    98  	require.EqualValues(t, ledger.None, transaction.None)
    99  	require.EqualValues(t, ledger.CalledByEntry, transaction.CalledByEntry)
   100  	require.EqualValues(t, ledger.CustomContracts, transaction.CustomContracts)
   101  	require.EqualValues(t, ledger.CustomGroups, transaction.CustomGroups)
   102  	require.EqualValues(t, ledger.Rules, transaction.Rules)
   103  	require.EqualValues(t, ledger.Global, transaction.Global)
   104  }
   105  
   106  func TestLedgerTransactionWitnessAction(t *testing.T) {
   107  	require.EqualValues(t, ledger.WitnessAllow, transaction.WitnessAllow)
   108  	require.EqualValues(t, ledger.WitnessDeny, transaction.WitnessDeny)
   109  }
   110  
   111  func TestLedgerTransactionWitnessCondition(t *testing.T) {
   112  	require.EqualValues(t, ledger.WitnessBoolean, transaction.WitnessBoolean)
   113  	require.EqualValues(t, ledger.WitnessNot, transaction.WitnessNot)
   114  	require.EqualValues(t, ledger.WitnessAnd, transaction.WitnessAnd)
   115  	require.EqualValues(t, ledger.WitnessOr, transaction.WitnessOr)
   116  	require.EqualValues(t, ledger.WitnessScriptHash, transaction.WitnessScriptHash)
   117  	require.EqualValues(t, ledger.WitnessGroup, transaction.WitnessGroup)
   118  	require.EqualValues(t, ledger.WitnessCalledByEntry, transaction.WitnessCalledByEntry)
   119  	require.EqualValues(t, ledger.WitnessCalledByContract, transaction.WitnessCalledByContract)
   120  	require.EqualValues(t, ledger.WitnessCalledByGroup, transaction.WitnessCalledByGroup)
   121  }
   122  
   123  func TestLedgerVMStates(t *testing.T) {
   124  	require.EqualValues(t, ledger.NoneState, vmstate.None)
   125  	require.EqualValues(t, ledger.HaltState, vmstate.Halt)
   126  	require.EqualValues(t, ledger.FaultState, vmstate.Fault)
   127  	require.EqualValues(t, ledger.BreakState, vmstate.Break)
   128  }
   129  
   130  func TestPolicyAttributeType(t *testing.T) {
   131  	require.EqualValues(t, policy.HighPriorityT, transaction.HighPriority)
   132  	require.EqualValues(t, policy.OracleResponseT, transaction.OracleResponseT)
   133  	require.EqualValues(t, policy.NotValidBeforeT, transaction.NotValidBeforeT)
   134  	require.EqualValues(t, policy.ConflictsT, transaction.ConflictsT)
   135  	require.EqualValues(t, policy.NotaryAssistedT, transaction.NotaryAssistedT)
   136  }
   137  
   138  func TestStorageLimits(t *testing.T) {
   139  	require.EqualValues(t, storage.MaxKeyLen, limits.MaxStorageKeyLen)
   140  	require.EqualValues(t, storage.MaxValueLen, limits.MaxStorageValueLen)
   141  }
   142  
   143  type nativeTestCase struct {
   144  	method string
   145  	params []string
   146  }
   147  
   148  // Here we test that corresponding method does exist, is invoked and correct value is returned.
   149  func TestNativeHelpersCompile(t *testing.T) {
   150  	cfg := config.ProtocolConfiguration{P2PSigExtensions: true}
   151  	cs := native.NewContracts(cfg)
   152  	u160 := `interop.Hash160("aaaaaaaaaaaaaaaaaaaa")`
   153  	u256 := `interop.Hash256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")`
   154  	pub := `interop.PublicKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")`
   155  	sig := `interop.Signature("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")`
   156  	nep17TestCases := []nativeTestCase{
   157  		{"balanceOf", []string{u160}},
   158  		{"decimals", nil},
   159  		{"symbol", nil},
   160  		{"totalSupply", nil},
   161  		{"transfer", []string{u160, u160, "123", "nil"}},
   162  	}
   163  	runNativeTestCases(t, cs.NEO.ContractMD, "neo", append([]nativeTestCase{
   164  		{"getCandidates", nil},
   165  		{"getAllCandidates", nil},
   166  		{"getCandidateVote", []string{pub}},
   167  		{"getCommittee", nil},
   168  		{"getCommitteeAddress", nil},
   169  		{"getGasPerBlock", nil},
   170  		{"getNextBlockValidators", nil},
   171  		{"getRegisterPrice", nil},
   172  		{"registerCandidate", []string{pub}},
   173  		{"setGasPerBlock", []string{"1"}},
   174  		{"setRegisterPrice", []string{"10"}},
   175  		{"vote", []string{u160, pub}},
   176  		{"unclaimedGas", []string{u160, "123"}},
   177  		{"unregisterCandidate", []string{pub}},
   178  		{"getAccountState", []string{u160}},
   179  	}, nep17TestCases...))
   180  	runNativeTestCases(t, cs.GAS.ContractMD, "gas", nep17TestCases)
   181  	runNativeTestCases(t, cs.Oracle.ContractMD, "oracle", []nativeTestCase{
   182  		{"getPrice", nil},
   183  		{"request", []string{`"url"`, "nil", `"callback"`, "nil", "123"}},
   184  		{"setPrice", []string{"10"}},
   185  	})
   186  	runNativeTestCases(t, cs.Designate.ContractMD, "roles", []nativeTestCase{
   187  		{"designateAsRole", []string{"1", "[]interop.PublicKey{}"}},
   188  		{"getDesignatedByRole", []string{"1", "1000"}},
   189  	})
   190  	runNativeTestCases(t, cs.Policy.ContractMD, "policy", []nativeTestCase{
   191  		{"blockAccount", []string{u160}},
   192  		{"getExecFeeFactor", nil},
   193  		{"getFeePerByte", nil},
   194  		{"getStoragePrice", nil},
   195  		{"isBlocked", []string{u160}},
   196  		{"setExecFeeFactor", []string{"42"}},
   197  		{"setFeePerByte", []string{"42"}},
   198  		{"setStoragePrice", []string{"42"}},
   199  		{"unblockAccount", []string{u160}},
   200  		{"getAttributeFee", []string{"1"}},
   201  		{"setAttributeFee", []string{"1", "123"}},
   202  	})
   203  	runNativeTestCases(t, cs.Ledger.ContractMD, "ledger", []nativeTestCase{
   204  		{"currentHash", nil},
   205  		{"currentIndex", nil},
   206  		{"getBlock", []string{"1"}},
   207  		{"getTransaction", []string{u256}},
   208  		{"getTransactionFromBlock", []string{u256, "1"}},
   209  		{"getTransactionHeight", []string{u256}},
   210  		{"getTransactionSigners", []string{u256}},
   211  		{"getTransactionVMState", []string{u256}},
   212  	})
   213  	runNativeTestCases(t, cs.Notary.ContractMD, "notary", []nativeTestCase{
   214  		{"lockDepositUntil", []string{u160, "123"}},
   215  		{"withdraw", []string{u160, u160}},
   216  		{"balanceOf", []string{u160}},
   217  		{"expirationOf", []string{u160}},
   218  		{"getMaxNotValidBeforeDelta", nil},
   219  		{"setMaxNotValidBeforeDelta", []string{"42"}},
   220  	})
   221  	runNativeTestCases(t, cs.Management.ContractMD, "management", []nativeTestCase{
   222  		{"deploy", []string{"nil", "nil"}},
   223  		{"deployWithData", []string{"nil", "nil", "123"}},
   224  		{"destroy", nil},
   225  		{"getContract", []string{u160}},
   226  		{"getContractById", []string{"1"}},
   227  		{"getContractHashes", nil},
   228  		{"getMinimumDeploymentFee", nil},
   229  		{"hasMethod", []string{u160, `"method"`, "0"}},
   230  		{"setMinimumDeploymentFee", []string{"42"}},
   231  		{"update", []string{"nil", "nil"}},
   232  		{"updateWithData", []string{"nil", "nil", "123"}},
   233  	})
   234  	runNativeTestCases(t, cs.Crypto.ContractMD, "crypto", []nativeTestCase{
   235  		{"sha256", []string{"[]byte{1, 2, 3}"}},
   236  		{"ripemd160", []string{"[]byte{1, 2, 3}"}},
   237  		{"murmur32", []string{"[]byte{1, 2, 3}", "123"}},
   238  		{"verifyWithECDsa", []string{"[]byte{1, 2, 3}", pub, sig, "crypto.Secp256k1Sha256"}},
   239  		{"bls12381Serialize", []string{"crypto.Bls12381Point{}"}},
   240  		{"bls12381Deserialize", []string{"[]byte{1, 2, 3}"}},
   241  		{"bls12381Equal", []string{"crypto.Bls12381Point{}", "crypto.Bls12381Point{}"}},
   242  		{"bls12381Add", []string{"crypto.Bls12381Point{}", "crypto.Bls12381Point{}"}},
   243  		{"bls12381Mul", []string{"crypto.Bls12381Point{}", "[]byte{1, 2, 3}", "true"}},
   244  		{"bls12381Pairing", []string{"crypto.Bls12381Point{}", "crypto.Bls12381Point{}"}},
   245  		{"keccak256", []string{"[]byte{1, 2, 3}"}},
   246  	})
   247  	runNativeTestCases(t, cs.Std.ContractMD, "std", []nativeTestCase{
   248  		{"serialize", []string{"[]byte{1, 2, 3}"}},
   249  		{"deserialize", []string{"[]byte{1, 2, 3}"}},
   250  		{"jsonSerialize", []string{"[]byte{1, 2, 3}"}},
   251  		{"jsonDeserialize", []string{"[]byte{1, 2, 3}"}},
   252  		{"base64Encode", []string{"[]byte{1, 2, 3}"}},
   253  		{"base64Decode", []string{"[]byte{1, 2, 3}"}},
   254  		{"base58Encode", []string{"[]byte{1, 2, 3}"}},
   255  		{"base58Decode", []string{"[]byte{1, 2, 3}"}},
   256  		{"base58CheckEncode", []string{"[]byte{1, 2, 3}"}},
   257  		{"base58CheckDecode", []string{"[]byte{1, 2, 3}"}},
   258  		{"itoa", []string{"4", "10"}},
   259  		{"itoa10", []string{"4"}},
   260  		{"atoi", []string{`"4"`, "10"}},
   261  		{"atoi10", []string{`"4"`}},
   262  		{"memoryCompare", []string{"[]byte{1}", "[]byte{2}"}},
   263  		{"memorySearch", []string{"[]byte{1}", "[]byte{2}"}},
   264  		{"memorySearchIndex", []string{"[]byte{1}", "[]byte{2}", "3"}},
   265  		{"memorySearchLastIndex", []string{"[]byte{1}", "[]byte{2}", "3"}},
   266  		{"stringSplit", []string{`"a,b"`, `","`}},
   267  		{"stringSplitNonEmpty", []string{`"a,b"`, `","`}},
   268  	})
   269  }
   270  
   271  func runNativeTestCases(t *testing.T, ctr interop.ContractMD, name string, nativeTestCases []nativeTestCase) {
   272  	srcBuilder := bytes.NewBuffer([]byte(`package foo
   273  		import "github.com/nspcc-dev/neo-go/pkg/interop/native/` + name + `"
   274  		import "github.com/nspcc-dev/neo-go/pkg/interop"
   275  		var _ interop.Hash160
   276  	`))
   277  	for i, tc := range nativeTestCases {
   278  		addNativeTestCase(t, srcBuilder, ctr, i, name, tc.method, tc.params...)
   279  	}
   280  
   281  	ne, di, err := compiler.CompileWithOptions("file.go", strings.NewReader(srcBuilder.String()), nil)
   282  	require.NoError(t, err)
   283  
   284  	t.Run(ctr.Name, func(t *testing.T) {
   285  		for i, tc := range nativeTestCases {
   286  			t.Run(tc.method, func(t *testing.T) {
   287  				runNativeTestCase(t, ne, di, ctr, i, tc.method, tc.params...)
   288  			})
   289  		}
   290  	})
   291  }
   292  
   293  func getMethod(t *testing.T, ctr interop.ContractMD, name string, params []string) interop.HFSpecificMethodAndPrice {
   294  	paramLen := len(params)
   295  
   296  	switch {
   297  	case name == "itoa10" || name == "atoi10":
   298  		name = name[:4]
   299  	case strings.HasPrefix(name, "memorySearch"):
   300  		if strings.HasSuffix(name, "LastIndex") {
   301  			paramLen++ // true should be appended inside of an interop
   302  		}
   303  		name = "memorySearch"
   304  	case strings.HasPrefix(name, "stringSplit"):
   305  		if strings.HasSuffix(name, "NonEmpty") {
   306  			paramLen++ // true should be appended inside of an interop
   307  		}
   308  		name = "stringSplit"
   309  	default:
   310  		name = strings.TrimSuffix(name, "WithData")
   311  	}
   312  
   313  	latestHF := config.LatestHardfork()
   314  	cMD := ctr.HFSpecificContractMD(&latestHF)
   315  	md, ok := cMD.GetMethod(name, paramLen)
   316  	require.True(t, ok, cMD.Manifest.Name, name, paramLen)
   317  	return md
   318  }
   319  
   320  func addNativeTestCase(t *testing.T, srcBuilder *bytes.Buffer, ctr interop.ContractMD, i int, name, method string, params ...string) {
   321  	md := getMethod(t, ctr, method, params)
   322  	isVoid := md.MD.ReturnType == smartcontract.VoidType
   323  	srcBuilder.WriteString("func F" + strconv.Itoa(i) + "() ")
   324  	if !isVoid {
   325  		srcBuilder.WriteString("any { return ")
   326  	} else {
   327  		srcBuilder.WriteString("{ ")
   328  	}
   329  	methodUpper := strings.ToUpper(method[:1]) + method[1:] // ASCII only
   330  	methodUpper = strings.ReplaceAll(methodUpper, "Gas", "GAS")
   331  	methodUpper = strings.ReplaceAll(methodUpper, "Json", "JSON")
   332  	methodUpper = strings.ReplaceAll(methodUpper, "Id", "ID")
   333  	srcBuilder.WriteString(name)
   334  	srcBuilder.WriteRune('.')
   335  	srcBuilder.WriteString(methodUpper)
   336  	srcBuilder.WriteRune('(')
   337  	srcBuilder.WriteString(strings.Join(params, ", "))
   338  	srcBuilder.WriteString(") }\n")
   339  }
   340  
   341  func runNativeTestCase(t *testing.T, b *nef.File, di *compiler.DebugInfo, ctr interop.ContractMD, i int, method string, params ...string) {
   342  	md := getMethod(t, ctr, method, params)
   343  	result := getTestStackItem(md.MD.ReturnType)
   344  	isVoid := md.MD.ReturnType == smartcontract.VoidType
   345  
   346  	v := vm.New()
   347  	v.LoadToken = func(id int32) error {
   348  		t := b.Tokens[id]
   349  		if t.Hash != ctr.Hash {
   350  			return fmt.Errorf("wrong hash %s", t.Hash.StringLE())
   351  		}
   352  		if t.Method != md.MD.Name {
   353  			return fmt.Errorf("wrong name %s", t.Method)
   354  		}
   355  		if int(t.ParamCount) != len(md.MD.Parameters) {
   356  			return fmt.Errorf("wrong number of parameters %v", t.ParamCount)
   357  		}
   358  		if t.HasReturn != !isVoid {
   359  			return fmt.Errorf("wrong hasReturn %v", t.HasReturn)
   360  		}
   361  		if t.CallFlag != md.RequiredFlags {
   362  			return fmt.Errorf("wrong flags %v", t.CallFlag)
   363  		}
   364  		for i := 0; i < int(t.ParamCount); i++ {
   365  			_ = v.Estack().Pop()
   366  		}
   367  		if v.Estack().Len() != 0 {
   368  			return errors.New("excessive parameters on the stack")
   369  		}
   370  		if !isVoid {
   371  			v.Estack().PushVal(result)
   372  		}
   373  		return nil
   374  	}
   375  	invokeMethod(t, fmt.Sprintf("F%d", i), b.Script, v, di)
   376  	require.NoError(t, v.Run())
   377  	if isVoid {
   378  		require.Equal(t, 0, v.Estack().Len())
   379  		return
   380  	}
   381  	require.Equal(t, 1, v.Estack().Len(), "stack contains unexpected items")
   382  	require.Equal(t, result.Value(), v.Estack().Pop().Item().Value())
   383  }
   384  
   385  func getTestStackItem(typ smartcontract.ParamType) stackitem.Item {
   386  	switch typ {
   387  	case smartcontract.AnyType, smartcontract.VoidType:
   388  		return stackitem.Null{}
   389  	case smartcontract.BoolType:
   390  		return stackitem.NewBool(true)
   391  	case smartcontract.IntegerType:
   392  		return stackitem.NewBigInteger(big.NewInt(42))
   393  	case smartcontract.ByteArrayType, smartcontract.StringType, smartcontract.Hash160Type,
   394  		smartcontract.Hash256Type, smartcontract.PublicKeyType, smartcontract.SignatureType:
   395  		return stackitem.NewByteArray([]byte("result"))
   396  	case smartcontract.ArrayType:
   397  		return stackitem.NewArray([]stackitem.Item{stackitem.NewBool(true), stackitem.Null{}})
   398  	case smartcontract.MapType:
   399  		return stackitem.NewMapWithValue([]stackitem.MapElement{{
   400  			Key:   stackitem.NewByteArray([]byte{1, 2, 3}),
   401  			Value: stackitem.NewByteArray([]byte{5, 6, 7}),
   402  		}})
   403  	case smartcontract.InteropInterfaceType:
   404  		return stackitem.NewInterop(42)
   405  	default:
   406  		panic("unexpected type")
   407  	}
   408  }