From 9d638d0feed516de8487457c1b2bdbc1cea9527f Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Mon, 23 Dec 2019 15:04:23 +0300 Subject: [PATCH] core: implement Neo.InvocationTransaction.GetScript --- pkg/core/interop_neo.go | 18 ++++++++++++++++++ pkg/core/interop_neo_test.go | 14 +++++++++++++- pkg/core/interops.go | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index 44c55b225..fddeca7bc 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -198,6 +198,24 @@ func (ic *interopContext) txGetWitnesses(v *vm.VM) error { return nil } +// invocationTx_GetScript returns invocation script from the current transaction. +func (ic *interopContext) invocationTxGetScript(v *vm.VM) error { + txInterface := v.Estack().Pop().Value() + tx, ok := txInterface.(*transaction.Transaction) + if !ok { + return errors.New("value is not a transaction") + } + inv, ok := tx.Data.(*transaction.InvocationTX) + if tx.Type != transaction.InvocationType || !ok { + return errors.New("value is not an invocation transaction") + } + // It's important not to share inv.Script slice with the code running in VM. + script := make([]byte, len(inv.Script)) + copy(script, inv.Script) + v.Estack().PushVal(script) + return nil +} + // bcGetValidators returns validators. func (ic *interopContext) bcGetValidators(v *vm.VM) error { validators := ic.dao.GetValidators() diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index ffe48a92f..d84dc4472 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -13,6 +13,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/smartcontract/trigger" "github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/vm" + "github.com/CityOfZion/neo-go/pkg/vm/opcode" "github.com/stretchr/testify/require" ) @@ -115,6 +116,16 @@ func TestTxGetType(t *testing.T) { require.Equal(t, big.NewInt(int64(tx.Type)), value) } +func TestInvocationTxGetScript(t *testing.T) { + v, tx, context := createVMAndPushTX(t) + + err := context.invocationTxGetScript(v) + require.NoError(t, err) + value := v.Estack().Pop().Value().([]byte) + inv := tx.Data.(*transaction.InvocationTX) + require.Equal(t, inv.Script, value) +} + func TestPopInputFromVM(t *testing.T) { v, tx, _ := createVMAndTX(t) v.Estack().PushVal(vm.NewInteropItem(&tx.Inputs[0])) @@ -395,7 +406,8 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interopContext) func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopContext) { v := vm.New() - tx := newMinerTX() + script := []byte{byte(opcode.PUSH1), byte(opcode.RET)} + tx := transaction.NewInvocationTX(script, 0) bytes := make([]byte, 1) attributes := append(tx.Attributes, transaction.Attribute{ diff --git a/pkg/core/interops.go b/pkg/core/interops.go index d8413774d..c0e405ec1 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -152,6 +152,7 @@ var neoInterops = []interopedFunction{ {Name: "Neo.Header.GetVersion", Func: (*interopContext).headerGetVersion, Price: 1}, {Name: "Neo.Input.GetHash", Func: (*interopContext).inputGetHash, Price: 1}, {Name: "Neo.Input.GetIndex", Func: (*interopContext).inputGetIndex, Price: 1}, + {Name: "Neo.InvocationTransaction.GetScript", Func: (*interopContext).invocationTxGetScript, Price: 1}, {Name: "Neo.Output.GetAssetId", Func: (*interopContext).outputGetAssetID, Price: 1}, {Name: "Neo.Output.GetScriptHash", Func: (*interopContext).outputGetScriptHash, Price: 1}, {Name: "Neo.Output.GetValue", Func: (*interopContext).outputGetValue, Price: 1}, @@ -178,7 +179,6 @@ var neoInterops = []interopedFunction{ // {Name: "Neo.Enumerator.Create", Func: (*interopContext).enumeratorCreate, Price: 1}, // {Name: "Neo.Enumerator.Next", Func: (*interopContext).enumeratorNext, Price: 1}, // {Name: "Neo.Enumerator.Value", Func: (*interopContext).enumeratorValue, Price: 1}, - // {Name: "Neo.InvocationTransaction.GetScript", {ic.invocationTx_GetScript, 1}, // {Name: "Neo.Iterator.Concat", Func: (*interopContext).iteratorConcat, Price: 1}, // {Name: "Neo.Iterator.Create", Func: (*interopContext).iteratorCreate, Price: 1}, // {Name: "Neo.Iterator.Key", Func: (*interopContext).iteratorKey, Price: 1},