core: implement Neo.InvocationTransaction.GetScript

This commit is contained in:
Roman Khimov 2019-12-23 15:04:23 +03:00
parent 33958be45f
commit 9d638d0fee
3 changed files with 32 additions and 2 deletions

View file

@ -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()

View file

@ -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{

View file

@ -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},