Merge pull request #938 from nspcc-dev/fix/appcall
vm: remove APPCALL, TAILCALL
This commit is contained in:
commit
b83ee77698
36 changed files with 297 additions and 376 deletions
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4",
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4",
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -44,11 +44,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "ANg3mmstMr7qtY8TgdKM777WSLKCNFbawM",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "AUhsL7QeeomkuzxZexPTa11xNXrbsBrGVc",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "110c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2110b683073b3bb",
|
||||
"script": "110c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2110b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "Aaidx8VxYVjpD6knF8toWG7WquQjQFWcZB",
|
||||
"key": "6PYMZM16cgdQ9GH5ejEPFqehuZ3Lp16W4fW7LyoBdUuVyeMeom7z8wP5QV",
|
||||
"address": "AJjSSuKdC88zWvXnZQbEfL21cm74pGJhsF",
|
||||
"key": "6PYLZTVkK3RoPU8PSAUPHfnu4Py2JcJfeT92FS77DDakRRLcrNu2uCY46Q",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0b680a906ad4",
|
||||
"script": "0c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYMZM16cgdQ9GH5ejEPFqehuZ3Lp16W4fW7LyoBdUuVyeMeom7z8wP5QV",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYLZTVkK3RoPU8PSAUPHfnu4Py2JcJfeT92FS77DDakRRLcrNu2uCY46Q",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "Ae6y4Jx6rjwGu6Vtf6y1piTN3dnhCs6Gp4",
|
||||
"key": "6PYSeHjvJFBn4FVccKHtaq2Hrvqa3aj9EDq5XSnWszvagRyxRmmRijqV6r",
|
||||
"address": "AbrcCqhFRvewc3Xg2FZMY4nFaNM78kiNGv",
|
||||
"key": "6PYUdV8YSMWxmJ6rjaUHBp8GazLwLCB5J69yy2Afgpjovescorhc5zS4Zy",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6990b680a906ad4",
|
||||
"script": "0c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6990b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYSeHjvJFBn4FVccKHtaq2Hrvqa3aj9EDq5XSnWszvagRyxRmmRijqV6r",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYUdV8YSMWxmJ6rjaUHBp8GazLwLCB5J69yy2Afgpjovescorhc5zS4Zy",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ANysJU18KPh6jBBcrGby9bPAHxFmAeL1q3",
|
||||
"key": "6PYNWeXTgyP88XsqDLUdjnCNHypSD8wYLURE78226LU9gYNiSGL1grjFC9",
|
||||
"address": "APw5jfiLG2VpvTzMhCKvfmWdGfWfTmNC7x",
|
||||
"key": "6PYVsJVu8LVaAUHi5hEpWVpWpdy9bWRk1x3RSp7ijCVkCoqyk9NjZT9NhM",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620b680a906ad4",
|
||||
"script": "0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNWeXTgyP88XsqDLUdjnCNHypSD8wYLURE78226LU9gYNiSGL1grjFC9",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYVsJVu8LVaAUHi5hEpWVpWpdy9bWRk1x3RSp7ijCVkCoqyk9NjZT9NhM",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -1081,16 +1081,12 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
case "SHA256":
|
||||
emit.Syscall(c.prog.BinWriter, "Neo.Crypto.SHA256")
|
||||
case "AppCall":
|
||||
numArgs := len(expr.Args) - 1
|
||||
c.emitReverse(numArgs)
|
||||
|
||||
emit.Opcode(c.prog.BinWriter, opcode.APPCALL)
|
||||
c.emitReverse(len(expr.Args))
|
||||
buf := c.getByteArray(expr.Args[0])
|
||||
if len(buf) != 20 {
|
||||
c.prog.Err = errors.New("invalid script hash")
|
||||
}
|
||||
|
||||
c.prog.WriteBytes(buf)
|
||||
emit.Syscall(c.prog.BinWriter, "System.Contract.Call")
|
||||
case "Equals":
|
||||
emit.Opcode(c.prog.BinWriter, opcode.EQUAL)
|
||||
case "FromAddress":
|
||||
|
@ -1112,16 +1108,14 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
|
|||
// transformArgs returns a list of function arguments
|
||||
// which should be put on stack.
|
||||
// There are special cases for builtins:
|
||||
// 1. When using AppCall, script hash is a part of the instruction so
|
||||
// it should be emitted after APPCALL.
|
||||
// 2. With FromAddress, parameter conversion is happening at compile-time
|
||||
// 1. With FromAddress, parameter conversion is happening at compile-time
|
||||
// so there is no need to push parameters on stack and perform an actual call
|
||||
// 3. With panic, generated code depends on if argument was nil or a string so
|
||||
// 2. With panic, generated code depends on if argument was nil or a string so
|
||||
// it should be handled accordingly.
|
||||
func transformArgs(fun ast.Expr, args []ast.Expr) []ast.Expr {
|
||||
switch f := fun.(type) {
|
||||
case *ast.SelectorExpr:
|
||||
if f.Sel.Name == "AppCall" || f.Sel.Name == "FromAddress" {
|
||||
if f.Sel.Name == "FromAddress" {
|
||||
return args[1:]
|
||||
}
|
||||
case *ast.Ident:
|
||||
|
|
|
@ -6,10 +6,17 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/zaptest"
|
||||
)
|
||||
|
||||
func TestFromAddress(t *testing.T) {
|
||||
|
@ -51,6 +58,14 @@ func TestFromAddress(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func spawnVM(t *testing.T, ic *interop.Context, src string) *vm.VM {
|
||||
b, err := compiler.Compile(strings.NewReader(src))
|
||||
require.NoError(t, err)
|
||||
v := core.SpawnVM(ic)
|
||||
v.Load(b)
|
||||
return v
|
||||
}
|
||||
|
||||
func TestAppCall(t *testing.T) {
|
||||
srcInner := `
|
||||
package foo
|
||||
|
@ -62,19 +77,13 @@ func TestAppCall(t *testing.T) {
|
|||
inner, err := compiler.Compile(strings.NewReader(srcInner))
|
||||
require.NoError(t, err)
|
||||
|
||||
ih := hash.Hash160(inner)
|
||||
getScript := func(u util.Uint160) ([]byte, bool) {
|
||||
if u.Equals(ih) {
|
||||
return inner, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
ic := interop.NewContext(trigger.Application, nil, dao.NewSimple(storage.NewMemoryStore()), nil, nil, nil, zaptest.NewLogger(t))
|
||||
require.NoError(t, ic.DAO.PutContractState(&state.Contract{Script: inner}))
|
||||
|
||||
ih := hash.Hash160(inner)
|
||||
t.Run("valid script", func(t *testing.T) {
|
||||
src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE()))
|
||||
v := vmAndCompile(t, src)
|
||||
v.SetScriptGetter(getScript)
|
||||
|
||||
v := spawnVM(t, ic, src)
|
||||
require.NoError(t, v.Run())
|
||||
|
||||
assertResult(t, v, []byte{1, 2, 3, 4})
|
||||
|
@ -85,9 +94,7 @@ func TestAppCall(t *testing.T) {
|
|||
h[0] = ^h[0]
|
||||
|
||||
src := getAppCallScript(fmt.Sprintf("%#v", h.BytesBE()))
|
||||
v := vmAndCompile(t, src)
|
||||
v.SetScriptGetter(getScript)
|
||||
|
||||
v := spawnVM(t, ic, src)
|
||||
require.Error(t, v.Run())
|
||||
})
|
||||
|
||||
|
@ -111,9 +118,7 @@ func TestAppCall(t *testing.T) {
|
|||
}
|
||||
`
|
||||
|
||||
v := vmAndCompile(t, src)
|
||||
v.SetScriptGetter(getScript)
|
||||
|
||||
v := spawnVM(t, ic, src)
|
||||
require.NoError(t, v.Run())
|
||||
|
||||
assertResult(t, v, []byte{1, 2, 3, 4})
|
||||
|
|
12
pkg/consensus/testdata/wallet1.json
vendored
12
pkg/consensus/testdata/wallet1.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4",
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
12
pkg/consensus/testdata/wallet2.json
vendored
12
pkg/consensus/testdata/wallet2.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "Aaidx8VxYVjpD6knF8toWG7WquQjQFWcZB",
|
||||
"key": "6PYMZM16cgdQ9GH5ejEPFqehuZ3Lp16W4fW7LyoBdUuVyeMeom7z8wP5QV",
|
||||
"address": "AJjSSuKdC88zWvXnZQbEfL21cm74pGJhsF",
|
||||
"key": "6PYLZTVkK3RoPU8PSAUPHfnu4Py2JcJfeT92FS77DDakRRLcrNu2uCY46Q",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0b680a906ad4",
|
||||
"script": "0c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYMZM16cgdQ9GH5ejEPFqehuZ3Lp16W4fW7LyoBdUuVyeMeom7z8wP5QV",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYLZTVkK3RoPU8PSAUPHfnu4Py2JcJfeT92FS77DDakRRLcrNu2uCY46Q",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
12
pkg/consensus/testdata/wallet3.json
vendored
12
pkg/consensus/testdata/wallet3.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "Ae6y4Jx6rjwGu6Vtf6y1piTN3dnhCs6Gp4",
|
||||
"key": "6PYSeHjvJFBn4FVccKHtaq2Hrvqa3aj9EDq5XSnWszvagRyxRmmRijqV6r",
|
||||
"address": "AbrcCqhFRvewc3Xg2FZMY4nFaNM78kiNGv",
|
||||
"key": "6PYUdV8YSMWxmJ6rjaUHBp8GazLwLCB5J69yy2Afgpjovescorhc5zS4Zy",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6990b680a906ad4",
|
||||
"script": "0c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6990b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYSeHjvJFBn4FVccKHtaq2Hrvqa3aj9EDq5XSnWszvagRyxRmmRijqV6r",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYUdV8YSMWxmJ6rjaUHBp8GazLwLCB5J69yy2Afgpjovescorhc5zS4Zy",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
12
pkg/consensus/testdata/wallet4.json
vendored
12
pkg/consensus/testdata/wallet4.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ANysJU18KPh6jBBcrGby9bPAHxFmAeL1q3",
|
||||
"key": "6PYNWeXTgyP88XsqDLUdjnCNHypSD8wYLURE78226LU9gYNiSGL1grjFC9",
|
||||
"address": "APw5jfiLG2VpvTzMhCKvfmWdGfWfTmNC7x",
|
||||
"key": "6PYVsJVu8LVaAUHi5hEpWVpWpdy9bWRk1x3RSp7ijCVkCoqyk9NjZT9NhM",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620b680a906ad4",
|
||||
"script": "0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNWeXTgyP88XsqDLUdjnCNHypSD8wYLURE78226LU9gYNiSGL1grjFC9",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYVsJVu8LVaAUHi5hEpWVpWpdy9bWRk1x3RSp7ijCVkCoqyk9NjZT9NhM",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -1616,7 +1616,7 @@ func ScriptFromWitness(hash util.Uint160, witness *transaction.Witness) ([]byte,
|
|||
|
||||
if len(verification) == 0 {
|
||||
bb := io.NewBufBinWriter()
|
||||
emit.AppCall(bb.BinWriter, hash, false)
|
||||
emit.AppCall(bb.BinWriter, hash)
|
||||
verification = bb.Bytes()
|
||||
} else if h := witness.ScriptHash(); hash != h {
|
||||
return nil, errors.New("witness hash mismatch")
|
||||
|
|
|
@ -20,8 +20,6 @@ func getPrice(v *vm.VM, op opcode.Opcode, parameter []byte) util.Fixed8 {
|
|||
}
|
||||
|
||||
switch op {
|
||||
case opcode.APPCALL, opcode.TAILCALL:
|
||||
return toFixed8(10)
|
||||
case opcode.SYSCALL:
|
||||
interopID := vm.GetInteropID(parameter)
|
||||
return getSyscallPrice(v, interopID)
|
||||
|
|
|
@ -84,6 +84,16 @@ type ContractMD struct {
|
|||
Methods map[string]MethodAndPrice
|
||||
}
|
||||
|
||||
// GetContract returns script of the contract with the specified hash.
|
||||
func (ic *Context) GetContract(h util.Uint160) ([]byte, bool) {
|
||||
cs, err := ic.DAO.GetContractState(h)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
hasDynamicInvoke := (cs.Properties & smartcontract.HasDynamicInvoke) != 0
|
||||
return cs.Script, hasDynamicInvoke
|
||||
}
|
||||
|
||||
// NewContractMD returns Contract with the specified list of methods.
|
||||
func NewContractMD(name string) *ContractMD {
|
||||
c := &ContractMD{
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
|
@ -470,6 +471,39 @@ func storageContextAsReadOnly(ic *interop.Context, v *vm.VM) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// contractCall calls a contract.
|
||||
func contractCall(ic *interop.Context, v *vm.VM) error {
|
||||
h := v.Estack().Pop().Bytes()
|
||||
method := v.Estack().Pop().Item()
|
||||
args := v.Estack().Pop().Item()
|
||||
return contractCallExInternal(ic, v, h, method, args, smartcontract.All)
|
||||
}
|
||||
|
||||
// contractCallEx calls a contract with flags.
|
||||
func contractCallEx(ic *interop.Context, v *vm.VM) error {
|
||||
h := v.Estack().Pop().Bytes()
|
||||
method := v.Estack().Pop().Item()
|
||||
args := v.Estack().Pop().Item()
|
||||
flags := smartcontract.CallFlag(int32(v.Estack().Pop().BigInt().Int64()))
|
||||
return contractCallExInternal(ic, v, h, method, args, flags)
|
||||
}
|
||||
|
||||
func contractCallExInternal(ic *interop.Context, v *vm.VM, h []byte, method vm.StackItem, args vm.StackItem, _ smartcontract.CallFlag) error {
|
||||
u, err := util.Uint160DecodeBytesBE(h)
|
||||
if err != nil {
|
||||
return errors.New("invalid contract hash")
|
||||
}
|
||||
script, _ := ic.GetContract(u)
|
||||
if script == nil {
|
||||
return errors.New("contract not found")
|
||||
}
|
||||
// TODO perform flags checking after #923
|
||||
v.LoadScript(script)
|
||||
v.Estack().PushVal(args)
|
||||
v.Estack().PushVal(method)
|
||||
return nil
|
||||
}
|
||||
|
||||
// contractDestroy destroys a contract.
|
||||
func contractDestroy(ic *interop.Context, v *vm.VM) error {
|
||||
if ic.Trigger != trigger.Application {
|
||||
|
|
|
@ -16,8 +16,6 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
)
|
||||
|
@ -26,22 +24,11 @@ import (
|
|||
// up for current blockchain.
|
||||
func SpawnVM(ic *interop.Context) *vm.VM {
|
||||
vm := vm.New()
|
||||
bc := ic.Chain.(*Blockchain)
|
||||
vm.SetScriptGetter(func(hash util.Uint160) ([]byte, bool) {
|
||||
if c := bc.contracts.ByHash(hash); c != nil {
|
||||
meta := c.Metadata()
|
||||
return meta.Script, (meta.Manifest.Features&smartcontract.HasDynamicInvoke != 0)
|
||||
}
|
||||
cs, err := ic.DAO.GetContractState(hash)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
hasDynamicInvoke := (cs.Properties & smartcontract.HasDynamicInvoke) != 0
|
||||
return cs.Script, hasDynamicInvoke
|
||||
})
|
||||
vm.RegisterInteropGetter(getSystemInterop(ic))
|
||||
vm.RegisterInteropGetter(getNeoInterop(ic))
|
||||
vm.RegisterInteropGetter(bc.contracts.GetNativeInterop(ic))
|
||||
if ic.Chain != nil {
|
||||
vm.RegisterInteropGetter(ic.Chain.(*Blockchain).contracts.GetNativeInterop(ic))
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
|
@ -84,6 +71,8 @@ var systemInterops = []interop.Function{
|
|||
{Name: "System.Blockchain.GetHeight", Func: bcGetHeight, Price: 1},
|
||||
{Name: "System.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 200},
|
||||
{Name: "System.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 100},
|
||||
{Name: "System.Contract.Call", Func: contractCall, Price: 1},
|
||||
{Name: "System.Contract.CallEx", Func: contractCallEx, Price: 1},
|
||||
{Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1},
|
||||
{Name: "System.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
|
||||
{Name: "System.ExecutionEngine.GetCallingScriptHash", Func: engineGetCallingScriptHash, Price: 1},
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
)
|
||||
|
||||
|
@ -15,8 +17,23 @@ func Deploy(ic *interop.Context, _ *vm.VM) error {
|
|||
}
|
||||
|
||||
for _, native := range ic.Natives {
|
||||
md := native.Metadata()
|
||||
|
||||
ps := md.Manifest.ABI.EntryPoint.Parameters
|
||||
params := make([]smartcontract.ParamType, len(ps))
|
||||
for i := range ps {
|
||||
params[i] = ps[i].Type
|
||||
}
|
||||
|
||||
cs := &state.Contract{
|
||||
Script: md.Script,
|
||||
ParamList: params,
|
||||
ReturnType: md.Manifest.ABI.EntryPoint.ReturnType,
|
||||
}
|
||||
if err := ic.DAO.PutContractState(cs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := native.Initialize(ic); err != nil {
|
||||
md := native.Metadata()
|
||||
return fmt.Errorf("initializing %s native contract: %v", md.ServiceName, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
|
@ -85,6 +86,9 @@ func TestNativeContract_Invoke(t *testing.T) {
|
|||
tn := newTestNative()
|
||||
chain.registerNative(tn)
|
||||
|
||||
err := chain.dao.PutContractState(&state.Contract{Script: tn.meta.Script})
|
||||
require.NoError(t, err)
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28))
|
||||
script := w.Bytes()
|
||||
|
|
|
@ -20,14 +20,14 @@ func TestGenesisBlockMainNet(t *testing.T) {
|
|||
// have been changed. Consequently, hash of the genesis block has been changed.
|
||||
// Update expected genesis block hash for better times.
|
||||
// Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf"
|
||||
expect := "8eb36fe47f07a795a1783a9f066603db66c5b76cf878650b1e137c114f46c0cc"
|
||||
expect := "56bb42c251ea2b216c5ee8306e94fe040613bc626a3813aa32fe07e7607b3a1a"
|
||||
assert.Equal(t, expect, block.Hash().StringLE())
|
||||
}
|
||||
|
||||
func TestGetConsensusAddressMainNet(t *testing.T) {
|
||||
var (
|
||||
consensusAddr = "APtiVEdLi5GEmQ8CL5RcCE7BNcsPsxeXh7"
|
||||
consensusScript = "590c459950f1d83e67ee11fcef202a6ebb8b1a77"
|
||||
consensusAddr = "ASEhJHr51ZMQUqmUbPC5uiuJwwvedwC48F"
|
||||
consensusScript = "72c3d9b3bbf776698694cd2c73fa597a10c31294"
|
||||
)
|
||||
|
||||
cfg, err := config.Load("../../config", config.ModeMainNet)
|
||||
|
|
|
@ -89,7 +89,7 @@ func TestPubkeyToAddress(t *testing.T) {
|
|||
pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
|
||||
require.NoError(t, err)
|
||||
actual := pubKey.Address()
|
||||
expected := "AbjmXh5RXBMvzYcv7LCmUgrX4sWk1QBJMK"
|
||||
expected := "AJhhwPRwjUmQhEmwPBrq4CVTMRq7u4S4in"
|
||||
require.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,28 +14,28 @@ type Ktype struct {
|
|||
// Arr contains a set of known keys in Ktype format.
|
||||
var Arr = []Ktype{
|
||||
{
|
||||
Address: "AZdm8Dt15QFTrYkMYRrZsTmpx4jbeLtPFj",
|
||||
Address: "AHF4z1wiN9EabrS4eZK9JngmmRYxkfNbLA",
|
||||
PrivateKey: "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344",
|
||||
PublicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef",
|
||||
Wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g",
|
||||
Passphrase: "city of zion",
|
||||
EncryptedWif: "6PYRQrhDFP6hM7Pb4cqJ7T1Erh1XabLDEs42fENU4Htvsdgt6SmShDbCLR",
|
||||
EncryptedWif: "6PYV843ZXHHRKhHbTTKqBxGXbYm8ZvpcZdmcMasZe2n8scuPBBkmdDZk1J",
|
||||
},
|
||||
{
|
||||
Address: "AHPNXvNiGGx43DBTEs9j1z9CjYSSC11jpe",
|
||||
Address: "AM41GdiGK6eFJ7PZhd6yxsvFVWnsh9xUfg",
|
||||
PrivateKey: "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69",
|
||||
PublicKey: "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9",
|
||||
Wif: "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG",
|
||||
Passphrase: "我的密码",
|
||||
EncryptedWif: "6PYKuvXj1Yq9ZjsVNVyNrAHVHrAqg6BLxUoTdpZX5NFkG5Akq79dPYYm7c",
|
||||
EncryptedWif: "6PYWUjTHVYg1iYVAR5B3E6BqbrcsYPVnHzpdHcjSE1emEYN9vqCGHtBBcx",
|
||||
},
|
||||
{
|
||||
Address: "AGo5guykksq8uRxfWyC8dAnTMoz62yUWcn",
|
||||
Address: "AP75QGPdWJceuMCVBiz1GN9Tj3XeU2uerB",
|
||||
PrivateKey: "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b",
|
||||
PublicKey: "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
|
||||
Wif: "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
|
||||
Passphrase: "MyL33tP@33w0rd",
|
||||
EncryptedWif: "6PYQUTBmYbWZukmBTuvTkbjSmz7m5XkEzsyJBk32ZhvC7AbVUpArb1yeMv",
|
||||
EncryptedWif: "6PYKssa8ZJE6LKvZ7TYomhwSs8jSvDuiPFcBwDVyeyYbgaXxRwtvKjYTe7",
|
||||
},
|
||||
{
|
||||
Address: "xdf4UGKevVrMR1j3UkPsuoYKSC4ocoAkKx",
|
||||
|
@ -43,7 +43,7 @@ var Arr = []Ktype{
|
|||
PublicKey: "zz232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
|
||||
Wif: "zzKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
|
||||
Passphrase: "zzL33tP@33w0rd",
|
||||
EncryptedWif: "6PYQUTBmYbWZukmBTuvTkbjSmz7m5XkEzsyJBk32ZhvC7AbVUpArb1yeMv",
|
||||
EncryptedWif: "6PYKssa8ZJE6LKvZ7TYomhwSs8jSvDuiPFcBwDVyeyYbgaXxRwtvKjYTe7",
|
||||
Invalid: true,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byt
|
|||
}
|
||||
}
|
||||
|
||||
emit.AppCall(script.BinWriter, contract, false)
|
||||
emit.AppCall(script.BinWriter, contract)
|
||||
return script.Bytes(), nil
|
||||
}
|
||||
|
||||
|
@ -224,6 +224,6 @@ func CreateInvocationScript(contract util.Uint160, funcParams []Param) ([]byte,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
emit.AppCall(script.BinWriter, contract, false)
|
||||
emit.AppCall(script.BinWriter, contract)
|
||||
return script.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -19,43 +19,43 @@ func TestInvocationScriptCreationGood(t *testing.T) {
|
|||
ps Params
|
||||
script string
|
||||
}{{
|
||||
script: "676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "transfer"}},
|
||||
script: "0c087472616e73666572676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: NumberT, Value: 42}},
|
||||
script: "0c023432676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{}}},
|
||||
script: "10c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "10c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
|
||||
script: "0c1450befd26fdf6e4d957c11e078b24ebce6291456f11c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c1450befd26fdf6e4d957c11e078b24ebce6291456f11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.SignatureType, Value: Param{Type: StringT, Value: "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}}}}}},
|
||||
script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
|
||||
script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash160Type, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
|
||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash256Type, Value: Param{Type: StringT, Value: "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}}}}}},
|
||||
script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.PublicKeyType, Value: Param{Type: StringT, Value: "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}}}}}},
|
||||
script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.IntegerType, Value: Param{Type: NumberT, Value: 42}}}}}},
|
||||
script: "002a11c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "002a11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "true"}}}}}},
|
||||
script: "1111c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "1111c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "false"}}}}}},
|
||||
script: "1011c00c0161676f459162ceeb248b071ec157d9e4f6fd26fdbe50",
|
||||
script: "1011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}}
|
||||
for _, ps := range paramScripts {
|
||||
script, err := CreateFunctionInvocationScript(contract, ps.ps)
|
||||
|
|
|
@ -48,18 +48,18 @@ type rpcTestCase struct {
|
|||
check func(t *testing.T, e *executor, result interface{})
|
||||
}
|
||||
|
||||
const testContractHash = "2077e1382aab3983aa342e68f7bbc94e69f204b9"
|
||||
const testContractHash = "a4bea0d56fad00a972135d54b381516205d78484"
|
||||
|
||||
var rpcTestCases = map[string][]rpcTestCase{
|
||||
"getapplicationlog": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["16c26d67f06770a5b0cda4b1c5ccc28d12c0197c7239a7fe30c2eb523b58f54d"]`,
|
||||
params: `["c296c0929350d051b9b40cace54db5a3eac4b730a8851e958795d44918f23c08"]`,
|
||||
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.ApplicationLog)
|
||||
require.True(t, ok)
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("16c26d67f06770a5b0cda4b1c5ccc28d12c0197c7239a7fe30c2eb523b58f54d")
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("c296c0929350d051b9b40cace54db5a3eac4b730a8851e958795d44918f23c08")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, 1, len(res.Executions))
|
||||
|
@ -473,7 +473,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
params: `["` + testchain.MultisigAddress() + `"]`,
|
||||
result: func(*executor) interface{} {
|
||||
// hash of the issueTx
|
||||
h, _ := util.Uint256DecodeStringBE("99bd2bb2791887ddd3f64dac70ac15339956c76e7c306a1202372ff24fe30635")
|
||||
h, _ := util.Uint256DecodeStringBE("3b76c9b726ffa9074a69441bf946c4c70b83474b3cf522ea3ba9dcd71c1a3db8")
|
||||
amount := util.Fixed8FromInt64(1 * 8) // (endHeight - startHeight) * genAmount[0]
|
||||
return &result.ClaimableInfo{
|
||||
Spents: []result.Claimable{
|
||||
|
@ -532,7 +532,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"gettransactionheight": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["1f08a32642a43e3f06b3b9a9355ed274c52de85a886841a2aef7edd94d1dc3f6"]`,
|
||||
params: `["a05ea6d90b761ec5430f29d25036fdad04efe731b6a5906f4fd1e19048dee0f2"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
h := 1
|
||||
return &h
|
||||
|
@ -647,7 +647,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, "0c06717765727479676f459162ceeb248b071ec157d9e4f6fd26fdbe50", res.Script)
|
||||
assert.Equal(t, "0c067177657274790c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", res.Script)
|
||||
assert.NotEqual(t, "", res.State)
|
||||
assert.NotEqual(t, 0, res.GasConsumed)
|
||||
},
|
||||
|
@ -744,7 +744,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"sendrawtransaction": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["80000b00000075a94799633ed955dd85a8af314a5b435ab51903b0040000000001e53e6c239e3d8441f623ea7b48cdea60c6ae0426a8bac04296002babfeafe5a4010001dcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d0030d3dec386230075a94799633ed955dd85a8af314a5b435ab5190301420c408378eb6bdba1f14540cf2920a4d49c52327f617dc861a21d1c085346aaae2abd410e28dc6a03471a78e71246696a591b9677a71144dfba557d1c781c8c97e350290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"]`,
|
||||
params: `["80000b000000316e851039019d39dfc2c37d6c3fee19fd580987b0040000000001241a237db30af3b33d29518288e0c9b542475733f78f4c6d7416cba89c1f1a67010001dcb7e70846bb5a6828205b81b579562f0e2c15f7b3badd68d485b035882fc17d0030d3dec3862300316e851039019d39dfc2c37d6c3fee19fd58098701420c40c3c3fedb73e36a8e78bae80ba07c20b34f5af6bba36dccbe0cdc7d4e1237f85eec36e63cb762e1e6ce031a6c752e1ce19a3994d15191a6b75f1a02ede7f9d117290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
v := true
|
||||
return &v
|
||||
|
|
BIN
pkg/rpc/server/testdata/test_contract.avm
vendored
BIN
pkg/rpc/server/testdata/test_contract.avm
vendored
Binary file not shown.
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -113,8 +113,6 @@ func (c *Context) Next() (opcode.Opcode, []byte, error) {
|
|||
opcode.JMPGTL, opcode.JMPGEL, opcode.JMPLTL, opcode.JMPLEL,
|
||||
opcode.CALLL, opcode.SYSCALL:
|
||||
numtoread = 4
|
||||
case opcode.APPCALL, opcode.TAILCALL:
|
||||
numtoread = 20
|
||||
default:
|
||||
if instr <= opcode.PUSHINT256 {
|
||||
numtoread = 1 << instr
|
||||
|
|
|
@ -141,35 +141,31 @@ func Jmp(w *io.BinWriter, op opcode.Opcode, label uint16) {
|
|||
Instruction(w, op, buf)
|
||||
}
|
||||
|
||||
// AppCall emits an appcall, if tailCall is true, tailCall opcode will be
|
||||
// emitted instead.
|
||||
func AppCall(w *io.BinWriter, scriptHash util.Uint160, tailCall bool) {
|
||||
op := opcode.APPCALL
|
||||
if tailCall {
|
||||
op = opcode.TAILCALL
|
||||
}
|
||||
Instruction(w, op, scriptHash.BytesBE())
|
||||
// AppCall emits call to provided contract.
|
||||
func AppCall(w *io.BinWriter, scriptHash util.Uint160) {
|
||||
Bytes(w, scriptHash.BytesBE())
|
||||
Syscall(w, "System.Contract.Call")
|
||||
}
|
||||
|
||||
// AppCallWithOperationAndArgs emits an APPCALL with the given operation and arguments.
|
||||
func AppCallWithOperationAndArgs(w *io.BinWriter, scriptHash util.Uint160, operation string, args ...interface{}) {
|
||||
Array(w, args...)
|
||||
String(w, operation)
|
||||
AppCall(w, scriptHash, false)
|
||||
AppCall(w, scriptHash)
|
||||
}
|
||||
|
||||
// AppCallWithOperationAndData emits an appcall with the given operation and data.
|
||||
func AppCallWithOperationAndData(w *io.BinWriter, scriptHash util.Uint160, operation string, data []byte) {
|
||||
Bytes(w, data)
|
||||
String(w, operation)
|
||||
AppCall(w, scriptHash, false)
|
||||
AppCall(w, scriptHash)
|
||||
}
|
||||
|
||||
// AppCallWithOperation emits an appcall with the given operation.
|
||||
func AppCallWithOperation(w *io.BinWriter, scriptHash util.Uint160, operation string) {
|
||||
Bool(w, false)
|
||||
String(w, operation)
|
||||
AppCall(w, scriptHash, false)
|
||||
AppCall(w, scriptHash)
|
||||
}
|
||||
|
||||
func isInstructionJmp(op opcode.Opcode) bool {
|
||||
|
|
|
@ -70,6 +70,9 @@ const (
|
|||
ASSERT Opcode = 0x38
|
||||
THROW Opcode = 0x3A
|
||||
|
||||
RET Opcode = 0x40
|
||||
SYSCALL Opcode = 0x41
|
||||
|
||||
// Stack
|
||||
DEPTH Opcode = 0x43
|
||||
DROP Opcode = 0x45
|
||||
|
@ -88,11 +91,6 @@ const (
|
|||
REVERSE4 Opcode = 0x54
|
||||
REVERSEN Opcode = 0x55
|
||||
|
||||
RET Opcode = 0x66
|
||||
APPCALL Opcode = 0x67
|
||||
SYSCALL Opcode = 0x68
|
||||
TAILCALL Opcode = 0x69
|
||||
|
||||
// Old stack opcodes
|
||||
DUPFROMALTSTACK Opcode = 0x6A
|
||||
TOALTSTACK Opcode = 0x6B
|
||||
|
|
|
@ -62,6 +62,8 @@ func _() {
|
|||
_ = x[ABORT-55]
|
||||
_ = x[ASSERT-56]
|
||||
_ = x[THROW-58]
|
||||
_ = x[RET-64]
|
||||
_ = x[SYSCALL-65]
|
||||
_ = x[DEPTH-67]
|
||||
_ = x[DROP-69]
|
||||
_ = x[NIP-70]
|
||||
|
@ -78,10 +80,6 @@ func _() {
|
|||
_ = x[REVERSE3-83]
|
||||
_ = x[REVERSE4-84]
|
||||
_ = x[REVERSEN-85]
|
||||
_ = x[RET-102]
|
||||
_ = x[APPCALL-103]
|
||||
_ = x[SYSCALL-104]
|
||||
_ = x[TAILCALL-105]
|
||||
_ = x[DUPFROMALTSTACK-106]
|
||||
_ = x[TOALTSTACK-107]
|
||||
_ = x[FROMALTSTACK-108]
|
||||
|
@ -143,7 +141,7 @@ func _() {
|
|||
_ = x[CONVERT-219]
|
||||
}
|
||||
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLABORTASSERTTHROWDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPOLDPUSH1ROLLREVERSE3REVERSE4REVERSENRETAPPCALLSYSCALLTAILCALLDUPFROMALTSTACKTOALTSTACKFROMALTSTACKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERT"
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMPLJMPIFJMPIFLJMPIFNOTJMPIFNOTLJMPEQJMPEQLJMPNEJMPNELJMPGTJMPGTLJMPGEJMPGELJMPLTJMPLTLJMPLEJMPLELCALLCALLLABORTASSERTTHROWRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPOLDPUSH1ROLLREVERSE3REVERSE4REVERSENDUPFROMALTSTACKTOALTSTACKFROMALTSTACKCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLTEGTGTEMINMAXWITHINPACKUNPACKNEWARRAY0NEWARRAYNEWARRAYTNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSISNULLISTYPECONVERT"
|
||||
|
||||
var _Opcode_map = map[Opcode]string{
|
||||
0: _Opcode_name[0:8],
|
||||
|
@ -198,84 +196,82 @@ var _Opcode_map = map[Opcode]string{
|
|||
55: _Opcode_name[301:306],
|
||||
56: _Opcode_name[306:312],
|
||||
58: _Opcode_name[312:317],
|
||||
67: _Opcode_name[317:322],
|
||||
69: _Opcode_name[322:326],
|
||||
70: _Opcode_name[326:329],
|
||||
72: _Opcode_name[329:334],
|
||||
73: _Opcode_name[334:339],
|
||||
74: _Opcode_name[339:342],
|
||||
75: _Opcode_name[342:346],
|
||||
77: _Opcode_name[346:350],
|
||||
78: _Opcode_name[350:354],
|
||||
80: _Opcode_name[354:358],
|
||||
81: _Opcode_name[358:366],
|
||||
82: _Opcode_name[366:370],
|
||||
83: _Opcode_name[370:378],
|
||||
84: _Opcode_name[378:386],
|
||||
85: _Opcode_name[386:394],
|
||||
102: _Opcode_name[394:397],
|
||||
103: _Opcode_name[397:404],
|
||||
104: _Opcode_name[404:411],
|
||||
105: _Opcode_name[411:419],
|
||||
106: _Opcode_name[419:434],
|
||||
107: _Opcode_name[434:444],
|
||||
108: _Opcode_name[444:456],
|
||||
126: _Opcode_name[456:459],
|
||||
127: _Opcode_name[459:465],
|
||||
128: _Opcode_name[465:469],
|
||||
129: _Opcode_name[469:474],
|
||||
144: _Opcode_name[474:480],
|
||||
145: _Opcode_name[480:483],
|
||||
146: _Opcode_name[483:485],
|
||||
147: _Opcode_name[485:488],
|
||||
151: _Opcode_name[488:493],
|
||||
152: _Opcode_name[493:501],
|
||||
153: _Opcode_name[501:505],
|
||||
154: _Opcode_name[505:508],
|
||||
155: _Opcode_name[508:514],
|
||||
156: _Opcode_name[514:517],
|
||||
157: _Opcode_name[517:520],
|
||||
158: _Opcode_name[520:523],
|
||||
159: _Opcode_name[523:526],
|
||||
160: _Opcode_name[526:529],
|
||||
161: _Opcode_name[529:532],
|
||||
162: _Opcode_name[532:535],
|
||||
168: _Opcode_name[535:538],
|
||||
169: _Opcode_name[538:541],
|
||||
170: _Opcode_name[541:544],
|
||||
171: _Opcode_name[544:551],
|
||||
172: _Opcode_name[551:557],
|
||||
177: _Opcode_name[557:559],
|
||||
179: _Opcode_name[559:567],
|
||||
180: _Opcode_name[567:578],
|
||||
181: _Opcode_name[578:580],
|
||||
182: _Opcode_name[580:583],
|
||||
183: _Opcode_name[583:585],
|
||||
184: _Opcode_name[585:588],
|
||||
185: _Opcode_name[588:591],
|
||||
186: _Opcode_name[591:594],
|
||||
187: _Opcode_name[594:600],
|
||||
192: _Opcode_name[600:604],
|
||||
193: _Opcode_name[604:610],
|
||||
194: _Opcode_name[610:619],
|
||||
195: _Opcode_name[619:627],
|
||||
196: _Opcode_name[627:636],
|
||||
197: _Opcode_name[636:646],
|
||||
198: _Opcode_name[646:655],
|
||||
200: _Opcode_name[655:661],
|
||||
202: _Opcode_name[661:665],
|
||||
203: _Opcode_name[665:671],
|
||||
204: _Opcode_name[671:675],
|
||||
205: _Opcode_name[675:681],
|
||||
206: _Opcode_name[681:689],
|
||||
207: _Opcode_name[689:695],
|
||||
208: _Opcode_name[695:702],
|
||||
209: _Opcode_name[702:714],
|
||||
210: _Opcode_name[714:720],
|
||||
211: _Opcode_name[720:730],
|
||||
216: _Opcode_name[730:736],
|
||||
217: _Opcode_name[736:742],
|
||||
219: _Opcode_name[742:749],
|
||||
64: _Opcode_name[317:320],
|
||||
65: _Opcode_name[320:327],
|
||||
67: _Opcode_name[327:332],
|
||||
69: _Opcode_name[332:336],
|
||||
70: _Opcode_name[336:339],
|
||||
72: _Opcode_name[339:344],
|
||||
73: _Opcode_name[344:349],
|
||||
74: _Opcode_name[349:352],
|
||||
75: _Opcode_name[352:356],
|
||||
77: _Opcode_name[356:360],
|
||||
78: _Opcode_name[360:364],
|
||||
80: _Opcode_name[364:368],
|
||||
81: _Opcode_name[368:376],
|
||||
82: _Opcode_name[376:380],
|
||||
83: _Opcode_name[380:388],
|
||||
84: _Opcode_name[388:396],
|
||||
85: _Opcode_name[396:404],
|
||||
106: _Opcode_name[404:419],
|
||||
107: _Opcode_name[419:429],
|
||||
108: _Opcode_name[429:441],
|
||||
126: _Opcode_name[441:444],
|
||||
127: _Opcode_name[444:450],
|
||||
128: _Opcode_name[450:454],
|
||||
129: _Opcode_name[454:459],
|
||||
144: _Opcode_name[459:465],
|
||||
145: _Opcode_name[465:468],
|
||||
146: _Opcode_name[468:470],
|
||||
147: _Opcode_name[470:473],
|
||||
151: _Opcode_name[473:478],
|
||||
152: _Opcode_name[478:486],
|
||||
153: _Opcode_name[486:490],
|
||||
154: _Opcode_name[490:493],
|
||||
155: _Opcode_name[493:499],
|
||||
156: _Opcode_name[499:502],
|
||||
157: _Opcode_name[502:505],
|
||||
158: _Opcode_name[505:508],
|
||||
159: _Opcode_name[508:511],
|
||||
160: _Opcode_name[511:514],
|
||||
161: _Opcode_name[514:517],
|
||||
162: _Opcode_name[517:520],
|
||||
168: _Opcode_name[520:523],
|
||||
169: _Opcode_name[523:526],
|
||||
170: _Opcode_name[526:529],
|
||||
171: _Opcode_name[529:536],
|
||||
172: _Opcode_name[536:542],
|
||||
177: _Opcode_name[542:544],
|
||||
179: _Opcode_name[544:552],
|
||||
180: _Opcode_name[552:563],
|
||||
181: _Opcode_name[563:565],
|
||||
182: _Opcode_name[565:568],
|
||||
183: _Opcode_name[568:570],
|
||||
184: _Opcode_name[570:573],
|
||||
185: _Opcode_name[573:576],
|
||||
186: _Opcode_name[576:579],
|
||||
187: _Opcode_name[579:585],
|
||||
192: _Opcode_name[585:589],
|
||||
193: _Opcode_name[589:595],
|
||||
194: _Opcode_name[595:604],
|
||||
195: _Opcode_name[604:612],
|
||||
196: _Opcode_name[612:621],
|
||||
197: _Opcode_name[621:631],
|
||||
198: _Opcode_name[631:640],
|
||||
200: _Opcode_name[640:646],
|
||||
202: _Opcode_name[646:650],
|
||||
203: _Opcode_name[650:656],
|
||||
204: _Opcode_name[656:660],
|
||||
205: _Opcode_name[660:666],
|
||||
206: _Opcode_name[666:674],
|
||||
207: _Opcode_name[674:680],
|
||||
208: _Opcode_name[680:687],
|
||||
209: _Opcode_name[687:699],
|
||||
210: _Opcode_name[699:705],
|
||||
211: _Opcode_name[705:715],
|
||||
216: _Opcode_name[715:721],
|
||||
217: _Opcode_name[721:727],
|
||||
219: _Opcode_name[727:734],
|
||||
}
|
||||
|
||||
func (i Opcode) String() string {
|
||||
|
|
55
pkg/vm/vm.go
55
pkg/vm/vm.go
|
@ -71,9 +71,6 @@ type VM struct {
|
|||
// callback to get interop price
|
||||
getPrice func(*VM, opcode.Opcode, []byte) util.Fixed8
|
||||
|
||||
// callback to get scripts.
|
||||
getScript func(util.Uint160) ([]byte, bool)
|
||||
|
||||
istack *Stack // invocation stack.
|
||||
estack *Stack // execution stack.
|
||||
astack *Stack // alt stack.
|
||||
|
@ -95,7 +92,6 @@ type VM struct {
|
|||
func New() *VM {
|
||||
vm := &VM{
|
||||
getInterop: make([]InteropGetterFunc, 0, 3), // 3 functions is typical for our default usage.
|
||||
getScript: nil,
|
||||
state: haltState,
|
||||
istack: NewStack("invocation"),
|
||||
|
||||
|
@ -204,8 +200,6 @@ func (v *VM) PrintOps() {
|
|||
desc = fmt.Sprintf("%d (%d/%x)", ctx.ip+int(offset), offset, parameter)
|
||||
case opcode.SYSCALL:
|
||||
desc = fmt.Sprintf("%q", parameter)
|
||||
case opcode.APPCALL, opcode.TAILCALL:
|
||||
desc = fmt.Sprintf("%x", parameter)
|
||||
default:
|
||||
if utf8.Valid(parameter) {
|
||||
desc = fmt.Sprintf("%x (%q)", parameter, parameter)
|
||||
|
@ -477,11 +471,6 @@ func (v *VM) SetCheckedHash(h []byte) {
|
|||
copy(v.checkhash, h)
|
||||
}
|
||||
|
||||
// SetScriptGetter sets the script getter for CALL instructions.
|
||||
func (v *VM) SetScriptGetter(gs func(util.Uint160) ([]byte, bool)) {
|
||||
v.getScript = gs
|
||||
}
|
||||
|
||||
// GetInteropID converts instruction parameter to an interop ID.
|
||||
func GetInteropID(parameter []byte) uint32 {
|
||||
return binary.LittleEndian.Uint32(parameter)
|
||||
|
@ -520,25 +509,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
}
|
||||
}
|
||||
|
||||
switch op {
|
||||
case opcode.APPCALL, opcode.TAILCALL:
|
||||
isZero := true
|
||||
for i := range parameter {
|
||||
if parameter[i] != 0 {
|
||||
isZero = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isZero {
|
||||
break
|
||||
}
|
||||
|
||||
parameter = v.estack.Pop().Bytes()
|
||||
if !ctx.hasDynamicInvoke {
|
||||
panic("contract is not allowed to make dynamic invocations")
|
||||
}
|
||||
}
|
||||
|
||||
if op <= opcode.PUSHINT256 {
|
||||
v.estack.PushVal(emit.BytesToInt(parameter))
|
||||
return
|
||||
|
@ -1175,31 +1145,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
panic(fmt.Sprintf("failed to invoke syscall: %s", err))
|
||||
}
|
||||
|
||||
case opcode.APPCALL, opcode.TAILCALL:
|
||||
if v.getScript == nil {
|
||||
panic("no getScript callback is set up")
|
||||
}
|
||||
|
||||
if op == opcode.APPCALL {
|
||||
v.checkInvocationStackSize()
|
||||
}
|
||||
|
||||
hash, err := util.Uint160DecodeBytesBE(parameter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
script, hasDynamicInvoke := v.getScript(hash)
|
||||
if script == nil {
|
||||
panic("could not find script")
|
||||
}
|
||||
|
||||
if op == opcode.TAILCALL {
|
||||
_ = v.istack.Pop()
|
||||
}
|
||||
|
||||
v.loadScriptWithHash(script, hash, hasDynamicInvoke)
|
||||
|
||||
case opcode.RET:
|
||||
oldCtx := v.istack.Pop().Value().(*Context)
|
||||
rvcount := oldCtx.rvcount
|
||||
|
|
|
@ -1413,69 +1413,6 @@ func TestSIGN(t *testing.T) {
|
|||
t.Run("ByteArray", getTestFuncForVM(prog, 1, []byte{0, 1}))
|
||||
}
|
||||
|
||||
func TestAppCall(t *testing.T) {
|
||||
prog := []byte{byte(opcode.APPCALL)}
|
||||
hash := util.Uint160{1, 2}
|
||||
prog = append(prog, hash.BytesBE()...)
|
||||
prog = append(prog, byte(opcode.RET))
|
||||
|
||||
vm := load(prog)
|
||||
vm.SetScriptGetter(func(in util.Uint160) ([]byte, bool) {
|
||||
if in.Equals(hash) {
|
||||
return makeProgram(opcode.DEPTH), true
|
||||
}
|
||||
return nil, false
|
||||
})
|
||||
vm.estack.PushVal(2)
|
||||
|
||||
runVM(t, vm)
|
||||
elem := vm.estack.Pop() // depth should be 1
|
||||
assert.Equal(t, int64(1), elem.BigInt().Int64())
|
||||
}
|
||||
|
||||
func TestAppCallDynamicBad(t *testing.T) {
|
||||
prog := []byte{byte(opcode.APPCALL)}
|
||||
hash := util.Uint160{}
|
||||
prog = append(prog, hash.BytesBE()...)
|
||||
prog = append(prog, byte(opcode.RET))
|
||||
|
||||
vm := load(prog)
|
||||
vm.SetScriptGetter(func(in util.Uint160) ([]byte, bool) {
|
||||
if in.Equals(hash) {
|
||||
return makeProgram(opcode.DEPTH), true
|
||||
}
|
||||
return nil, false
|
||||
})
|
||||
vm.estack.PushVal(2)
|
||||
vm.estack.PushVal(hash.BytesBE())
|
||||
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestAppCallDynamicGood(t *testing.T) {
|
||||
prog := []byte{byte(opcode.APPCALL)}
|
||||
zeroHash := util.Uint160{}
|
||||
hash := util.Uint160{1, 2, 3}
|
||||
prog = append(prog, zeroHash.BytesBE()...)
|
||||
prog = append(prog, byte(opcode.RET))
|
||||
|
||||
vm := load(prog)
|
||||
vm.SetScriptGetter(func(in util.Uint160) ([]byte, bool) {
|
||||
if in.Equals(hash) {
|
||||
return makeProgram(opcode.DEPTH), true
|
||||
}
|
||||
return nil, false
|
||||
})
|
||||
vm.estack.PushVal(42)
|
||||
vm.estack.PushVal(42)
|
||||
vm.estack.PushVal(hash.BytesBE())
|
||||
vm.Context().hasDynamicInvoke = true
|
||||
|
||||
runVM(t, vm)
|
||||
elem := vm.estack.Pop() // depth should be 2
|
||||
assert.Equal(t, int64(2), elem.BigInt().Int64())
|
||||
}
|
||||
|
||||
func TestSimpleCall(t *testing.T) {
|
||||
buf := io.NewBufBinWriter()
|
||||
w := buf.BinWriter
|
||||
|
|
|
@ -113,13 +113,13 @@ func TestAccount_ConvertMultisig(t *testing.T) {
|
|||
t.Run("1/1 multisig", func(t *testing.T) {
|
||||
pubs := convertPubs(t, hexs[:1])
|
||||
require.NoError(t, a.ConvertMultisig(1, pubs))
|
||||
require.Equal(t, "ANg3mmstMr7qtY8TgdKM777WSLKCNFbawM", a.Address)
|
||||
require.Equal(t, "AUhsL7QeeomkuzxZexPTa11xNXrbsBrGVc", a.Address)
|
||||
})
|
||||
|
||||
t.Run("3/4 multisig", func(t *testing.T) {
|
||||
pubs := convertPubs(t, hexs)
|
||||
require.NoError(t, a.ConvertMultisig(3, pubs))
|
||||
require.Equal(t, "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy", a.Address)
|
||||
require.Equal(t, "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL", a.Address)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
12
pkg/wallet/testdata/wallet1.json
vendored
12
pkg/wallet/testdata/wallet1.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4",
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
18
pkg/wallet/testdata/wallet2.json
vendored
18
pkg/wallet/testdata/wallet2.json
vendored
|
@ -2,11 +2,11 @@
|
|||
"version": "1.0",
|
||||
"accounts": [
|
||||
{
|
||||
"address": "ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4",
|
||||
"script": "0c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -19,11 +19,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
|
||||
"key": "6PYNTeMkEZ1Q2MCqkPMgvC2kvRzH6f1sz4Sj9cGcLG4iYb43yQcpThAeap",
|
||||
"address": "AXSvJVzydxXuL9da4GVwK25zdesCrVKkHL",
|
||||
"key": "6PYMnbn4qBT8v156ii3nijRo2hQD1YHWkFXN7NKCrAZRzJDU1ych1sh2Wj",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb",
|
||||
"script": "130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b413073b3bb",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
@ -44,11 +44,11 @@
|
|||
"isDefault": false
|
||||
},
|
||||
{
|
||||
"address": "Aaidx8VxYVjpD6knF8toWG7WquQjQFWcZB",
|
||||
"key": "6PYMZM16cgdQ9GH5ejEPFqehuZ3Lp16W4fW7LyoBdUuVyeMeom7z8wP5QV",
|
||||
"address": "AJjSSuKdC88zWvXnZQbEfL21cm74pGJhsF",
|
||||
"key": "6PYLZTVkK3RoPU8PSAUPHfnu4Py2JcJfeT92FS77DDakRRLcrNu2uCY46Q",
|
||||
"label": "",
|
||||
"contract": {
|
||||
"script": "0c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0b680a906ad4",
|
||||
"script": "0c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0b410a906ad4",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parameter0",
|
||||
|
|
|
@ -181,14 +181,14 @@ func TestWalletGetChangeAddress(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
sh := w1.GetChangeAddress()
|
||||
// No default address, the first one is used.
|
||||
expected, err := address.StringToUint160("ASW1VhcukJRrukCXRipY4BE9d9zy4mAYsR")
|
||||
expected, err := address.StringToUint160("ALHF9wsXZVEuCGgmDA6ZNsCLtrb4A1g4yG")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, sh)
|
||||
w2, err := NewWalletFromFile("testdata/wallet2.json")
|
||||
require.NoError(t, err)
|
||||
sh = w2.GetChangeAddress()
|
||||
// Default address.
|
||||
expected, err = address.StringToUint160("Aaidx8VxYVjpD6knF8toWG7WquQjQFWcZB")
|
||||
expected, err = address.StringToUint160("AJjSSuKdC88zWvXnZQbEfL21cm74pGJhsF")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected, sh)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue