github.com/ontio/ontology@v1.14.4/vm/neovm/stack_opcode_test.go (about)

     1  /*
     2   * Copyright (C) 2018 The ontology Authors
     3   * This file is part of The ontology library.
     4   *
     5   * The ontology is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU Lesser General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * The ontology is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU Lesser General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU Lesser General Public License
    16   * along with The ontology.  If not, see <http://www.gnu.org/licenses/>.
    17   */
    18  
    19  package neovm
    20  
    21  import (
    22  	"crypto/sha1"
    23  	"crypto/sha256"
    24  	"encoding/json"
    25  	"fmt"
    26  	"math"
    27  	"math/big"
    28  	"testing"
    29  
    30  	"github.com/ontio/ontology-crypto/keypair"
    31  	s "github.com/ontio/ontology-crypto/signature"
    32  	"github.com/ontio/ontology/vm/neovm/interfaces"
    33  	"github.com/ontio/ontology/vm/neovm/types"
    34  	"github.com/stretchr/testify/assert"
    35  	"golang.org/x/crypto/ripemd160"
    36  )
    37  
    38  type Value interface{}
    39  
    40  func value2json(t *testing.T, expect types.VmValue) string {
    41  	//e, err := expect.ConvertNeoVmValueHexString()
    42  	e, err := expect.Stringify()
    43  	assert.Nil(t, err)
    44  	exp, err := json.Marshal(e)
    45  	assert.Nil(t, err)
    46  
    47  	return string(exp)
    48  }
    49  
    50  func assertEqual(t *testing.T, expect, actual types.VmValue) {
    51  	assert.Equal(t, value2json(t, expect), value2json(t, actual))
    52  }
    53  
    54  func newVmValue(t *testing.T, data Value) types.VmValue {
    55  	switch v := data.(type) {
    56  	case int8, int16, int32, int64, int, uint8, uint16, uint32, uint64, *big.Int, big.Int:
    57  		val, err := types.VmValueFromBigInt(ToBigInt(v))
    58  		assert.Nil(t, err)
    59  		return val
    60  	case bool:
    61  		return types.VmValueFromBool(v)
    62  	case []byte:
    63  		val, err := types.VmValueFromBytes(v)
    64  		assert.Nil(t, err)
    65  		return val
    66  	case string:
    67  		val, err := types.VmValueFromBytes([]byte(v))
    68  		assert.Nil(t, err)
    69  		return val
    70  	case []Value:
    71  		arr := types.NewArrayValue()
    72  		for _, item := range v {
    73  			arr.Append(newVmValue(t, item))
    74  		}
    75  
    76  		return types.VmValueFromArrayVal(arr)
    77  	case map[interface{}]interface{}:
    78  		mp := types.NewMapValue()
    79  		for key, value := range v {
    80  			mp.Set(newVmValue(t, key), newVmValue(t, value))
    81  		}
    82  		return types.VmValueFromMapValue(mp)
    83  	case *types.StructValue:
    84  		return types.VmValueFromStructVal(data.(*types.StructValue))
    85  	case interfaces.Interop:
    86  		return types.VmValueFromInteropValue(types.NewInteropValue(v))
    87  	default:
    88  		panic(fmt.Sprintf("newVmValue Invalid Type:%t", v))
    89  	}
    90  }
    91  
    92  func checkStackOpCode(t *testing.T, code OpCode, origin, expected []Value) {
    93  	checkAltStackOpCode(t, code, [2][]Value{origin, {}}, [2][]Value{expected, {}})
    94  }
    95  
    96  func checkAltStackOpCode(t *testing.T, code OpCode, origin [2][]Value, expected [2][]Value) {
    97  	//checkAltStackOpCodeOld(t, []byte{byte(code)}, origin, expected)
    98  	checkAltStackOpCodeNew(t, []byte{byte(code)}, origin, expected)
    99  }
   100  
   101  func checkMultiStackOpCode(t *testing.T, code []OpCode, origin, expected []Value) {
   102  	var raw []byte
   103  	for _, c := range code {
   104  		raw = append(raw, byte(c))
   105  	}
   106  	checkMultiAltStackOpCode(t, raw, [2][]Value{origin, {}}, [2][]Value{expected, {}})
   107  }
   108  func checkMultiAltStackOpCode(t *testing.T, code []byte, origin [2][]Value, expected [2][]Value) {
   109  	var raw []byte
   110  	for _, c := range code {
   111  		raw = append(raw, byte(c))
   112  	}
   113  	//checkAltStackOpCodeOld(t, raw, origin, expected)
   114  	checkAltStackOpCodeNew(t, raw, origin, expected)
   115  }
   116  func checkMultiOpCode(t *testing.T, code []byte, origin []Value, expected []Value) {
   117  	var raw []byte
   118  	for _, c := range code {
   119  		raw = append(raw, byte(c))
   120  	}
   121  	//checkAltStackOpCodeOld(t, raw, [2][]Value{origin}, [2][]Value{expected})
   122  	checkAltStackOpCodeNew(t, raw, [2][]Value{origin}, [2][]Value{expected})
   123  }
   124  
   125  func checkAltStackOpCodeNew(t *testing.T, code []byte, origin [2][]Value, expected [2][]Value) {
   126  	executor := NewExecutor(code, VmFeatureFlag{})
   127  	for _, val := range origin[0] {
   128  		err := executor.EvalStack.Push(newVmValue(t, val))
   129  		assert.Nil(t, err)
   130  	}
   131  	for _, val := range origin[1] {
   132  		err := executor.AltStack.Push(newVmValue(t, val))
   133  		assert.Nil(t, err)
   134  	}
   135  	err := executor.Execute()
   136  	assert.Nil(t, err)
   137  	assert.Equal(t, len(expected[0]), executor.EvalStack.Count())
   138  	assert.Equal(t, len(expected[1]), executor.AltStack.Count())
   139  
   140  	stacks := [2]*ValueStack{executor.EvalStack, executor.AltStack}
   141  	for s, stack := range stacks {
   142  		expect := expected[s]
   143  		for i := 0; i < len(expect); i++ {
   144  			val := expect[len(expect)-i-1]
   145  			res, _ := stack.Pop()
   146  			exp := newVmValue(t, val)
   147  			assertEqual(t, res, exp)
   148  		}
   149  	}
   150  }
   151  
   152  func TestAltStackOpCode(t *testing.T) {
   153  	checkAltStackOpCode(t, DUPFROMALTSTACK, [2][]Value{
   154  		{8888},
   155  		{9999},
   156  	}, [2][]Value{
   157  		{8888, 9999},
   158  		{9999},
   159  	})
   160  
   161  	checkAltStackOpCode(t, TOALTSTACK, [2][]Value{
   162  		{8888},
   163  		{9999},
   164  	}, [2][]Value{
   165  		{},
   166  		{9999, 8888},
   167  	})
   168  
   169  	checkAltStackOpCode(t, FROMALTSTACK, [2][]Value{
   170  		{8888},
   171  		{9999},
   172  	}, [2][]Value{
   173  		{8888, 9999},
   174  		{},
   175  	})
   176  }
   177  
   178  func TestStackOpCode(t *testing.T) {
   179  	checkStackOpCode(t, SWAP, []Value{1, 2}, []Value{2, 1})
   180  	checkStackOpCode(t, XDROP, []Value{3, 2, 1}, []Value{2})
   181  	checkStackOpCode(t, XDROP, []Value{3, 2, 0}, []Value{3})
   182  	checkStackOpCode(t, XSWAP, []Value{3, 2, 1}, []Value{2, 3})
   183  	checkStackOpCode(t, XTUCK, []Value{3, 2, 1}, []Value{3, 2, 2})
   184  	checkStackOpCode(t, DEPTH, []Value{1, 2}, []Value{1, 2, 2})
   185  	checkStackOpCode(t, DROP, []Value{1, 2}, []Value{1})
   186  	checkStackOpCode(t, DUP, []Value{1, 2}, []Value{1, 2, 2})
   187  	checkStackOpCode(t, NIP, []Value{1, 2}, []Value{2})
   188  	checkStackOpCode(t, OVER, []Value{1, 2}, []Value{1, 2, 1})
   189  	checkStackOpCode(t, PICK, []Value{3, 2, 1}, []Value{3, 2, 3})
   190  	checkStackOpCode(t, ROLL, []Value{3, 2, 1}, []Value{2, 3})
   191  	checkStackOpCode(t, ROT, []Value{4, 3, 2, 1}, []Value{4, 2, 1, 3})
   192  	checkStackOpCode(t, ROT, []Value{1, 2, 3}, []Value{2, 3, 1})
   193  	checkStackOpCode(t, TUCK, []Value{1, 2}, []Value{2, 1, 2})
   194  
   195  	checkStackOpCode(t, INVERT, []Value{2}, []Value{-3})
   196  	checkStackOpCode(t, AND, []Value{1, 2}, []Value{0})
   197  	checkStackOpCode(t, OR, []Value{1, 2}, []Value{3})
   198  	checkStackOpCode(t, XOR, []Value{1, 2}, []Value{3})
   199  	checkStackOpCode(t, EQUAL, []Value{1, 2}, []Value{false})
   200  
   201  	checkStackOpCode(t, INC, []Value{1}, []Value{2})
   202  	checkStackOpCode(t, DEC, []Value{2}, []Value{1})
   203  	checkStackOpCode(t, SIGN, []Value{1}, []Value{1})
   204  	checkStackOpCode(t, NEGATE, []Value{1}, []Value{-1})
   205  	checkStackOpCode(t, ABS, []Value{-9999}, []Value{9999})
   206  	checkStackOpCode(t, ABS, []Value{9999}, []Value{9999})
   207  	a, _ := new(big.Int).SetString("-83786976294838206464", 10)
   208  	checkStackOpCode(t, ABS, []Value{a}, []Value{new(big.Int).Abs(a)})
   209  	checkStackOpCode(t, NOT, []Value{true}, []Value{false})
   210  
   211  	b, _ := new(big.Int).SetString("73786976294838206464", 10)
   212  	checkStackOpCode(t, SHL, []Value{1, new(big.Int).SetUint64(uint64(20))}, []Value{1 << 20})
   213  	checkStackOpCode(t, SHR, []Value{4, 1}, []Value{2})
   214  	checkStackOpCode(t, SHR, []Value{b, 10}, []Value{2 << 55})
   215  	checkStackOpCode(t, BOOLAND, []Value{1, 2}, []Value{1})
   216  	checkStackOpCode(t, BOOLOR, []Value{1, 2}, []Value{1})
   217  	checkStackOpCode(t, NUMEQUAL, []Value{1, 2}, []Value{false})
   218  	checkStackOpCode(t, NUMNOTEQUAL, []Value{1, 2}, []Value{1})
   219  	checkStackOpCode(t, LT, []Value{1, 2}, []Value{1})
   220  	checkStackOpCode(t, GT, []Value{1, 2}, []Value{false})
   221  	checkStackOpCode(t, LTE, []Value{1, 2}, []Value{1})
   222  	checkStackOpCode(t, GTE, []Value{1, 2}, []Value{false})
   223  	checkStackOpCode(t, MIN, []Value{1, 2}, []Value{1})
   224  	checkStackOpCode(t, MAX, []Value{1, 2}, []Value{2})
   225  }
   226  
   227  func TestArithmetic(t *testing.T) {
   228  
   229  	checkStackOpCode(t, ADD, []Value{1, 2}, []Value{3})
   230  	checkStackOpCode(t, SUB, []Value{1, 2}, []Value{-1})
   231  
   232  	checkStackOpCode(t, MUL, []Value{3, 2}, []Value{6})
   233  
   234  	checkStackOpCode(t, DIV, []Value{3, 2}, []Value{1})
   235  	checkStackOpCode(t, DIV, []Value{103, 2}, []Value{51})
   236  
   237  	checkStackOpCode(t, MOD, []Value{1, 2}, []Value{1})
   238  	checkStackOpCode(t, MOD, []Value{math.MaxInt64, 2}, []Value{1})
   239  	checkStackOpCode(t, MOD, []Value{-math.MaxInt64, 2}, []Value{-1})
   240  
   241  	checkStackOpCode(t, MAX, []Value{3, 2}, []Value{3})
   242  	checkStackOpCode(t, MAX, []Value{-3, 2}, []Value{2})
   243  
   244  	checkStackOpCode(t, MIN, []Value{3, 2}, []Value{2})
   245  	checkStackOpCode(t, MIN, []Value{-3, 2}, []Value{-3})
   246  
   247  	checkStackOpCode(t, SIGN, []Value{3}, []Value{1})
   248  	checkStackOpCode(t, SIGN, []Value{-3}, []Value{-1})
   249  	checkStackOpCode(t, SIGN, []Value{0}, []Value{0})
   250  
   251  	checkStackOpCode(t, INC, []Value{-10}, []Value{-9})
   252  	checkStackOpCode(t, DEC, []Value{-10}, []Value{-11})
   253  	checkStackOpCode(t, NEGATE, []Value{-10}, []Value{10})
   254  	checkStackOpCode(t, ABS, []Value{-10}, []Value{10})
   255  
   256  	checkStackOpCode(t, NOT, []Value{1}, []Value{false})
   257  	checkStackOpCode(t, NOT, []Value{0}, []Value{1})
   258  
   259  	checkStackOpCode(t, NZ, []Value{0}, []Value{false})
   260  	checkStackOpCode(t, NZ, []Value{-10}, []Value{true})
   261  	checkStackOpCode(t, NZ, []Value{10}, []Value{true})
   262  }
   263  
   264  func TestArrayOpCode(t *testing.T) {
   265  	checkStackOpCode(t, ARRAYSIZE, []Value{"12345"}, []Value{5})
   266  	checkStackOpCode(t, ARRAYSIZE, []Value{[]Value{1, 2, 3}}, []Value{3})
   267  	checkStackOpCode(t, ARRAYSIZE, []Value{[]Value{}}, []Value{0})
   268  
   269  	checkStackOpCode(t, PACK, []Value{"aaa", "bbb", "ccc", 3}, []Value{[]Value{"ccc", "bbb", "aaa"}})
   270  
   271  	checkStackOpCode(t, UNPACK, []Value{[]Value{"ccc", "bbb", "aaa"}}, []Value{"aaa", "bbb", "ccc", 3})
   272  
   273  	checkStackOpCode(t, PICKITEM, []Value{[]Value{"ccc", "bbb", "aaa"}, 0}, []Value{"ccc"})
   274  	checkStackOpCode(t, PICKITEM, []Value{[]Value{"ccc", "bbb", "aaa"}, 1}, []Value{"bbb"})
   275  
   276  	checkStackOpCode(t, NEWARRAY, []Value{int64(1)}, []Value{[]Value{false}})
   277  
   278  	checkMultiStackOpCode(t, []OpCode{TOALTSTACK, DUPFROMALTSTACK, PUSH1, REMOVE, FROMALTSTACK}, []Value{[]Value{"ccc", "bbb", "aaa"}}, []Value{[]Value{"ccc", "aaa"}})
   279  
   280  	checkMultiStackOpCode(t, []OpCode{TOALTSTACK, PUSH1, DUPFROMALTSTACK, PUSH2, XSWAP, SETITEM, FROMALTSTACK}, []Value{"ddd", []Value{"ccc", "bbb", "aaa"}}, []Value{[]Value{"ccc", "ddd", "aaa"}})
   281  
   282  	// reverse will pop the value from stack
   283  	checkStackOpCode(t, REVERSE, []Value{[]Value{"ccc", "bbb", "aaa"}}, []Value{})
   284  	checkMultiStackOpCode(t, []OpCode{TOALTSTACK, DUPFROMALTSTACK, REVERSE, FROMALTSTACK},
   285  		[]Value{[]Value{"ccc", "bbb", "aaa"}},
   286  		[]Value{[]Value{"aaa", "bbb", "ccc"}},
   287  	)
   288  
   289  	checkMultiStackOpCode(t, []OpCode{SWAP, TOALTSTACK, DUPFROMALTSTACK, SWAP, APPEND, FROMALTSTACK},
   290  		[]Value{[]Value{"aaa", "bbb", "ccc"}, "eee"},
   291  		[]Value{[]Value{"aaa", "bbb", "ccc", "eee"}},
   292  	)
   293  
   294  	checkStackOpCode(t, WITHIN, []Value{1, 2, 3}, []Value{false})
   295  }
   296  
   297  func TestMapValue(t *testing.T) {
   298  	mp := make(map[interface{}]interface{}, 0)
   299  	mp["key"] = "value"
   300  	mp["key2"] = "value2"
   301  
   302  	mp2 := make(map[interface{}]interface{}, 0)
   303  	mp2["key2"] = "value2"
   304  	checkMultiStackOpCode(t, []OpCode{SWAP, TOALTSTACK, DUPFROMALTSTACK, SWAP, REMOVE, FROMALTSTACK},
   305  		[]Value{mp, "key"},
   306  		[]Value{mp2},
   307  	)
   308  
   309  	checkMultiStackOpCode(t, []OpCode{HASKEY}, []Value{mp, "key"}, []Value{true})
   310  	checkMultiStackOpCode(t, []OpCode{KEYS}, []Value{mp}, []Value{[]Value{"key", "key2"}})
   311  	checkMultiStackOpCode(t, []OpCode{VALUES}, []Value{mp}, []Value{[]Value{"value", "value2"}})
   312  	checkMultiStackOpCode(t, []OpCode{PICKITEM}, []Value{mp, "key"}, []Value{"value"})
   313  	checkMultiStackOpCode(t, []OpCode{TOALTSTACK, DUPFROMALTSTACK, SETITEM, FROMALTSTACK},
   314  		[]Value{mp, "key", "value3"}, []Value{"value3"})
   315  	m := make(map[interface{}]interface{}, 0)
   316  	checkStackOpCode(t, NEWMAP, []Value{}, []Value{m})
   317  
   318  }
   319  func TestStructValue(t *testing.T) {
   320  	s := types.NewStructValue()
   321  	k, err := types.VmValueFromBytes([]byte("key"))
   322  	assert.Equal(t, err, nil)
   323  	v, err := types.VmValueFromBytes([]byte("value"))
   324  	assert.Equal(t, err, nil)
   325  	err = s.Append(k)
   326  	assert.Nil(t, err)
   327  	err = s.Append(v)
   328  	assert.Nil(t, err)
   329  	s4 := types.NewStructValue()
   330  	v2, err := types.VmValueFromBytes([]byte("value2"))
   331  	assert.Equal(t, err, nil)
   332  	err = s4.Append(k)
   333  	assert.Nil(t, err)
   334  	err = s4.Append(v2)
   335  	assert.Nil(t, err)
   336  	s3 := types.NewStructValue()
   337  	err = s3.Append(k)
   338  	assert.Nil(t, err)
   339  	s5 := types.NewStructValue()
   340  	err = s5.Append(k)
   341  	assert.Nil(t, err)
   342  	err = s5.Append(types.VmValueFromStructVal(s3))
   343  	assert.Nil(t, err)
   344  
   345  	//checkMultiStackOpCode(t, []OpCode{PICKITEM}, []Value{s, int64(1)}, []Value{"value"})
   346  	checkAltStackOpCodeNew(t, []byte{byte(PICKITEM)}, [2][]Value{{s, int64(1)}, {}}, [2][]Value{{[]byte("value")}, {}})
   347  	checkAltStackOpCodeNew(t, []byte{byte(TOALTSTACK), byte(PUSH1), byte(DUPFROMALTSTACK), byte(PUSH2), byte(XSWAP), byte(SETITEM), byte(FROMALTSTACK)},
   348  		[2][]Value{{[]byte("value2"), s}},
   349  		[2][]Value{{s4}})
   350  
   351  	checkAltStackOpCodeNew(t, []byte{byte(TOALTSTACK), byte(PUSH1), byte(DUPFROMALTSTACK), byte(PUSH2), byte(XSWAP), byte(SETITEM), byte(FROMALTSTACK)},
   352  		[2][]Value{{s3, s}},
   353  		[2][]Value{{s5}})
   354  
   355  	s2 := types.NewStructValue()
   356  	err = s2.Append(types.VmValueFromBool(false))
   357  	assert.Nil(t, err)
   358  	checkAltStackOpCodeNew(t, []byte{byte(NEWSTRUCT)},
   359  		[2][]Value{{int64(1)}}, [2][]Value{{s2}})
   360  
   361  	s7 := types.NewStructValue()
   362  	err = s7.Append(types.VmValueFromBool(false))
   363  	assert.Nil(t, err)
   364  	err = s7.Append(types.VmValueFromStructVal(s3))
   365  	assert.Nil(t, err)
   366  
   367  	s6 := types.NewStructValue()
   368  	err = s6.Append(types.VmValueFromBool(false))
   369  	assert.Nil(t, err)
   370  	checkAltStackOpCodeNew(t, []byte{byte(TOALTSTACK), byte(DUPFROMALTSTACK), byte(PUSH1), byte(XSWAP), byte(APPEND), byte(FROMALTSTACK)},
   371  		[2][]Value{{s3, s6}}, [2][]Value{{s7}})
   372  
   373  	checkAltStackOpCodeNew(t, []byte{byte(PUSH1), byte(PICKITEM)}, [2][]Value{{s7}}, [2][]Value{{s3}})
   374  }
   375  
   376  func TestStringOpcode(t *testing.T) {
   377  	checkStackOpCode(t, SIZE, []Value{"12345"}, []Value{5})
   378  	checkStackOpCode(t, CAT, []Value{"aaa", "bbb"}, []Value{"aaabbb"})
   379  	checkStackOpCode(t, SUBSTR, []Value{"aaabbb", 1, 3}, []Value{"aab"})
   380  	checkStackOpCode(t, LEFT, []Value{"aaabbb", 3}, []Value{"aaa"})
   381  	checkStackOpCode(t, RIGHT, []Value{"aaabbb", 3}, []Value{"bbb"})
   382  }
   383  
   384  func TestPUSHDATA(t *testing.T) {
   385  	checkStackOpCode(t, PUSH0, []Value{9999}, []Value{9999, 0})
   386  	checkStackOpCode(t, PUSH1, []Value{9999}, []Value{9999, 1})
   387  	checkStackOpCode(t, PUSH2, []Value{9999}, []Value{9999, 2})
   388  	checkStackOpCode(t, PUSH4, []Value{9999}, []Value{9999, 4})
   389  	checkStackOpCode(t, PUSHM1, []Value{1}, []Value{1, -1})
   390  	checkStackOpCode(t, PUSH1, []Value{9999}, []Value{9999, 1})
   391  	checkStackOpCode(t, PUSH2, []Value{9999}, []Value{9999, 2})
   392  	checkStackOpCode(t, PUSH3, []Value{9999}, []Value{9999, 3})
   393  	checkStackOpCode(t, PUSH4, []Value{9999}, []Value{9999, 4})
   394  	checkStackOpCode(t, PUSH5, []Value{9999}, []Value{9999, 5})
   395  	checkStackOpCode(t, PUSH6, []Value{9999}, []Value{9999, 6})
   396  	checkStackOpCode(t, PUSH7, []Value{9999}, []Value{9999, 7})
   397  	checkStackOpCode(t, PUSH8, []Value{9999}, []Value{9999, 8})
   398  	checkStackOpCode(t, PUSH9, []Value{9999}, []Value{9999, 9})
   399  	checkStackOpCode(t, PUSH10, []Value{9999}, []Value{9999, 10})
   400  	checkStackOpCode(t, PUSH11, []Value{9999}, []Value{9999, 11})
   401  	checkStackOpCode(t, PUSH12, []Value{9999}, []Value{9999, 12})
   402  	checkStackOpCode(t, PUSH13, []Value{9999}, []Value{9999, 13})
   403  	checkStackOpCode(t, PUSH14, []Value{9999}, []Value{9999, 14})
   404  	checkStackOpCode(t, PUSH15, []Value{9999}, []Value{9999, 15})
   405  	checkStackOpCode(t, PUSH16, []Value{9999}, []Value{9999, 16})
   406  }
   407  
   408  func TestFlowControl(t *testing.T) {
   409  	checkMultiStackOpCode(t, []OpCode{PUSH3, DCALL, PUSH0, PUSH1, RET}, nil, []Value{1, 0, 1})
   410  	checkMultiOpCode(t, []byte{byte(CALL), byte(0x03), byte(0x00), byte(PUSH2), byte(RET)}, nil, []Value{2, 2})
   411  	checkMultiOpCode(t, []byte{byte(JMP), byte(0x03), byte(0x00), byte(PUSH2), byte(RET)}, nil, []Value{2})
   412  	checkMultiOpCode(t, []byte{byte(JMPIF), byte(0x03), byte(0x00), byte(PUSH2), byte(RET)}, []Value{true}, []Value{2})
   413  	checkMultiOpCode(t, []byte{byte(JMPIF), byte(0x04), byte(0x00), byte(PUSH2), byte(PUSH14), byte(RET)}, []Value{true}, []Value{14})
   414  	checkMultiOpCode(t, []byte{byte(JMPIFNOT), byte(0x03), byte(0x00), byte(PUSH2), byte(RET)}, []Value{true}, []Value{2})
   415  	checkMultiOpCode(t, []byte{byte(JMPIFNOT), byte(0x04), byte(0x00), byte(PUSH2), byte(PUSH1), byte(RET)}, []Value{true}, []Value{2, 1})
   416  }
   417  
   418  func TestPushData(t *testing.T) {
   419  	checkMultiOpCode(t, []byte{byte(PUSHDATA1), byte(1), byte(2)}, nil, []Value{2})
   420  	checkMultiOpCode(t, []byte{byte(PUSHDATA2), byte(0x01), byte(0x00), byte(2)}, nil, []Value{2})
   421  	checkMultiOpCode(t, []byte{byte(PUSHDATA4), byte(0x01), byte(0x00), byte(0x00), byte(0x00), byte(2)}, nil, []Value{2})
   422  }
   423  
   424  func TestPushBytes(t *testing.T) {
   425  	checkMultiOpCode(t, []byte{byte(PUSHBYTES1), byte(1)}, nil, []Value{1})
   426  	code := make([]byte, 0)
   427  	code = append(code, byte(PUSHBYTES75))
   428  	for i := 0; i < int(PUSHBYTES75); i++ {
   429  		code = append(code, byte(1))
   430  	}
   431  	code2 := make([]byte, len(code)-1, cap(code))
   432  	copy(code2, code[1:])
   433  	checkMultiOpCode(t, code, nil, []Value{code2})
   434  }
   435  
   436  func TestHashOpCode(t *testing.T) {
   437  	data := []byte{1, 2, 3, 4, 5, 6, 7, 8}
   438  	temp := sha256.Sum256(data)
   439  	md := ripemd160.New()
   440  	md.Write(temp[:])
   441  	checkStackOpCode(t, HASH160, []Value{data}, []Value{md.Sum(nil)})
   442  	hash256 := sha256.Sum256(temp[:])
   443  	checkStackOpCode(t, HASH256, []Value{data}, []Value{hash256[:]})
   444  
   445  	sh := sha1.New()
   446  	sh.Write(data)
   447  	hash := sh.Sum(nil)
   448  	checkStackOpCode(t, SHA1, []Value{data}, []Value{hash[:]})
   449  
   450  	sh = sha256.New()
   451  	sh.Write(data)
   452  	hash = sh.Sum(nil)
   453  	checkStackOpCode(t, SHA256, []Value{data}, []Value{hash[:]})
   454  }
   455  
   456  func TestVerify(t *testing.T) {
   457  	pkAlgorithm := keypair.PK_ECDSA
   458  	params := keypair.P256
   459  	pri, pub, _ := keypair.GenerateKeyPair(pkAlgorithm, params)
   460  	sig, err := s.Sign(s.SHA256withECDSA, pri, []byte("test"), nil)
   461  	assert.Equal(t, err, nil)
   462  	sigBytes, err := s.Serialize(sig)
   463  	assert.Equal(t, err, nil)
   464  	checkAltStackOpCodeNew(t, []byte{byte(VERIFY)},
   465  		[2][]Value{{keypair.SerializePublicKey(pub), sigBytes, []byte("test")}, {}}, [2][]Value{{true}, {}})
   466  }
   467  
   468  func TestAssertEqual(t *testing.T) {
   469  	val1 := newVmValue(t, -12345678910)
   470  	buf, _ := val1.AsBytes()
   471  	val2 := newVmValue(t, buf)
   472  
   473  	assertEqual(t, val1, val2)
   474  }
   475  
   476  func TestXTuck(t *testing.T) {
   477  	checkStackOpCode(t, XTUCK, []Value{3, 2, 1, 0, 0}, []Value{3, 2, 1, 0, 0})
   478  	checkStackOpCode(t, XTUCK, []Value{3, 2, 1, 0, 1}, []Value{3, 2, 1, 0, 0})
   479  	checkStackOpCode(t, XTUCK, []Value{3, 2, 1, 0, 2}, []Value{3, 2, 0, 1, 0})
   480  	checkStackOpCode(t, XTUCK, []Value{3, 2, 1, 0, 3}, []Value{3, 0, 2, 1, 0})
   481  	checkStackOpCode(t, XTUCK, []Value{3, 2, 1, 0, 4}, []Value{0, 3, 2, 1, 0})
   482  }
   483  
   484  func TestThrow(t *testing.T) {
   485  	checkStackOpCode(t, THROW, []Value{}, []Value{})
   486  	checkStackOpCode(t, THROWIFNOT, []Value{true}, []Value{})
   487  }