vm: remove crypto-related opcodes
All cryptography has moved to interops in NEO3. There is no SHA256 interop RN, but it is to appear later. Closes #777.
This commit is contained in:
parent
c1aa96d614
commit
519b31a704
13 changed files with 90 additions and 110 deletions
|
@ -13,7 +13,6 @@ var (
|
||||||
// Go language builtin functions and custom builtin utility functions.
|
// Go language builtin functions and custom builtin utility functions.
|
||||||
builtinFuncs = []string{
|
builtinFuncs = []string{
|
||||||
"len", "append", "SHA256",
|
"len", "append", "SHA256",
|
||||||
"SHA1", "Hash256", "Hash160",
|
|
||||||
"AppCall",
|
"AppCall",
|
||||||
"FromAddress", "Equals",
|
"FromAddress", "Equals",
|
||||||
"panic",
|
"panic",
|
||||||
|
|
|
@ -1065,9 +1065,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
||||||
}
|
}
|
||||||
emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)})
|
emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)})
|
||||||
case "SHA256":
|
case "SHA256":
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.SHA256)
|
emit.Syscall(c.prog.BinWriter, "Neo.Crypto.SHA256")
|
||||||
case "SHA1":
|
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.SHA1)
|
|
||||||
case "AppCall":
|
case "AppCall":
|
||||||
numArgs := len(expr.Args) - 1
|
numArgs := len(expr.Args) - 1
|
||||||
c.emitReverse(numArgs)
|
c.emitReverse(numArgs)
|
||||||
|
|
|
@ -2,6 +2,11 @@ package compiler_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSHA256(t *testing.T) {
|
func TestSHA256(t *testing.T) {
|
||||||
|
@ -16,20 +21,12 @@ func TestSHA256(t *testing.T) {
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
eval(t, src, []byte{0x2a, 0xa, 0xb7, 0x32, 0xb4, 0xe9, 0xd8, 0x5e, 0xf7, 0xdc, 0x25, 0x30, 0x3b, 0x64, 0xab, 0x52, 0x7c, 0x25, 0xa4, 0xd7, 0x78, 0x15, 0xeb, 0xb5, 0x79, 0xf3, 0x96, 0xec, 0x6c, 0xac, 0xca, 0xd3})
|
v := vmAndCompile(t, src)
|
||||||
}
|
ic := &interop.Context{Trigger: trigger.Verification}
|
||||||
|
v.RegisterInteropGetter(crypto.GetInterop(ic))
|
||||||
|
require.NoError(t, v.Run())
|
||||||
|
require.True(t, v.Estack().Len() >= 1)
|
||||||
|
|
||||||
func TestSHA1(t *testing.T) {
|
h := []byte{0x2a, 0xa, 0xb7, 0x32, 0xb4, 0xe9, 0xd8, 0x5e, 0xf7, 0xdc, 0x25, 0x30, 0x3b, 0x64, 0xab, 0x52, 0x7c, 0x25, 0xa4, 0xd7, 0x78, 0x15, 0xeb, 0xb5, 0x79, 0xf3, 0x96, 0xec, 0x6c, 0xac, 0xca, 0xd3}
|
||||||
src := `
|
require.Equal(t, h, v.PopResult())
|
||||||
package foo
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
|
||||||
)
|
|
||||||
func Main() []byte {
|
|
||||||
src := []byte{0x97}
|
|
||||||
hash := crypto.SHA1(src)
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
`
|
|
||||||
eval(t, src, []byte{0xfa, 0x13, 0x8a, 0xe3, 0x56, 0xd3, 0x5c, 0x8d, 0x77, 0x8, 0x3c, 0x40, 0x6a, 0x5b, 0xe7, 0x37, 0x45, 0x64, 0x3a, 0xae})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,6 @@ func getPrice(v *vm.VM, op opcode.Opcode, parameter []byte) util.Fixed8 {
|
||||||
case opcode.SYSCALL:
|
case opcode.SYSCALL:
|
||||||
interopID := vm.GetInteropID(parameter)
|
interopID := vm.GetInteropID(parameter)
|
||||||
return getSyscallPrice(v, interopID)
|
return getSyscallPrice(v, interopID)
|
||||||
case opcode.SHA1, opcode.SHA256:
|
|
||||||
return toFixed8(10)
|
|
||||||
case opcode.HASH160, opcode.HASH256:
|
|
||||||
return toFixed8(20)
|
|
||||||
default:
|
default:
|
||||||
return toFixed8(1)
|
return toFixed8(1)
|
||||||
}
|
}
|
||||||
|
|
15
pkg/core/interop/crypto/hash.go
Normal file
15
pkg/core/interop/crypto/hash.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package crypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sha256 returns sha256 hash of the data.
|
||||||
|
func Sha256(ic *interop.Context, v *vm.VM) error {
|
||||||
|
msg := getMessage(ic, v.Estack().Pop().Item())
|
||||||
|
h := hash.Sha256(msg).BytesBE()
|
||||||
|
v.Estack().PushVal(h)
|
||||||
|
return nil
|
||||||
|
}
|
30
pkg/core/interop/crypto/hash_test.go
Normal file
30
pkg/core/interop/crypto/hash_test.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package crypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSHA256(t *testing.T) {
|
||||||
|
// 0x0100 hashes to 47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254
|
||||||
|
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
|
||||||
|
buf := io.NewBufBinWriter()
|
||||||
|
emit.Bytes(buf.BinWriter, []byte{1, 0})
|
||||||
|
emit.Syscall(buf.BinWriter, "Neo.Crypto.SHA256")
|
||||||
|
prog := buf.Bytes()
|
||||||
|
v := vm.New()
|
||||||
|
ic := &interop.Context{Trigger: trigger.Verification}
|
||||||
|
v.RegisterInteropGetter(GetInterop(ic))
|
||||||
|
v.Load(prog)
|
||||||
|
require.NoError(t, v.Run())
|
||||||
|
assert.Equal(t, 1, v.Estack().Len())
|
||||||
|
assert.Equal(t, res, hex.EncodeToString(v.Estack().Pop().Bytes()))
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
var (
|
var (
|
||||||
ecdsaVerifyID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
|
ecdsaVerifyID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
|
||||||
ecdsaCheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
|
ecdsaCheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
|
||||||
|
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetInterop returns interop getter for crypto-related stuff.
|
// GetInterop returns interop getter for crypto-related stuff.
|
||||||
|
@ -27,6 +28,12 @@ func GetInterop(ic *interop.Context) func(uint32) *vm.InteropFuncPrice {
|
||||||
return ECDSACheckMultisig(ic, v)
|
return ECDSACheckMultisig(ic, v)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
case sha256ID:
|
||||||
|
return &vm.InteropFuncPrice{
|
||||||
|
Func: func(v *vm.VM) error {
|
||||||
|
return Sha256(ic, v)
|
||||||
|
},
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,7 @@ var neoInterops = []interop.Function{
|
||||||
{Name: "Neo.Contract.Migrate", Func: contractMigrate, Price: 0},
|
{Name: "Neo.Contract.Migrate", Func: contractMigrate, Price: 0},
|
||||||
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: 1},
|
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: 1},
|
||||||
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 1},
|
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 1},
|
||||||
|
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1},
|
||||||
{Name: "Neo.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
|
{Name: "Neo.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
|
||||||
{Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1},
|
{Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1},
|
||||||
{Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1},
|
{Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1},
|
||||||
|
|
|
@ -3,11 +3,6 @@ package crypto
|
||||||
// Package crypto provides function signatures that can be used inside
|
// Package crypto provides function signatures that can be used inside
|
||||||
// smart contracts that are written in the neo-go framework.
|
// smart contracts that are written in the neo-go framework.
|
||||||
|
|
||||||
// SHA1 computes the sha1 hash of b.
|
|
||||||
func SHA1(b []byte) []byte {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SHA256 computes the sha256 hash of b.
|
// SHA256 computes the sha256 hash of b.
|
||||||
func SHA256(b []byte) []byte {
|
func SHA256(b []byte) []byte {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -131,15 +131,6 @@ const (
|
||||||
MAX Opcode = 0xA4
|
MAX Opcode = 0xA4
|
||||||
WITHIN Opcode = 0xA5
|
WITHIN Opcode = 0xA5
|
||||||
|
|
||||||
// Crypto
|
|
||||||
SHA1 Opcode = 0xA7
|
|
||||||
SHA256 Opcode = 0xA8
|
|
||||||
HASH160 Opcode = 0xA9
|
|
||||||
HASH256 Opcode = 0xAA
|
|
||||||
CHECKSIG Opcode = 0xAC
|
|
||||||
VERIFY Opcode = 0xAD
|
|
||||||
CHECKMULTISIG Opcode = 0xAE
|
|
||||||
|
|
||||||
// Advanced data structures (arrays, structures, maps)
|
// Advanced data structures (arrays, structures, maps)
|
||||||
PACK Opcode = 0xC0
|
PACK Opcode = 0xC0
|
||||||
UNPACK Opcode = 0xC1
|
UNPACK Opcode = 0xC1
|
||||||
|
|
|
@ -114,13 +114,6 @@ func _() {
|
||||||
_ = x[MIN-163]
|
_ = x[MIN-163]
|
||||||
_ = x[MAX-164]
|
_ = x[MAX-164]
|
||||||
_ = x[WITHIN-165]
|
_ = x[WITHIN-165]
|
||||||
_ = x[SHA1-167]
|
|
||||||
_ = x[SHA256-168]
|
|
||||||
_ = x[HASH160-169]
|
|
||||||
_ = x[HASH256-170]
|
|
||||||
_ = x[CHECKSIG-172]
|
|
||||||
_ = x[VERIFY-173]
|
|
||||||
_ = x[CHECKMULTISIG-174]
|
|
||||||
_ = x[PACK-192]
|
_ = x[PACK-192]
|
||||||
_ = x[UNPACK-193]
|
_ = x[UNPACK-193]
|
||||||
_ = x[NEWARRAY0-194]
|
_ = x[NEWARRAY0-194]
|
||||||
|
@ -146,7 +139,7 @@ func _() {
|
||||||
_ = x[THROWIFNOT-241]
|
_ = x[THROWIFNOT-241]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINSHA1SHA256HASH160HASH256CHECKSIGVERIFYCHECKMULTISIGPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERTTHROWTHROWIFNOT"
|
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLOLDPUSH1RETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKXDROPXSWAPXTUCKDEPTHDROPDUPNIPOVERPICKROLLROTSWAPTUCKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALINCDECSIGNNEGATEABSNOTNZADDSUBMULDIVMODSHLSHRBOOLANDBOOLORNUMEQUALNUMNOTEQUALLTGTLTEGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERTTHROWTHROWIFNOT"
|
||||||
|
|
||||||
var _Opcode_map = map[Opcode]string{
|
var _Opcode_map = map[Opcode]string{
|
||||||
0: _Opcode_name[0:8],
|
0: _Opcode_name[0:8],
|
||||||
|
@ -253,36 +246,29 @@ var _Opcode_map = map[Opcode]string{
|
||||||
163: _Opcode_name[548:551],
|
163: _Opcode_name[548:551],
|
||||||
164: _Opcode_name[551:554],
|
164: _Opcode_name[551:554],
|
||||||
165: _Opcode_name[554:560],
|
165: _Opcode_name[554:560],
|
||||||
167: _Opcode_name[560:564],
|
192: _Opcode_name[560:564],
|
||||||
168: _Opcode_name[564:570],
|
193: _Opcode_name[564:570],
|
||||||
169: _Opcode_name[570:577],
|
194: _Opcode_name[570:579],
|
||||||
170: _Opcode_name[577:584],
|
195: _Opcode_name[579:587],
|
||||||
172: _Opcode_name[584:592],
|
196: _Opcode_name[587:596],
|
||||||
173: _Opcode_name[592:598],
|
197: _Opcode_name[596:606],
|
||||||
174: _Opcode_name[598:611],
|
198: _Opcode_name[606:615],
|
||||||
192: _Opcode_name[611:615],
|
200: _Opcode_name[615:621],
|
||||||
193: _Opcode_name[615:621],
|
202: _Opcode_name[621:625],
|
||||||
194: _Opcode_name[621:630],
|
203: _Opcode_name[625:631],
|
||||||
195: _Opcode_name[630:638],
|
204: _Opcode_name[631:635],
|
||||||
196: _Opcode_name[638:647],
|
205: _Opcode_name[635:641],
|
||||||
197: _Opcode_name[647:657],
|
206: _Opcode_name[641:649],
|
||||||
198: _Opcode_name[657:666],
|
207: _Opcode_name[649:655],
|
||||||
200: _Opcode_name[666:672],
|
208: _Opcode_name[655:662],
|
||||||
202: _Opcode_name[672:676],
|
209: _Opcode_name[662:674],
|
||||||
203: _Opcode_name[676:682],
|
210: _Opcode_name[674:680],
|
||||||
204: _Opcode_name[682:686],
|
211: _Opcode_name[680:690],
|
||||||
205: _Opcode_name[686:692],
|
216: _Opcode_name[690:696],
|
||||||
206: _Opcode_name[692:700],
|
217: _Opcode_name[696:702],
|
||||||
207: _Opcode_name[700:706],
|
219: _Opcode_name[702:709],
|
||||||
208: _Opcode_name[706:713],
|
240: _Opcode_name[709:714],
|
||||||
209: _Opcode_name[713:725],
|
241: _Opcode_name[714:724],
|
||||||
210: _Opcode_name[725:731],
|
|
||||||
211: _Opcode_name[731:741],
|
|
||||||
216: _Opcode_name[741:747],
|
|
||||||
217: _Opcode_name[747:753],
|
|
||||||
219: _Opcode_name[753:760],
|
|
||||||
240: _Opcode_name[760:765],
|
|
||||||
241: _Opcode_name[765:775],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Opcode) String() string {
|
func (i Opcode) String() string {
|
||||||
|
|
13
pkg/vm/vm.go
13
pkg/vm/vm.go
|
@ -1,7 +1,6 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -11,7 +10,6 @@ import (
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
|
@ -1314,17 +1312,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
panic("wrong collection type")
|
panic("wrong collection type")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cryptographic operations.
|
|
||||||
case opcode.SHA1:
|
|
||||||
b := v.estack.Pop().Bytes()
|
|
||||||
sha := sha1.New()
|
|
||||||
sha.Write(b)
|
|
||||||
v.estack.PushVal(sha.Sum(nil))
|
|
||||||
|
|
||||||
case opcode.SHA256:
|
|
||||||
b := v.estack.Pop().Bytes()
|
|
||||||
v.estack.PushVal(hash.Sha256(b).BytesBE())
|
|
||||||
|
|
||||||
case opcode.NOP:
|
case opcode.NOP:
|
||||||
// unlucky ^^
|
// unlucky ^^
|
||||||
|
|
||||||
|
|
|
@ -3037,28 +3037,6 @@ func TestDupBool(t *testing.T) {
|
||||||
assert.Equal(t, true, vm.estack.Pop().Bool())
|
assert.Equal(t, true, vm.estack.Pop().Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSHA1(t *testing.T) {
|
|
||||||
// 0x0100 hashes to 0e356ba505631fbf715758bed27d503f8b260e3a
|
|
||||||
res := "0e356ba505631fbf715758bed27d503f8b260e3a"
|
|
||||||
prog := makeProgram(opcode.PUSHDATA1, 2, 1, 0,
|
|
||||||
opcode.SHA1)
|
|
||||||
vm := load(prog)
|
|
||||||
runVM(t, vm)
|
|
||||||
assert.Equal(t, 1, vm.estack.Len())
|
|
||||||
assert.Equal(t, res, hex.EncodeToString(vm.estack.Pop().Bytes()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSHA256(t *testing.T) {
|
|
||||||
// 0x0100 hashes to 47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254
|
|
||||||
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
|
|
||||||
prog := makeProgram(opcode.PUSHDATA1, 2, 1, 0,
|
|
||||||
opcode.SHA256)
|
|
||||||
vm := load(prog)
|
|
||||||
runVM(t, vm)
|
|
||||||
assert.Equal(t, 1, vm.estack.Len())
|
|
||||||
assert.Equal(t, res, hex.EncodeToString(vm.estack.Pop().Bytes()))
|
|
||||||
}
|
|
||||||
|
|
||||||
var opcodesTestCases = map[opcode.Opcode][]struct {
|
var opcodesTestCases = map[opcode.Opcode][]struct {
|
||||||
name string
|
name string
|
||||||
args []interface{}
|
args []interface{}
|
||||||
|
|
Loading…
Reference in a new issue