diff --git a/.docker/wallets/wallet1.json b/.docker/wallets/wallet1.json index 448326566..31b76902d 100644 --- a/.docker/wallets/wallet1.json +++ b/.docker/wallets/wallet1.json @@ -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", diff --git a/.docker/wallets/wallet1_solo.json b/.docker/wallets/wallet1_solo.json index efc26dbf5..dcd32238a 100644 --- a/.docker/wallets/wallet1_solo.json +++ b/.docker/wallets/wallet1_solo.json @@ -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", diff --git a/.docker/wallets/wallet2.json b/.docker/wallets/wallet2.json index c50c2c414..a82f6a56a 100644 --- a/.docker/wallets/wallet2.json +++ b/.docker/wallets/wallet2.json @@ -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", diff --git a/.docker/wallets/wallet3.json b/.docker/wallets/wallet3.json index caa3d7b02..84bd5d2b9 100644 --- a/.docker/wallets/wallet3.json +++ b/.docker/wallets/wallet3.json @@ -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", diff --git a/.docker/wallets/wallet4.json b/.docker/wallets/wallet4.json index a7bdd86da..698458d54 100644 --- a/.docker/wallets/wallet4.json +++ b/.docker/wallets/wallet4.json @@ -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", diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 71cf35c7e..c40e6c766 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -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: diff --git a/pkg/compiler/interop_test.go b/pkg/compiler/interop_test.go index 39435c243..efdb19654 100644 --- a/pkg/compiler/interop_test.go +++ b/pkg/compiler/interop_test.go @@ -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}) diff --git a/pkg/consensus/testdata/wallet1.json b/pkg/consensus/testdata/wallet1.json index 448326566..31b76902d 100644 --- a/pkg/consensus/testdata/wallet1.json +++ b/pkg/consensus/testdata/wallet1.json @@ -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", diff --git a/pkg/consensus/testdata/wallet2.json b/pkg/consensus/testdata/wallet2.json index c50c2c414..a82f6a56a 100644 --- a/pkg/consensus/testdata/wallet2.json +++ b/pkg/consensus/testdata/wallet2.json @@ -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", diff --git a/pkg/consensus/testdata/wallet3.json b/pkg/consensus/testdata/wallet3.json index caa3d7b02..84bd5d2b9 100644 --- a/pkg/consensus/testdata/wallet3.json +++ b/pkg/consensus/testdata/wallet3.json @@ -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", diff --git a/pkg/consensus/testdata/wallet4.json b/pkg/consensus/testdata/wallet4.json index a7bdd86da..698458d54 100644 --- a/pkg/consensus/testdata/wallet4.json +++ b/pkg/consensus/testdata/wallet4.json @@ -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", diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index ce6e19c2d..35a8a07fc 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -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") diff --git a/pkg/core/gas_price.go b/pkg/core/gas_price.go index a4d281b5d..7d248d5ec 100644 --- a/pkg/core/gas_price.go +++ b/pkg/core/gas_price.go @@ -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) diff --git a/pkg/core/interop/context.go b/pkg/core/interop/context.go index ff42e8fa4..59b2337b0 100644 --- a/pkg/core/interop/context.go +++ b/pkg/core/interop/context.go @@ -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{ diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 30f085f7c..4f6bfea4b 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -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 { diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 03728282a..3a6aba2ea 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -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}, diff --git a/pkg/core/native/interop.go b/pkg/core/native/interop.go index b535313f9..24a6a28b4 100644 --- a/pkg/core/native/interop.go +++ b/pkg/core/native/interop.go @@ -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) } } diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index 90e422483..fd2d10024 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -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() diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index 1c66de845..90d8dbbe7 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -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) diff --git a/pkg/crypto/keys/publickey_test.go b/pkg/crypto/keys/publickey_test.go index e2e0a0da2..dd658c06c 100644 --- a/pkg/crypto/keys/publickey_test.go +++ b/pkg/crypto/keys/publickey_test.go @@ -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) } diff --git a/pkg/internal/keytestcases/testcases.go b/pkg/internal/keytestcases/testcases.go index 640cf3701..e21ea951b 100644 --- a/pkg/internal/keytestcases/testcases.go +++ b/pkg/internal/keytestcases/testcases.go @@ -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, }, } diff --git a/pkg/rpc/request/txBuilder.go b/pkg/rpc/request/txBuilder.go index a9659a266..0be028eb0 100644 --- a/pkg/rpc/request/txBuilder.go +++ b/pkg/rpc/request/txBuilder.go @@ -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 } diff --git a/pkg/rpc/request/tx_builder_test.go b/pkg/rpc/request/tx_builder_test.go index 74fcc394c..a132c629f 100644 --- a/pkg/rpc/request/tx_builder_test.go +++ b/pkg/rpc/request/tx_builder_test.go @@ -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) diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index bb424b3bd..e038a584c 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -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 diff --git a/pkg/rpc/server/testdata/test_contract.avm b/pkg/rpc/server/testdata/test_contract.avm index ab0710b41..4afd3f630 100755 Binary files a/pkg/rpc/server/testdata/test_contract.avm and b/pkg/rpc/server/testdata/test_contract.avm differ diff --git a/pkg/rpc/server/testdata/testblocks.acc b/pkg/rpc/server/testdata/testblocks.acc index 822a8a344..ea5e93376 100644 Binary files a/pkg/rpc/server/testdata/testblocks.acc and b/pkg/rpc/server/testdata/testblocks.acc differ diff --git a/pkg/vm/context.go b/pkg/vm/context.go index b20dbb088..bcc7194dd 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -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 diff --git a/pkg/vm/emit/emit.go b/pkg/vm/emit/emit.go index f510efb7d..b962efb99 100644 --- a/pkg/vm/emit/emit.go +++ b/pkg/vm/emit/emit.go @@ -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 { diff --git a/pkg/vm/opcode/opcode.go b/pkg/vm/opcode/opcode.go index a3874019d..b6fcc13a1 100644 --- a/pkg/vm/opcode/opcode.go +++ b/pkg/vm/opcode/opcode.go @@ -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 diff --git a/pkg/vm/opcode/opcode_string.go b/pkg/vm/opcode/opcode_string.go index 7b4c086bf..5ff84b7b5 100644 --- a/pkg/vm/opcode/opcode_string.go +++ b/pkg/vm/opcode/opcode_string.go @@ -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 { diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 4d8540455..da444962b 100644 --- a/pkg/vm/vm.go +++ b/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 diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index f67a760f3..ad1386d1c 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -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 diff --git a/pkg/wallet/account_test.go b/pkg/wallet/account_test.go index 380a7d2c7..fb61c3dc4 100644 --- a/pkg/wallet/account_test.go +++ b/pkg/wallet/account_test.go @@ -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) }) } diff --git a/pkg/wallet/testdata/wallet1.json b/pkg/wallet/testdata/wallet1.json index 448326566..31b76902d 100644 --- a/pkg/wallet/testdata/wallet1.json +++ b/pkg/wallet/testdata/wallet1.json @@ -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", diff --git a/pkg/wallet/testdata/wallet2.json b/pkg/wallet/testdata/wallet2.json index 7a9f98719..f3c5aa294 100644 --- a/pkg/wallet/testdata/wallet2.json +++ b/pkg/wallet/testdata/wallet2.json @@ -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", diff --git a/pkg/wallet/wallet_test.go b/pkg/wallet/wallet_test.go index b159582ad..eada0c507 100644 --- a/pkg/wallet/wallet_test.go +++ b/pkg/wallet/wallet_test.go @@ -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) }