forked from TrueCloudLab/neoneo-go
Merge pull request #1647 from nspcc-dev/contractcall
Update `System.Contract.Call`
This commit is contained in:
commit
e36e71ffbd
57 changed files with 360 additions and 685 deletions
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -821,7 +822,9 @@ func contractDeploy(ctx *cli.Context) error {
|
|||
return cli.NewExitError(fmt.Errorf("failed to get management contract's hash: %w", err), 1)
|
||||
}
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(buf.BinWriter, mgmtHash, "deploy", f, manifestBytes)
|
||||
emit.AppCall(buf.BinWriter, mgmtHash, "deploy",
|
||||
callflag.ReadStates|callflag.WriteStates|callflag.AllowNotify,
|
||||
f, manifestBytes)
|
||||
if buf.Err != nil {
|
||||
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %w", buf.Err), 1)
|
||||
}
|
||||
|
|
BIN
cli/testdata/chain50x2.acc
vendored
BIN
cli/testdata/chain50x2.acc
vendored
Binary file not shown.
2
cli/testdata/deploy/main.go
vendored
2
cli/testdata/deploy/main.go
vendored
|
@ -36,7 +36,7 @@ func Fail() {
|
|||
func Update(script, manifest []byte) {
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
mgmt := storage.Get(ctx, mgmtKey).(interop.Hash160)
|
||||
contract.Call(mgmt, "update", script, manifest)
|
||||
contract.Call(mgmt, "update", contract.All, script, manifest)
|
||||
}
|
||||
|
||||
// GetValue returns stored value.
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -105,7 +106,7 @@ func handleCandidate(ctx *cli.Context, method string) error {
|
|||
return err
|
||||
}
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, neoContractHash, method, acc.PrivateKey().PublicKey().Bytes())
|
||||
emit.AppCall(w.BinWriter, neoContractHash, method, callflag.WriteStates, acc.PrivateKey().PublicKey().Bytes())
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
tx, err := c.CreateTxFromScript(w.Bytes(), acc, -1, int64(gas), transaction.Signer{
|
||||
Account: acc.Contract.ScriptHash(),
|
||||
|
@ -167,7 +168,7 @@ func handleVote(ctx *cli.Context) error {
|
|||
return cli.NewExitError(err, 1)
|
||||
}
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, neoContractHash, "vote", addr.BytesBE(), pubArg)
|
||||
emit.AppCall(w.BinWriter, neoContractHash, "vote", callflag.WriteStates, addr.BytesBE(), pubArg)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
|
||||
tx, err := c.CreateTxFromScript(w.Bytes(), acc, -1, int64(gas), transaction.Signer{
|
||||
|
|
|
@ -46,7 +46,7 @@ func Migrate(script []byte, manifest []byte) bool {
|
|||
return false
|
||||
}
|
||||
mgmt := storage.Get(ctx, mgmtKey).(interop.Hash160)
|
||||
contract.Call(mgmt, "update", script, manifest)
|
||||
contract.Call(mgmt, "update", contract.All, script, manifest)
|
||||
runtime.Log("Contract updated.")
|
||||
return true
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func Tick() bool {
|
|||
ticksLeft = ticksLeft.(int) - 1
|
||||
if ticksLeft == 0 {
|
||||
runtime.Log("Fired!")
|
||||
return contract.Call(runtime.GetExecutingScriptHash(), "selfDestroy").(bool)
|
||||
return contract.Call(runtime.GetExecutingScriptHash(), "selfDestroy", contract.All).(bool)
|
||||
}
|
||||
storage.Put(ctx, ticksKey, ticksLeft)
|
||||
i := binary.Itoa(ticksLeft.(int), 10)
|
||||
|
@ -73,7 +73,7 @@ func SelfDestroy() bool {
|
|||
return false
|
||||
}
|
||||
mgmt := storage.Get(ctx, mgmtKey).(interop.Hash160)
|
||||
contract.Call(mgmt, "destroy")
|
||||
contract.Call(mgmt, "destroy", contract.All)
|
||||
runtime.Log("Destroyed.")
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"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/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
|
@ -28,7 +29,7 @@ var (
|
|||
func NewTransferFromOwner(bc blockchainer.Blockchainer, contractHash, to util.Uint160, amount int64,
|
||||
nonce, validUntil uint32) (*transaction.Transaction, error) {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, contractHash, "transfer", ownerHash, to, amount, nil)
|
||||
emit.AppCall(w.BinWriter, contractHash, "transfer", callflag.All, ownerHash, to, amount, nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
if w.Err != nil {
|
||||
return nil, w.Err
|
||||
|
@ -76,7 +77,7 @@ func NewDeployTx(bc blockchainer.Blockchainer, name string, sender util.Uint160,
|
|||
return nil, util.Uint160{}, err
|
||||
}
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(buf.BinWriter, bc.ManagementContractHash(), "deploy", neb, rawManifest)
|
||||
emit.AppCall(buf.BinWriter, bc.ManagementContractHash(), "deploy", callflag.All, neb, rawManifest)
|
||||
if buf.Err != nil {
|
||||
return nil, util.Uint160{}, buf.Err
|
||||
}
|
||||
|
|
|
@ -866,15 +866,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
emit.Opcodes(c.prog.BinWriter, opcode.PACK)
|
||||
numArgs -= varSize - 1
|
||||
}
|
||||
// CallFlag in CallEx interop should be the last argument
|
||||
// but this can't be reflected in signature due to varargs.
|
||||
// It is first in compiler interop though, thus we just need to reverse 1 values less.
|
||||
if f != nil && isSyscall(f) && f.pkg.Name() == "contract" && f.name == "CallEx" {
|
||||
c.emitReverse(numArgs - 1)
|
||||
} else {
|
||||
c.emitReverse(numArgs)
|
||||
}
|
||||
}
|
||||
|
||||
// Check builtin first to avoid nil pointer on funcScope!
|
||||
switch {
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
cinterop "github.com/nspcc-dev/neo-go/pkg/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -120,7 +120,7 @@ func spawnVM(t *testing.T, ic *interop.Context, src string) *vm.VM {
|
|||
require.NoError(t, err)
|
||||
v := core.SpawnVM(ic)
|
||||
invokeMethod(t, testMainIdent, b, v, di)
|
||||
v.LoadScriptWithFlags(b, smartcontract.All)
|
||||
v.LoadScriptWithFlags(b, callflag.All)
|
||||
return v
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ func TestAppCall(t *testing.T) {
|
|||
return a + n
|
||||
}
|
||||
func CallInner() int {
|
||||
return contract.Call(%s, "get42").(int)
|
||||
return contract.Call(%s, "get42", contract.All).(int)
|
||||
}`
|
||||
srcInner = fmt.Sprintf(srcInner,
|
||||
fmt.Sprintf("%#v", cinterop.Hash160(barH.BytesBE())))
|
||||
|
@ -222,7 +222,7 @@ func TestAppCall(t *testing.T) {
|
|||
func Main() []byte {
|
||||
x := []byte{1, 2}
|
||||
y := []byte{3, 4}
|
||||
result := contract.Call([]byte(scriptHash), "append", x, y)
|
||||
result := contract.Call([]byte(scriptHash), "append", contract.All, x, y)
|
||||
return result.([]byte)
|
||||
}
|
||||
`
|
||||
|
@ -241,7 +241,7 @@ func TestAppCall(t *testing.T) {
|
|||
x := []byte{1, 2}
|
||||
y := []byte{3, 4}
|
||||
var addr = []byte(` + fmt.Sprintf("%#v", string(ih.BytesBE())) + `)
|
||||
result := contract.Call(addr, "append", x, y)
|
||||
result := contract.Call(addr, "append", contract.All, x, y)
|
||||
return result.([]byte)
|
||||
}
|
||||
`
|
||||
|
@ -257,7 +257,7 @@ func TestAppCall(t *testing.T) {
|
|||
import "github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||
func Main() int {
|
||||
var addr = []byte(` + fmt.Sprintf("%#v", string(ih.BytesBE())) + `)
|
||||
result := contract.Call(addr, "add3", 39)
|
||||
result := contract.Call(addr, "add3", contract.All, 39)
|
||||
return result.(int)
|
||||
}`
|
||||
|
||||
|
@ -272,7 +272,7 @@ func TestAppCall(t *testing.T) {
|
|||
import ee "github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||
func Main() int {
|
||||
var addr = []byte(` + fmt.Sprintf("%#v", string(ih.BytesBE())) + `)
|
||||
result := ee.Call(addr, "add3", 39)
|
||||
result := ee.Call(addr, "add3", ee.All, 39)
|
||||
return result.(int)
|
||||
}`
|
||||
v := spawnVM(t, ic, src)
|
||||
|
@ -288,7 +288,7 @@ func getAppCallScript(h string) string {
|
|||
func Main() []byte {
|
||||
x := []byte{1, 2}
|
||||
y := []byte{3, 4}
|
||||
result := contract.Call(` + h + `, "append", x, y)
|
||||
result := contract.Call(` + h + `, "append", contract.All, x, y)
|
||||
return result.([]byte)
|
||||
}
|
||||
`
|
||||
|
@ -298,7 +298,7 @@ func getCallExScript(h string, flags string) string {
|
|||
return `package foo
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||
func Main() int {
|
||||
result := contract.CallEx(` + flags + `, ` + h + `, "callInner")
|
||||
result := contract.Call(` + h + `, "callInner", ` + flags + `)
|
||||
return result.(int)
|
||||
}`
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ var syscalls = map[string]map[string]string{
|
|||
},
|
||||
"contract": {
|
||||
"Call": interopnames.SystemContractCall,
|
||||
"CallEx": interopnames.SystemContractCallEx,
|
||||
"CreateStandardAccount": interopnames.SystemContractCreateStandardAccount,
|
||||
"IsStandard": interopnames.SystemContractIsStandard,
|
||||
"GetCallFlags": interopnames.SystemContractGetCallFlags,
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -13,14 +13,14 @@ import (
|
|||
|
||||
// Checks that changes in `smartcontract` are reflected in compiler interop package.
|
||||
func TestCallFlags(t *testing.T) {
|
||||
require.EqualValues(t, contract.ReadStates, smartcontract.ReadStates)
|
||||
require.EqualValues(t, contract.WriteStates, smartcontract.WriteStates)
|
||||
require.EqualValues(t, contract.AllowCall, smartcontract.AllowCall)
|
||||
require.EqualValues(t, contract.AllowNotify, smartcontract.AllowNotify)
|
||||
require.EqualValues(t, contract.States, smartcontract.States)
|
||||
require.EqualValues(t, contract.ReadOnly, smartcontract.ReadOnly)
|
||||
require.EqualValues(t, contract.All, smartcontract.All)
|
||||
require.EqualValues(t, contract.NoneFlag, smartcontract.NoneFlag)
|
||||
require.EqualValues(t, contract.ReadStates, callflag.ReadStates)
|
||||
require.EqualValues(t, contract.WriteStates, callflag.WriteStates)
|
||||
require.EqualValues(t, contract.AllowCall, callflag.AllowCall)
|
||||
require.EqualValues(t, contract.AllowNotify, callflag.AllowNotify)
|
||||
require.EqualValues(t, contract.States, callflag.States)
|
||||
require.EqualValues(t, contract.ReadOnly, callflag.ReadOnly)
|
||||
require.EqualValues(t, contract.All, callflag.All)
|
||||
require.EqualValues(t, contract.NoneFlag, callflag.NoneFlag)
|
||||
}
|
||||
|
||||
func TestStoragePutGet(t *testing.T) {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -85,7 +85,7 @@ func invokeMethod(t *testing.T, method string, script []byte, v *vm.VM, di *comp
|
|||
}
|
||||
}
|
||||
require.True(t, mainOffset >= 0)
|
||||
v.LoadScriptWithFlags(script, smartcontract.All)
|
||||
v.LoadScriptWithFlags(script, callflag.All)
|
||||
v.Jump(v.Context(), mainOffset)
|
||||
if initOffset >= 0 {
|
||||
v.Call(v.Context(), initOffset)
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -54,10 +55,10 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3
|
|||
|
||||
// Transfer funds to new validator.
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.GoverningTokenHash(), "transfer",
|
||||
emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "transfer", callflag.All,
|
||||
acc.Contract.ScriptHash().BytesBE(), newPriv.GetScriptHash().BytesBE(), int64(native.NEOTotalSupply), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.UtilityTokenHash(), "transfer",
|
||||
emit.AppCall(w.BinWriter, bc.UtilityTokenHash(), "transfer", callflag.All,
|
||||
acc.Contract.ScriptHash().BytesBE(), newPriv.GetScriptHash().BytesBE(), int64(1_000_000_000), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
require.NoError(t, w.Err)
|
||||
|
@ -74,7 +75,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3
|
|||
|
||||
// Register new candidate.
|
||||
w.Reset()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.GoverningTokenHash(), "registerCandidate", newPriv.PublicKey().Bytes())
|
||||
emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "registerCandidate", callflag.All, newPriv.PublicKey().Bytes())
|
||||
require.NoError(t, w.Err)
|
||||
|
||||
tx = transaction.New(netmode.UnitTestNet, w.Bytes(), 20_000_000)
|
||||
|
@ -92,7 +93,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3
|
|||
|
||||
// Vote for new candidate.
|
||||
w.Reset()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.GoverningTokenHash(), "vote",
|
||||
emit.AppCall(w.BinWriter, bc.GoverningTokenHash(), "vote", callflag.All,
|
||||
newPriv.GetScriptHash(), newPriv.PublicKey().Bytes())
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
require.NoError(t, w.Err)
|
||||
|
|
|
@ -27,13 +27,12 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -624,7 +623,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
|
|||
|
||||
systemInterop := bc.newInteropContext(trigger.Application, cache, block, tx)
|
||||
v := systemInterop.SpawnVM()
|
||||
v.LoadScriptWithFlags(tx.Script, smartcontract.All)
|
||||
v.LoadScriptWithFlags(tx.Script, callflag.All)
|
||||
v.SetPriceGetter(bc.getPrice)
|
||||
v.GasLimit = tx.SystemFee
|
||||
|
||||
|
@ -765,7 +764,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
|
|||
func (bc *Blockchain) runPersist(script []byte, block *block.Block, cache *dao.Cached, trig trigger.Type) (*state.AppExecResult, error) {
|
||||
systemInterop := bc.newInteropContext(trig, cache, block, nil)
|
||||
v := systemInterop.SpawnVM()
|
||||
v.LoadScriptWithFlags(script, smartcontract.WriteStates|smartcontract.AllowCall)
|
||||
v.LoadScriptWithFlags(script, callflag.WriteStates|callflag.AllowCall)
|
||||
v.SetPriceGetter(bc.getPrice)
|
||||
if err := v.Run(); err != nil {
|
||||
return nil, fmt.Errorf("VM has failed: %w", err)
|
||||
|
@ -1659,7 +1658,7 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160,
|
|||
if bc.contracts.ByHash(hash) != nil {
|
||||
return ErrNativeContractWitness
|
||||
}
|
||||
v.LoadScriptWithFlags(witness.VerificationScript, smartcontract.NoneFlag)
|
||||
v.LoadScriptWithFlags(witness.VerificationScript, callflag.NoneFlag)
|
||||
} else {
|
||||
cs, err := ic.GetContract(hash)
|
||||
if err != nil {
|
||||
|
@ -1670,12 +1669,11 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160,
|
|||
return ErrInvalidVerificationContract
|
||||
}
|
||||
initMD := cs.Manifest.ABI.GetMethod(manifest.MethodInit)
|
||||
v.LoadScriptWithHash(cs.NEF.Script, hash, smartcontract.ReadStates)
|
||||
v.LoadScriptWithHash(cs.NEF.Script, hash, callflag.ReadStates)
|
||||
v.Jump(v.Context(), md.Offset)
|
||||
|
||||
if cs.ID <= 0 {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.Opcodes(w.BinWriter, opcode.DEPTH, opcode.PACK)
|
||||
emit.String(w.BinWriter, manifest.MethodVerify)
|
||||
if w.Err != nil {
|
||||
return w.Err
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"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"
|
||||
|
@ -272,12 +273,12 @@ func TestVerifyTx(t *testing.T) {
|
|||
if sc.Equals(gasHash) {
|
||||
amount = 1_000_000_000
|
||||
}
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, sc, "transfer",
|
||||
emit.AppCall(w.BinWriter, sc, "transfer", callflag.All,
|
||||
neoOwner, a.Contract.ScriptHash(), amount, nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
}
|
||||
}
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, gasHash, "transfer",
|
||||
emit.AppCall(w.BinWriter, gasHash, "transfer", callflag.All,
|
||||
neoOwner, testchain.CommitteeScriptHash(), int64(1_000_000_000), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
require.NoError(t, w.Err)
|
||||
|
@ -973,7 +974,7 @@ func TestVerifyTx(t *testing.T) {
|
|||
transaction.NotaryServiceFeePerKey + // fee for Notary attribute
|
||||
fee.Opcode(bc.GetBaseExecFee(), // Notary verification script
|
||||
opcode.PUSHDATA1, opcode.RET, // invocation script
|
||||
opcode.DEPTH, opcode.PACK, opcode.PUSHDATA1, opcode.RET, // arguments for native verification call
|
||||
opcode.PUSHDATA1, opcode.RET, // arguments for native verification call
|
||||
opcode.PUSHDATA1, opcode.SYSCALL, opcode.RET) + // Neo.Native.Call
|
||||
native.NotaryVerificationPrice // Notary witness verification price
|
||||
tx.Scripts = []transaction.Witness{
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"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"
|
||||
|
@ -298,7 +299,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
|
|||
|
||||
// Now invoke this contract.
|
||||
script := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(script.BinWriter, cHash, "putValue", "testkey", "testvalue")
|
||||
emit.AppCall(script.BinWriter, cHash, "putValue", callflag.All, "testkey", "testvalue")
|
||||
|
||||
txInv := transaction.New(testchain.Network(), script.Bytes(), 1*native.GASFactor)
|
||||
txInv.Nonce = getNextNonce()
|
||||
|
@ -328,7 +329,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
|
|||
require.NoError(t, bc.AddBlock(b))
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, cHash, "init")
|
||||
emit.AppCall(w.BinWriter, cHash, "init", callflag.All)
|
||||
initTx := transaction.New(testchain.Network(), w.Bytes(), 1*native.GASFactor)
|
||||
initTx.Nonce = getNextNonce()
|
||||
initTx.ValidUntilBlock = validUntilBlock
|
||||
|
@ -383,7 +384,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
|
|||
|
||||
func newNEP17Transfer(sc, from, to util.Uint160, amount int64, additionalArgs ...interface{}) *transaction.Transaction {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, sc, "transfer", from, to, amount, additionalArgs)
|
||||
emit.AppCall(w.BinWriter, sc, "transfer", callflag.All, from, to, amount, additionalArgs)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
|
||||
script := w.Bytes()
|
||||
|
@ -430,7 +431,7 @@ func addNetworkFee(bc *Blockchain, tx *transaction.Transaction, sender *wallet.A
|
|||
func prepareContractMethodInvoke(chain *Blockchain, sysfee int64,
|
||||
hash util.Uint160, method string, args ...interface{}) (*transaction.Transaction, error) {
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, hash, method, args...)
|
||||
emit.AppCall(w.BinWriter, hash, method, callflag.All, args...)
|
||||
if w.Err != nil {
|
||||
return nil, w.Err
|
||||
}
|
||||
|
@ -487,7 +488,7 @@ func invokeContractMethodBy(t *testing.T, chain *Blockchain, signer *wallet.Acco
|
|||
require.Equal(t, 0, len(res[0].Stack))
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, hash, method, args...)
|
||||
emit.AppCall(w.BinWriter, hash, method, callflag.All, args...)
|
||||
if w.Err != nil {
|
||||
return nil, w.Err
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package callback
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// Callback is an interface for arbitrary callbacks.
|
||||
type Callback interface {
|
||||
// ArgCount returns expected number of arguments.
|
||||
ArgCount() int
|
||||
// LoadContext loads context and arguments on stack.
|
||||
LoadContext(*vm.VM, []stackitem.Item)
|
||||
}
|
||||
|
||||
// Invoke invokes provided callback.
|
||||
func Invoke(ic *interop.Context) error {
|
||||
cb := ic.VM.Estack().Pop().Interop().Value().(Callback)
|
||||
args := ic.VM.Estack().Pop().Array()
|
||||
if cb.ArgCount() != len(args) {
|
||||
return errors.New("invalid argument count")
|
||||
}
|
||||
cb.LoadContext(ic.VM, args)
|
||||
switch t := cb.(type) {
|
||||
case *MethodCallback:
|
||||
id := interopnames.ToID([]byte(interopnames.SystemContractCall))
|
||||
return ic.SyscallHandler(ic.VM, id)
|
||||
case *SyscallCallback:
|
||||
return ic.SyscallHandler(ic.VM, t.desc.ID)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package callback
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"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/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// MethodCallback represents callback for contract method.
|
||||
type MethodCallback struct {
|
||||
contract *state.Contract
|
||||
method *manifest.Method
|
||||
}
|
||||
|
||||
var _ Callback = (*MethodCallback)(nil)
|
||||
|
||||
// ArgCount implements Callback interface.
|
||||
func (s *MethodCallback) ArgCount() int {
|
||||
return len(s.method.Parameters)
|
||||
}
|
||||
|
||||
// LoadContext implements Callback interface.
|
||||
func (s *MethodCallback) LoadContext(v *vm.VM, args []stackitem.Item) {
|
||||
v.Estack().PushVal(args)
|
||||
v.Estack().PushVal(s.method.Name)
|
||||
v.Estack().PushVal(s.contract.Hash.BytesBE())
|
||||
}
|
||||
|
||||
// CreateFromMethod creates callback for a contract method.
|
||||
func CreateFromMethod(ic *interop.Context) error {
|
||||
rawHash := ic.VM.Estack().Pop().Bytes()
|
||||
h, err := util.Uint160DecodeBytesBE(rawHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cs, err := ic.GetContract(h)
|
||||
if err != nil {
|
||||
return fmt.Errorf("contract not found: %w", err)
|
||||
}
|
||||
method := string(ic.VM.Estack().Pop().Bytes())
|
||||
if strings.HasPrefix(method, "_") {
|
||||
return errors.New("invalid method name")
|
||||
}
|
||||
currCs, err := ic.GetContract(ic.VM.GetCurrentScriptHash())
|
||||
if err == nil && !currCs.Manifest.CanCall(h, &cs.Manifest, method) {
|
||||
return errors.New("method call is not allowed")
|
||||
}
|
||||
md := cs.Manifest.ABI.GetMethod(method)
|
||||
ic.VM.Estack().PushVal(stackitem.NewInterop(&MethodCallback{
|
||||
contract: cs,
|
||||
method: md,
|
||||
}))
|
||||
return nil
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package callback
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// PointerCallback represents callback for a pointer.
|
||||
type PointerCallback struct {
|
||||
paramCount int
|
||||
offset int
|
||||
context *vm.Context
|
||||
}
|
||||
|
||||
var _ Callback = (*PointerCallback)(nil)
|
||||
|
||||
// ArgCount implements Callback interface.
|
||||
func (p *PointerCallback) ArgCount() int {
|
||||
return p.paramCount
|
||||
}
|
||||
|
||||
// LoadContext implements Callback interface.
|
||||
func (p *PointerCallback) LoadContext(v *vm.VM, args []stackitem.Item) {
|
||||
v.Call(p.context, p.offset)
|
||||
for i := len(args) - 1; i >= 0; i-- {
|
||||
v.Estack().PushVal(args[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Create creates callback using pointer and parameters count.
|
||||
func Create(ic *interop.Context) error {
|
||||
ctx := ic.VM.Estack().Pop().Item().(*vm.Context)
|
||||
offset := ic.VM.Estack().Pop().Item().(*stackitem.Pointer).Position()
|
||||
count := ic.VM.Estack().Pop().BigInt().Int64()
|
||||
ic.VM.Estack().PushVal(stackitem.NewInterop(&PointerCallback{
|
||||
paramCount: int(count),
|
||||
offset: offset,
|
||||
context: ctx,
|
||||
}))
|
||||
return nil
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package callback
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// SyscallCallback represents callback for a syscall.
|
||||
type SyscallCallback struct {
|
||||
desc *interop.Function
|
||||
}
|
||||
|
||||
var _ Callback = (*SyscallCallback)(nil)
|
||||
|
||||
// ArgCount implements Callback interface.
|
||||
func (p *SyscallCallback) ArgCount() int {
|
||||
return p.desc.ParamCount
|
||||
}
|
||||
|
||||
// LoadContext implements Callback interface.
|
||||
func (p *SyscallCallback) LoadContext(v *vm.VM, args []stackitem.Item) {
|
||||
for i := len(args) - 1; i >= 0; i-- {
|
||||
v.Estack().PushVal(args[i])
|
||||
}
|
||||
}
|
||||
|
||||
// CreateFromSyscall creates callback from syscall.
|
||||
func CreateFromSyscall(ic *interop.Context) error {
|
||||
id := uint32(ic.VM.Estack().Pop().BigInt().Int64())
|
||||
f := ic.GetFunction(id)
|
||||
if f == nil {
|
||||
return errors.New("syscall not found")
|
||||
}
|
||||
if f.DisallowCallback {
|
||||
return errors.New("syscall is not allowed to be used in a callback")
|
||||
}
|
||||
ic.VM.Estack().PushVal(stackitem.NewInterop(&SyscallCallback{f}))
|
||||
return nil
|
||||
}
|
|
@ -11,7 +11,7 @@ import (
|
|||
"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/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
|
@ -70,14 +70,12 @@ type Function struct {
|
|||
ID uint32
|
||||
Name string
|
||||
Func func(*Context) error
|
||||
// DisallowCallback is true iff syscall can't be used in a callback.
|
||||
DisallowCallback bool
|
||||
// ParamCount is a number of function parameters.
|
||||
ParamCount int
|
||||
Price int64
|
||||
// RequiredFlags is a set of flags which must be set during script invocations.
|
||||
// Default value is NoneFlag i.e. no flags are required.
|
||||
RequiredFlags smartcontract.CallFlag
|
||||
RequiredFlags callflag.CallFlag
|
||||
}
|
||||
|
||||
// Method is a signature for a native method.
|
||||
|
@ -88,7 +86,7 @@ type MethodAndPrice struct {
|
|||
Func Method
|
||||
MD *manifest.Method
|
||||
Price int64
|
||||
RequiredFlags smartcontract.CallFlag
|
||||
RequiredFlags callflag.CallFlag
|
||||
}
|
||||
|
||||
// Contract is an interface for all native contracts.
|
||||
|
@ -132,7 +130,7 @@ func NewContractMD(name string) *ContractMD {
|
|||
func (c *ContractMD) AddMethod(md *MethodAndPrice, desc *manifest.Method) {
|
||||
c.Manifest.ABI.Methods = append(c.Manifest.ABI.Methods, *desc)
|
||||
md.MD = desc
|
||||
desc.Safe = md.RequiredFlags&(smartcontract.All^smartcontract.ReadOnly) == 0
|
||||
desc.Safe = md.RequiredFlags&(callflag.All^callflag.ReadOnly) == 0
|
||||
c.Methods[desc.Name] = *md
|
||||
}
|
||||
|
||||
|
|
|
@ -8,33 +8,26 @@ 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/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// Call calls a contract.
|
||||
// Call calls a contract with flags.
|
||||
func Call(ic *interop.Context) error {
|
||||
h := ic.VM.Estack().Pop().Bytes()
|
||||
method := ic.VM.Estack().Pop().String()
|
||||
args := ic.VM.Estack().Pop().Array()
|
||||
return callExInternal(ic, h, method, args, smartcontract.All)
|
||||
}
|
||||
|
||||
// CallEx calls a contract with flags.
|
||||
func CallEx(ic *interop.Context) error {
|
||||
h := ic.VM.Estack().Pop().Bytes()
|
||||
method := ic.VM.Estack().Pop().String()
|
||||
args := ic.VM.Estack().Pop().Array()
|
||||
flags := smartcontract.CallFlag(int32(ic.VM.Estack().Pop().BigInt().Int64()))
|
||||
if flags&^smartcontract.All != 0 {
|
||||
fs := callflag.CallFlag(int32(ic.VM.Estack().Pop().BigInt().Int64()))
|
||||
if fs&^callflag.All != 0 {
|
||||
return errors.New("call flags out of range")
|
||||
}
|
||||
return callExInternal(ic, h, method, args, flags)
|
||||
args := ic.VM.Estack().Pop().Array()
|
||||
return callInternal(ic, h, method, fs, args)
|
||||
}
|
||||
|
||||
func callExInternal(ic *interop.Context, h []byte, name string, args []stackitem.Item, f smartcontract.CallFlag) error {
|
||||
func callInternal(ic *interop.Context, h []byte, name string, f callflag.CallFlag, args []stackitem.Item) error {
|
||||
u, err := util.Uint160DecodeBytesBE(h)
|
||||
if err != nil {
|
||||
return errors.New("invalid contract hash")
|
||||
|
@ -50,8 +43,12 @@ func callExInternal(ic *interop.Context, h []byte, name string, args []stackitem
|
|||
if md == nil {
|
||||
return errors.New("method not found")
|
||||
}
|
||||
hasReturn := md.ReturnType != smartcontract.VoidType
|
||||
if !hasReturn {
|
||||
ic.VM.Estack().PushVal(stackitem.Null{})
|
||||
}
|
||||
if md.Safe {
|
||||
f &^= smartcontract.WriteStates
|
||||
f &^= callflag.WriteStates
|
||||
} else if ctx := ic.VM.Context(); ctx != nil && ctx.IsDeployed() {
|
||||
curr, err := ic.GetContract(ic.VM.GetCurrentScriptHash())
|
||||
if err == nil {
|
||||
|
@ -60,18 +57,12 @@ func callExInternal(ic *interop.Context, h []byte, name string, args []stackitem
|
|||
}
|
||||
}
|
||||
}
|
||||
return CallExInternal(ic, cs, name, args, f, vm.EnsureNotEmpty)
|
||||
}
|
||||
|
||||
// CallExInternal calls a contract with flags and can't be invoked directly by user.
|
||||
func CallExInternal(ic *interop.Context, cs *state.Contract,
|
||||
name string, args []stackitem.Item, f smartcontract.CallFlag, checkReturn vm.CheckReturnState) error {
|
||||
return callExFromNative(ic, ic.VM.GetCurrentScriptHash(), cs, name, args, f, checkReturn)
|
||||
return callExFromNative(ic, ic.VM.GetCurrentScriptHash(), cs, name, args, f, hasReturn)
|
||||
}
|
||||
|
||||
// callExFromNative calls a contract with flags using provided calling hash.
|
||||
func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract,
|
||||
name string, args []stackitem.Item, f smartcontract.CallFlag, checkReturn vm.CheckReturnState) error {
|
||||
name string, args []stackitem.Item, f callflag.CallFlag, hasReturn bool) error {
|
||||
md := cs.Manifest.ABI.GetMethod(name)
|
||||
if md == nil {
|
||||
return fmt.Errorf("method '%s' not found", name)
|
||||
|
@ -82,7 +73,7 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra
|
|||
}
|
||||
|
||||
ic.VM.Invocations[cs.Hash]++
|
||||
ic.VM.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f)
|
||||
ic.VM.LoadScriptWithCallingHash(caller, cs.NEF.Script, cs.Hash, ic.VM.Context().GetCallFlags()&f, true, uint16(len(args)))
|
||||
var isNative bool
|
||||
for i := range ic.Natives {
|
||||
if ic.Natives[i].Metadata().Hash.Equals(cs.Hash) {
|
||||
|
@ -90,17 +81,20 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra
|
|||
break
|
||||
}
|
||||
}
|
||||
if isNative {
|
||||
ic.VM.Estack().PushVal(args)
|
||||
ic.VM.Estack().PushVal(name)
|
||||
} else {
|
||||
for i := len(args) - 1; i >= 0; i-- {
|
||||
ic.VM.Estack().PushVal(args[i])
|
||||
}
|
||||
if isNative {
|
||||
ic.VM.Estack().PushVal(name)
|
||||
} else {
|
||||
// use Jump not Call here because context was loaded in LoadScript above.
|
||||
ic.VM.Jump(ic.VM.Context(), md.Offset)
|
||||
}
|
||||
ic.VM.Context().CheckReturn = checkReturn
|
||||
if hasReturn {
|
||||
ic.VM.Context().RetCount = 1
|
||||
} else {
|
||||
ic.VM.Context().RetCount = 0
|
||||
}
|
||||
|
||||
md = cs.Manifest.ABI.GetMethod(manifest.MethodInit)
|
||||
if md != nil {
|
||||
|
@ -114,9 +108,9 @@ func callExFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contra
|
|||
var ErrNativeCall = errors.New("error during call from native")
|
||||
|
||||
// CallFromNative performs synchronous call from native contract.
|
||||
func CallFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, method string, args []stackitem.Item, checkReturn vm.CheckReturnState) error {
|
||||
func CallFromNative(ic *interop.Context, caller util.Uint160, cs *state.Contract, method string, args []stackitem.Item, hasReturn bool) error {
|
||||
startSize := ic.VM.Istack().Len()
|
||||
if err := callExFromNative(ic, caller, cs, method, args, smartcontract.All, checkReturn); err != nil {
|
||||
if err := callExFromNative(ic, caller, cs, method, args, callflag.All, hasReturn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ const (
|
|||
SystemCallbackCreateFromSyscall = "System.Callback.CreateFromSyscall"
|
||||
SystemCallbackInvoke = "System.Callback.Invoke"
|
||||
SystemContractCall = "System.Contract.Call"
|
||||
SystemContractCallEx = "System.Contract.CallEx"
|
||||
SystemContractCallNative = "System.Contract.CallNative"
|
||||
SystemContractCreateStandardAccount = "System.Contract.CreateStandardAccount"
|
||||
SystemContractIsStandard = "System.Contract.IsStandard"
|
||||
|
@ -86,7 +85,6 @@ var names = []string{
|
|||
SystemCallbackCreateFromSyscall,
|
||||
SystemCallbackInvoke,
|
||||
SystemContractCall,
|
||||
SystemContractCallEx,
|
||||
SystemContractCallNative,
|
||||
SystemContractCreateStandardAccount,
|
||||
SystemContractIsStandard,
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"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"
|
||||
|
@ -64,7 +64,7 @@ func TestGetScriptHash(t *testing.T) {
|
|||
}
|
||||
|
||||
ic := &interop.Context{VM: vm.New()}
|
||||
ic.VM.LoadScriptWithFlags(scripts[0].s, smartcontract.All)
|
||||
ic.VM.LoadScriptWithFlags(scripts[0].s, callflag.All)
|
||||
require.NoError(t, GetEntryScriptHash(ic))
|
||||
checkStack(t, ic.VM, scripts[0].h.BytesBE())
|
||||
require.NoError(t, GetCallingScriptHash(ic))
|
||||
|
@ -72,7 +72,7 @@ func TestGetScriptHash(t *testing.T) {
|
|||
require.NoError(t, GetExecutingScriptHash(ic))
|
||||
checkStack(t, ic.VM, scripts[0].h.BytesBE())
|
||||
|
||||
ic.VM.LoadScriptWithHash(scripts[1].s, scripts[1].h, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash(scripts[1].s, scripts[1].h, callflag.All)
|
||||
require.NoError(t, GetEntryScriptHash(ic))
|
||||
checkStack(t, ic.VM, scripts[0].h.BytesBE())
|
||||
require.NoError(t, GetCallingScriptHash(ic))
|
||||
|
@ -108,7 +108,7 @@ func TestLog(t *testing.T) {
|
|||
|
||||
t.Run("big message", func(t *testing.T) {
|
||||
ic := &interop.Context{Log: zap.NewNop(), VM: vm.New()}
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, callflag.All)
|
||||
ic.VM.Estack().PushVal(string(make([]byte, MaxNotificationSize+1)))
|
||||
require.Error(t, Log(ic))
|
||||
})
|
||||
|
@ -116,7 +116,7 @@ func TestLog(t *testing.T) {
|
|||
t.Run("good", func(t *testing.T) {
|
||||
log, buf := newL(zapcore.InfoLevel)
|
||||
ic := &interop.Context{Log: log, VM: vm.New()}
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, callflag.All)
|
||||
ic.VM.Estack().PushVal("hello")
|
||||
require.NoError(t, Log(ic))
|
||||
|
||||
|
@ -137,7 +137,7 @@ func TestNotify(t *testing.T) {
|
|||
h := random.Uint160()
|
||||
newIC := func(name string, args interface{}) *interop.Context {
|
||||
ic := &interop.Context{VM: vm.New()}
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, smartcontract.NoneFlag)
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, callflag.NoneFlag)
|
||||
ic.VM.Estack().PushVal(args)
|
||||
ic.VM.Estack().PushVal(name)
|
||||
return ic
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/internal/random"
|
||||
"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/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -103,13 +103,13 @@ func TestRuntimeGetInvocationCounter(t *testing.T) {
|
|||
t.Run("No invocations", func(t *testing.T) {
|
||||
h1 := h
|
||||
h1[0] ^= 0xFF
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h1, smartcontract.NoneFlag)
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h1, callflag.NoneFlag)
|
||||
// do not return an error in this case.
|
||||
require.NoError(t, GetInvocationCounter(ic))
|
||||
checkStack(t, ic.VM, 1)
|
||||
})
|
||||
t.Run("NonZero", func(t *testing.T) {
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, smartcontract.NoneFlag)
|
||||
ic.VM.LoadScriptWithHash([]byte{1}, h, callflag.NoneFlag)
|
||||
require.NoError(t, GetInvocationCounter(ic))
|
||||
checkStack(t, ic.VM, 42)
|
||||
})
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
)
|
||||
|
@ -53,7 +53,7 @@ func checkScope(ic *interop.Context, tx *transaction.Transaction, v *vm.VM, hash
|
|||
if callingScriptHash.Equals(util.Uint160{}) {
|
||||
return false, nil
|
||||
}
|
||||
if !v.Context().GetCallFlags().Has(smartcontract.ReadStates) {
|
||||
if !v.Context().GetCallFlags().Has(callflag.ReadStates) {
|
||||
return false, errors.New("missing ReadStates call flag")
|
||||
}
|
||||
cs, err := ic.GetContract(callingScriptHash)
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/internal/random"
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/callback"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/contract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
|
||||
|
@ -20,10 +19,10 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -418,7 +417,7 @@ func TestStorageDelete(t *testing.T) {
|
|||
defer bc.Close()
|
||||
|
||||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, cs))
|
||||
v.LoadScriptWithHash(cs.NEF.Script, cs.Hash, smartcontract.All)
|
||||
v.LoadScriptWithHash(cs.NEF.Script, cs.Hash, callflag.All)
|
||||
put := func(key, value string, flag int) {
|
||||
v.Estack().PushVal(flag)
|
||||
v.Estack().PushVal(value)
|
||||
|
@ -503,13 +502,12 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
|
|||
updateOff := w.Len()
|
||||
emit.Int(w.BinWriter, 2)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.String(w.BinWriter, "update")
|
||||
emit.AppCall(w.BinWriter, mgmtHash)
|
||||
emit.AppCallNoArgs(w.BinWriter, mgmtHash, "update", callflag.All)
|
||||
emit.Opcodes(w.BinWriter, opcode.DROP)
|
||||
emit.Opcodes(w.BinWriter, opcode.RET)
|
||||
destroyOff := w.Len()
|
||||
emit.Opcodes(w.BinWriter, opcode.NEWARRAY0)
|
||||
emit.String(w.BinWriter, "destroy")
|
||||
emit.AppCall(w.BinWriter, mgmtHash)
|
||||
emit.AppCall(w.BinWriter, mgmtHash, "destroy", callflag.All)
|
||||
emit.Opcodes(w.BinWriter, opcode.DROP)
|
||||
emit.Opcodes(w.BinWriter, opcode.RET)
|
||||
invalidStackOff := w.Len()
|
||||
emit.Opcodes(w.BinWriter, opcode.NEWARRAY0, opcode.DUP, opcode.DUP, opcode.APPEND, opcode.NEWMAP)
|
||||
|
@ -655,14 +653,14 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
|
|||
|
||||
func loadScript(ic *interop.Context, script []byte, args ...interface{}) {
|
||||
ic.SpawnVM()
|
||||
ic.VM.LoadScriptWithFlags(script, smartcontract.AllowCall)
|
||||
ic.VM.LoadScriptWithFlags(script, callflag.AllowCall)
|
||||
for i := range args {
|
||||
ic.VM.Estack().PushVal(args[i])
|
||||
}
|
||||
ic.VM.GasLimit = -1
|
||||
}
|
||||
|
||||
func loadScriptWithHashAndFlags(ic *interop.Context, script []byte, hash util.Uint160, f smartcontract.CallFlag, args ...interface{}) {
|
||||
func loadScriptWithHashAndFlags(ic *interop.Context, script []byte, hash util.Uint160, f callflag.CallFlag, args ...interface{}) {
|
||||
ic.SpawnVM()
|
||||
ic.VM.LoadScriptWithHash(script, hash, f)
|
||||
for i := range args {
|
||||
|
@ -686,6 +684,7 @@ func TestContractCall(t *testing.T) {
|
|||
t.Run("Good", func(t *testing.T) {
|
||||
loadScript(ic, currScript, 42)
|
||||
ic.VM.Estack().PushVal(addArgs)
|
||||
ic.VM.Estack().PushVal(callflag.All)
|
||||
ic.VM.Estack().PushVal("add")
|
||||
ic.VM.Estack().PushVal(h.BytesBE())
|
||||
require.NoError(t, contract.Call(ic))
|
||||
|
@ -697,16 +696,16 @@ func TestContractCall(t *testing.T) {
|
|||
|
||||
t.Run("CallExInvalidFlag", func(t *testing.T) {
|
||||
loadScript(ic, currScript, 42)
|
||||
ic.VM.Estack().PushVal(byte(0xFF))
|
||||
ic.VM.Estack().PushVal(addArgs)
|
||||
ic.VM.Estack().PushVal(byte(0xFF))
|
||||
ic.VM.Estack().PushVal("add")
|
||||
ic.VM.Estack().PushVal(h.BytesBE())
|
||||
require.Error(t, contract.CallEx(ic))
|
||||
require.Error(t, contract.Call(ic))
|
||||
})
|
||||
|
||||
runInvalid := func(args ...interface{}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
loadScriptWithHashAndFlags(ic, currScript, h, smartcontract.All, 42)
|
||||
loadScriptWithHashAndFlags(ic, currScript, h, callflag.All, 42)
|
||||
for i := range args {
|
||||
ic.VM.Estack().PushVal(args[i])
|
||||
}
|
||||
|
@ -736,6 +735,7 @@ func TestContractCall(t *testing.T) {
|
|||
t.Run("Many", func(t *testing.T) {
|
||||
loadScript(ic, currScript, 42)
|
||||
ic.VM.Estack().PushVal(stackitem.NewArray(nil))
|
||||
ic.VM.Estack().PushVal(callflag.All)
|
||||
ic.VM.Estack().PushVal("invalidReturn")
|
||||
ic.VM.Estack().PushVal(h.BytesBE())
|
||||
require.NoError(t, contract.Call(ic))
|
||||
|
@ -744,6 +744,7 @@ func TestContractCall(t *testing.T) {
|
|||
t.Run("Void", func(t *testing.T) {
|
||||
loadScript(ic, currScript, 42)
|
||||
ic.VM.Estack().PushVal(stackitem.NewArray(nil))
|
||||
ic.VM.Estack().PushVal(callflag.All)
|
||||
ic.VM.Estack().PushVal("justReturn")
|
||||
ic.VM.Estack().PushVal(h.BytesBE())
|
||||
require.NoError(t, contract.Call(ic))
|
||||
|
@ -757,6 +758,7 @@ func TestContractCall(t *testing.T) {
|
|||
t.Run("IsolatedStack", func(t *testing.T) {
|
||||
loadScript(ic, currScript, 42)
|
||||
ic.VM.Estack().PushVal(stackitem.NewArray(nil))
|
||||
ic.VM.Estack().PushVal(callflag.All)
|
||||
ic.VM.Estack().PushVal("drop")
|
||||
ic.VM.Estack().PushVal(h.BytesBE())
|
||||
require.NoError(t, contract.Call(ic))
|
||||
|
@ -768,6 +770,7 @@ func TestContractCall(t *testing.T) {
|
|||
|
||||
loadScript(ic, currScript, 42)
|
||||
ic.VM.Estack().PushVal(stackitem.NewArray([]stackitem.Item{stackitem.Make(5)}))
|
||||
ic.VM.Estack().PushVal(callflag.All)
|
||||
ic.VM.Estack().PushVal("add3")
|
||||
ic.VM.Estack().PushVal(h.BytesBE())
|
||||
require.NoError(t, contract.Call(ic))
|
||||
|
@ -782,153 +785,9 @@ func TestContractGetCallFlags(t *testing.T) {
|
|||
v, ic, bc := createVM(t)
|
||||
defer bc.Close()
|
||||
|
||||
v.LoadScriptWithHash([]byte{byte(opcode.RET)}, util.Uint160{1, 2, 3}, smartcontract.All)
|
||||
v.LoadScriptWithHash([]byte{byte(opcode.RET)}, util.Uint160{1, 2, 3}, callflag.All)
|
||||
require.NoError(t, contractGetCallFlags(ic))
|
||||
require.Equal(t, int64(smartcontract.All), v.Estack().Pop().Value().(*big.Int).Int64())
|
||||
}
|
||||
|
||||
func TestPointerCallback(t *testing.T) {
|
||||
_, ic, bc := createVM(t)
|
||||
defer bc.Close()
|
||||
|
||||
script := []byte{
|
||||
byte(opcode.NOP), byte(opcode.INC), byte(opcode.RET),
|
||||
byte(opcode.DIV), byte(opcode.RET),
|
||||
}
|
||||
t.Run("Good", func(t *testing.T) {
|
||||
loadScript(ic, script, 2, stackitem.NewPointer(3, script))
|
||||
ic.VM.Estack().PushVal(ic.VM.Context())
|
||||
require.NoError(t, callback.Create(ic))
|
||||
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(3), stackitem.Make(12)})
|
||||
ic.VM.Estack().InsertAt(vm.NewElement(args), 1)
|
||||
require.NoError(t, callback.Invoke(ic))
|
||||
|
||||
require.NoError(t, ic.VM.Run())
|
||||
require.Equal(t, 1, ic.VM.Estack().Len())
|
||||
require.Equal(t, big.NewInt(5), ic.VM.Estack().Pop().Item().Value())
|
||||
})
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
t.Run("NotEnoughParameters", func(t *testing.T) {
|
||||
loadScript(ic, script, 2, stackitem.NewPointer(3, script))
|
||||
ic.VM.Estack().PushVal(ic.VM.Context())
|
||||
require.NoError(t, callback.Create(ic))
|
||||
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(3)})
|
||||
ic.VM.Estack().InsertAt(vm.NewElement(args), 1)
|
||||
require.Error(t, callback.Invoke(ic))
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestMethodCallback(t *testing.T) {
|
||||
_, ic, bc := createVM(t)
|
||||
defer bc.Close()
|
||||
|
||||
cs, currCs := getTestContractState(bc)
|
||||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, cs))
|
||||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, currCs))
|
||||
|
||||
ic.Functions = append(ic.Functions, systemInterops)
|
||||
rawHash := cs.Hash.BytesBE()
|
||||
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
runInvalid := func(args ...interface{}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
loadScript(ic, currCs.NEF.Script, 42)
|
||||
for i := range args {
|
||||
ic.VM.Estack().PushVal(args[i])
|
||||
}
|
||||
require.Error(t, callback.CreateFromMethod(ic))
|
||||
}
|
||||
}
|
||||
t.Run("Hash", runInvalid("add", rawHash[1:]))
|
||||
t.Run("MissingHash", runInvalid("add", util.Uint160{}.BytesBE()))
|
||||
t.Run("MissingMethod", runInvalid("sub", rawHash))
|
||||
t.Run("DisallowedMethod", runInvalid("ret7", rawHash))
|
||||
t.Run("Initialize", runInvalid("_initialize", rawHash))
|
||||
t.Run("NotEnoughArguments", func(t *testing.T) {
|
||||
loadScript(ic, currCs.NEF.Script, 42, "add", rawHash)
|
||||
require.NoError(t, callback.CreateFromMethod(ic))
|
||||
|
||||
ic.VM.Estack().InsertAt(vm.NewElement(stackitem.NewArray([]stackitem.Item{stackitem.Make(1)})), 1)
|
||||
require.Error(t, callback.Invoke(ic))
|
||||
})
|
||||
t.Run("CallIsNotAllowed", func(t *testing.T) {
|
||||
ic.SpawnVM()
|
||||
ic.VM.Load(currCs.NEF.Script)
|
||||
ic.VM.Estack().PushVal("add")
|
||||
ic.VM.Estack().PushVal(rawHash)
|
||||
require.NoError(t, callback.CreateFromMethod(ic))
|
||||
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(1), stackitem.Make(5)})
|
||||
ic.VM.Estack().InsertAt(vm.NewElement(args), 1)
|
||||
require.Error(t, callback.Invoke(ic))
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Good", func(t *testing.T) {
|
||||
loadScript(ic, currCs.NEF.Script, 42, "add", rawHash)
|
||||
require.NoError(t, callback.CreateFromMethod(ic))
|
||||
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(1), stackitem.Make(5)})
|
||||
ic.VM.Estack().InsertAt(vm.NewElement(args), 1)
|
||||
|
||||
require.NoError(t, callback.Invoke(ic))
|
||||
require.NoError(t, ic.VM.Run())
|
||||
require.Equal(t, 2, ic.VM.Estack().Len())
|
||||
require.Equal(t, big.NewInt(6), ic.VM.Estack().Pop().Item().Value())
|
||||
require.Equal(t, big.NewInt(42), ic.VM.Estack().Pop().Item().Value())
|
||||
})
|
||||
}
|
||||
func TestSyscallCallback(t *testing.T) {
|
||||
_, ic, bc := createVM(t)
|
||||
defer bc.Close()
|
||||
|
||||
ic.Functions = append(ic.Functions, []interop.Function{
|
||||
{
|
||||
ID: 0x42,
|
||||
Func: func(ic *interop.Context) error {
|
||||
a := ic.VM.Estack().Pop().BigInt()
|
||||
b := ic.VM.Estack().Pop().BigInt()
|
||||
ic.VM.Estack().PushVal(new(big.Int).Add(a, b))
|
||||
return nil
|
||||
},
|
||||
ParamCount: 2,
|
||||
},
|
||||
{
|
||||
ID: 0x53,
|
||||
Func: func(_ *interop.Context) error { return nil },
|
||||
DisallowCallback: true,
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("Good", func(t *testing.T) {
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(12), stackitem.Make(30)})
|
||||
loadScript(ic, []byte{byte(opcode.RET)}, args, 0x42)
|
||||
require.NoError(t, callback.CreateFromSyscall(ic))
|
||||
require.NoError(t, callback.Invoke(ic))
|
||||
require.Equal(t, 1, ic.VM.Estack().Len())
|
||||
require.Equal(t, big.NewInt(42), ic.VM.Estack().Pop().Item().Value())
|
||||
})
|
||||
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
t.Run("InvalidParameterCount", func(t *testing.T) {
|
||||
args := stackitem.NewArray([]stackitem.Item{stackitem.Make(12)})
|
||||
loadScript(ic, []byte{byte(opcode.RET)}, args, 0x42)
|
||||
require.NoError(t, callback.CreateFromSyscall(ic))
|
||||
require.Error(t, callback.Invoke(ic))
|
||||
})
|
||||
t.Run("MissingSyscall", func(t *testing.T) {
|
||||
loadScript(ic, []byte{byte(opcode.RET)}, stackitem.NewArray(nil), 0x43)
|
||||
require.Error(t, callback.CreateFromSyscall(ic))
|
||||
})
|
||||
t.Run("Disallowed", func(t *testing.T) {
|
||||
loadScript(ic, []byte{byte(opcode.RET)}, stackitem.NewArray(nil), 0x53)
|
||||
require.Error(t, callback.CreateFromSyscall(ic))
|
||||
})
|
||||
})
|
||||
require.Equal(t, int64(callflag.All), v.Estack().Pop().Value().(*big.Int).Int64())
|
||||
}
|
||||
|
||||
func TestRuntimeCheckWitness(t *testing.T) {
|
||||
|
@ -955,7 +814,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
check(t, ic, []byte{1, 2, 3}, true)
|
||||
})
|
||||
t.Run("script container is not a transaction", func(t *testing.T) {
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, callflag.ReadStates)
|
||||
check(t, ic, random.Uint160().BytesBE(), true)
|
||||
})
|
||||
t.Run("check scope", func(t *testing.T) {
|
||||
|
@ -972,8 +831,8 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
}
|
||||
ic.Container = tx
|
||||
callingScriptHash := scriptHash
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), smartcontract.AllowCall)
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, callflag.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), callflag.AllowCall)
|
||||
check(t, ic, hash.BytesBE(), true)
|
||||
})
|
||||
t.Run("CustomGroups, unknown contract", func(t *testing.T) {
|
||||
|
@ -989,8 +848,8 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
}
|
||||
ic.Container = tx
|
||||
callingScriptHash := scriptHash
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, callflag.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), callflag.ReadStates)
|
||||
check(t, ic, hash.BytesBE(), true)
|
||||
})
|
||||
})
|
||||
|
@ -999,16 +858,16 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
t.Run("calling scripthash", func(t *testing.T) {
|
||||
t.Run("hashed witness", func(t *testing.T) {
|
||||
callingScriptHash := scriptHash
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), smartcontract.All)
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, callflag.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), callflag.All)
|
||||
check(t, ic, callingScriptHash.BytesBE(), false, true)
|
||||
})
|
||||
t.Run("keyed witness", func(t *testing.T) {
|
||||
pk, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
callingScriptHash := pk.PublicKey().GetScriptHash()
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), smartcontract.All)
|
||||
loadScriptWithHashAndFlags(ic, script, callingScriptHash, callflag.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), callflag.All)
|
||||
check(t, ic, pk.PublicKey().Bytes(), false, true)
|
||||
})
|
||||
})
|
||||
|
@ -1023,7 +882,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, callflag.ReadStates)
|
||||
ic.Container = tx
|
||||
check(t, ic, hash.BytesBE(), false, true)
|
||||
})
|
||||
|
@ -1037,7 +896,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, callflag.ReadStates)
|
||||
ic.Container = tx
|
||||
check(t, ic, hash.BytesBE(), false, true)
|
||||
})
|
||||
|
@ -1052,7 +911,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, callflag.ReadStates)
|
||||
ic.Container = tx
|
||||
check(t, ic, hash.BytesBE(), false, true)
|
||||
})
|
||||
|
@ -1068,7 +927,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, callflag.ReadStates)
|
||||
ic.Container = tx
|
||||
check(t, ic, hash.BytesBE(), false, false)
|
||||
})
|
||||
|
@ -1098,8 +957,8 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
},
|
||||
}
|
||||
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, contractState))
|
||||
loadScriptWithHashAndFlags(ic, contractScript, contractScriptHash, smartcontract.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, contractScript, contractScriptHash, callflag.All)
|
||||
ic.VM.LoadScriptWithHash([]byte{0x1}, random.Uint160(), callflag.ReadStates)
|
||||
ic.Container = tx
|
||||
check(t, ic, targetHash.BytesBE(), false, true)
|
||||
})
|
||||
|
@ -1114,7 +973,7 @@ func TestRuntimeCheckWitness(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, smartcontract.ReadStates)
|
||||
loadScriptWithHashAndFlags(ic, script, scriptHash, callflag.ReadStates)
|
||||
ic.Container = tx
|
||||
check(t, ic, hash.BytesBE(), false, false)
|
||||
})
|
||||
|
|
|
@ -10,7 +10,6 @@ package core
|
|||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/binary"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/callback"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/contract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
|
||||
|
@ -19,7 +18,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop/json"
|
||||
"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/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
)
|
||||
|
||||
|
@ -42,42 +41,36 @@ var systemInterops = []interop.Function{
|
|||
{Name: interopnames.SystemBinaryItoa, Func: binary.Itoa, Price: 1 << 12, ParamCount: 2},
|
||||
{Name: interopnames.SystemBinarySerialize, Func: binary.Serialize, Price: 1 << 12, ParamCount: 1},
|
||||
{Name: interopnames.SystemBlockchainGetBlock, Func: bcGetBlock, Price: 1 << 16,
|
||||
RequiredFlags: smartcontract.ReadStates, ParamCount: 1},
|
||||
RequiredFlags: callflag.ReadStates, ParamCount: 1},
|
||||
{Name: interopnames.SystemBlockchainGetHeight, Func: bcGetHeight, Price: 1 << 4,
|
||||
RequiredFlags: smartcontract.ReadStates},
|
||||
RequiredFlags: callflag.ReadStates},
|
||||
{Name: interopnames.SystemBlockchainGetTransaction, Func: bcGetTransaction, Price: 1 << 15,
|
||||
RequiredFlags: smartcontract.ReadStates, ParamCount: 1},
|
||||
RequiredFlags: callflag.ReadStates, ParamCount: 1},
|
||||
{Name: interopnames.SystemBlockchainGetTransactionFromBlock, Func: bcGetTransactionFromBlock, Price: 1 << 15,
|
||||
RequiredFlags: smartcontract.ReadStates, ParamCount: 2},
|
||||
RequiredFlags: callflag.ReadStates, ParamCount: 2},
|
||||
{Name: interopnames.SystemBlockchainGetTransactionHeight, Func: bcGetTransactionHeight, Price: 1 << 15,
|
||||
RequiredFlags: smartcontract.ReadStates, ParamCount: 1},
|
||||
{Name: interopnames.SystemCallbackCreate, Func: callback.Create, Price: 1 << 4, ParamCount: 3, DisallowCallback: true},
|
||||
{Name: interopnames.SystemCallbackCreateFromMethod, Func: callback.CreateFromMethod, Price: 1 << 15, ParamCount: 2, DisallowCallback: true},
|
||||
{Name: interopnames.SystemCallbackCreateFromSyscall, Func: callback.CreateFromSyscall, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemCallbackInvoke, Func: callback.Invoke, Price: 1 << 15, ParamCount: 2, DisallowCallback: true},
|
||||
RequiredFlags: callflag.ReadStates, ParamCount: 1},
|
||||
{Name: interopnames.SystemContractCall, Func: contract.Call, Price: 1 << 15,
|
||||
RequiredFlags: smartcontract.AllowCall, ParamCount: 3, DisallowCallback: true},
|
||||
{Name: interopnames.SystemContractCallEx, Func: contract.CallEx, Price: 1 << 15,
|
||||
RequiredFlags: smartcontract.AllowCall, ParamCount: 4, DisallowCallback: true},
|
||||
{Name: interopnames.SystemContractCallNative, Func: native.Call, Price: 0, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemContractCreateStandardAccount, Func: contractCreateStandardAccount, Price: 1 << 8, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemContractIsStandard, Func: contractIsStandard, Price: 1 << 10, RequiredFlags: smartcontract.ReadStates, ParamCount: 1},
|
||||
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10, DisallowCallback: true},
|
||||
{Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: smartcontract.WriteStates, DisallowCallback: true},
|
||||
{Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: smartcontract.WriteStates, DisallowCallback: true},
|
||||
{Name: interopnames.SystemEnumeratorConcat, Func: enumerator.Concat, Price: 1 << 4, ParamCount: 2, DisallowCallback: true},
|
||||
{Name: interopnames.SystemEnumeratorCreate, Func: enumerator.Create, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemEnumeratorNext, Func: enumerator.Next, Price: 1 << 15, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemEnumeratorValue, Func: enumerator.Value, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemIteratorConcat, Func: iterator.Concat, Price: 1 << 4, ParamCount: 2, DisallowCallback: true},
|
||||
{Name: interopnames.SystemIteratorCreate, Func: iterator.Create, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemIteratorKey, Func: iterator.Key, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemIteratorKeys, Func: iterator.Keys, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemIteratorValues, Func: iterator.Values, Price: 1 << 4, ParamCount: 1, DisallowCallback: true},
|
||||
RequiredFlags: callflag.AllowCall, ParamCount: 4},
|
||||
{Name: interopnames.SystemContractCallNative, Func: native.Call, Price: 0, ParamCount: 1},
|
||||
{Name: interopnames.SystemContractCreateStandardAccount, Func: contractCreateStandardAccount, Price: 1 << 8, ParamCount: 1},
|
||||
{Name: interopnames.SystemContractIsStandard, Func: contractIsStandard, Price: 1 << 10, RequiredFlags: callflag.ReadStates, ParamCount: 1},
|
||||
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10},
|
||||
{Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.WriteStates},
|
||||
{Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: callflag.WriteStates},
|
||||
{Name: interopnames.SystemEnumeratorConcat, Func: enumerator.Concat, Price: 1 << 4, ParamCount: 2},
|
||||
{Name: interopnames.SystemEnumeratorCreate, Func: enumerator.Create, Price: 1 << 4, ParamCount: 1},
|
||||
{Name: interopnames.SystemEnumeratorNext, Func: enumerator.Next, Price: 1 << 15, ParamCount: 1},
|
||||
{Name: interopnames.SystemEnumeratorValue, Func: enumerator.Value, Price: 1 << 4, ParamCount: 1},
|
||||
{Name: interopnames.SystemIteratorConcat, Func: iterator.Concat, Price: 1 << 4, ParamCount: 2},
|
||||
{Name: interopnames.SystemIteratorCreate, Func: iterator.Create, Price: 1 << 4, ParamCount: 1},
|
||||
{Name: interopnames.SystemIteratorKey, Func: iterator.Key, Price: 1 << 4, ParamCount: 1},
|
||||
{Name: interopnames.SystemIteratorKeys, Func: iterator.Keys, Price: 1 << 4, ParamCount: 1},
|
||||
{Name: interopnames.SystemIteratorValues, Func: iterator.Values, Price: 1 << 4, ParamCount: 1},
|
||||
{Name: interopnames.SystemJSONDeserialize, Func: json.Deserialize, Price: 1 << 14, ParamCount: 1},
|
||||
{Name: interopnames.SystemJSONSerialize, Func: json.Serialize, Price: 1 << 12, ParamCount: 1},
|
||||
{Name: interopnames.SystemRuntimeCheckWitness, Func: runtime.CheckWitness, Price: 1 << 10,
|
||||
RequiredFlags: smartcontract.NoneFlag, ParamCount: 1},
|
||||
RequiredFlags: callflag.NoneFlag, ParamCount: 1},
|
||||
{Name: interopnames.SystemRuntimeGasLeft, Func: runtime.GasLeft, Price: 1 << 4},
|
||||
{Name: interopnames.SystemRuntimeGetCallingScriptHash, Func: runtime.GetCallingScriptHash, Price: 1 << 4},
|
||||
{Name: interopnames.SystemRuntimeGetEntryScriptHash, Func: runtime.GetEntryScriptHash, Price: 1 << 4},
|
||||
|
@ -85,29 +78,29 @@ var systemInterops = []interop.Function{
|
|||
{Name: interopnames.SystemRuntimeGetInvocationCounter, Func: runtime.GetInvocationCounter, Price: 1 << 4},
|
||||
{Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 1 << 8, ParamCount: 1},
|
||||
{Name: interopnames.SystemRuntimeGetScriptContainer, Func: engineGetScriptContainer, Price: 1 << 3},
|
||||
{Name: interopnames.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: smartcontract.ReadStates},
|
||||
{Name: interopnames.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: callflag.ReadStates},
|
||||
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtime.GetTrigger, Price: 1 << 3},
|
||||
{Name: interopnames.SystemRuntimeLog, Func: runtime.Log, Price: 1 << 15, RequiredFlags: smartcontract.AllowNotify,
|
||||
ParamCount: 1, DisallowCallback: true},
|
||||
{Name: interopnames.SystemRuntimeNotify, Func: runtime.Notify, Price: 1 << 15, RequiredFlags: smartcontract.AllowNotify,
|
||||
ParamCount: 2, DisallowCallback: true},
|
||||
{Name: interopnames.SystemRuntimeLog, Func: runtime.Log, Price: 1 << 15, RequiredFlags: callflag.AllowNotify,
|
||||
ParamCount: 1},
|
||||
{Name: interopnames.SystemRuntimeNotify, Func: runtime.Notify, Price: 1 << 15, RequiredFlags: callflag.AllowNotify,
|
||||
ParamCount: 2},
|
||||
{Name: interopnames.SystemRuntimePlatform, Func: runtime.Platform, Price: 1 << 3},
|
||||
{Name: interopnames.SystemStorageDelete, Func: storageDelete, Price: 0,
|
||||
RequiredFlags: smartcontract.WriteStates, ParamCount: 2, DisallowCallback: true},
|
||||
{Name: interopnames.SystemStorageFind, Func: storageFind, Price: 1 << 15, RequiredFlags: smartcontract.ReadStates,
|
||||
ParamCount: 2, DisallowCallback: true},
|
||||
{Name: interopnames.SystemStorageGet, Func: storageGet, Price: 1 << 15, RequiredFlags: smartcontract.ReadStates,
|
||||
ParamCount: 2, DisallowCallback: true},
|
||||
RequiredFlags: callflag.WriteStates, ParamCount: 2},
|
||||
{Name: interopnames.SystemStorageFind, Func: storageFind, Price: 1 << 15, RequiredFlags: callflag.ReadStates,
|
||||
ParamCount: 2},
|
||||
{Name: interopnames.SystemStorageGet, Func: storageGet, Price: 1 << 15, RequiredFlags: callflag.ReadStates,
|
||||
ParamCount: 2},
|
||||
{Name: interopnames.SystemStorageGetContext, Func: storageGetContext, Price: 1 << 4,
|
||||
RequiredFlags: smartcontract.ReadStates, DisallowCallback: true},
|
||||
RequiredFlags: callflag.ReadStates},
|
||||
{Name: interopnames.SystemStorageGetReadOnlyContext, Func: storageGetReadOnlyContext, Price: 1 << 4,
|
||||
RequiredFlags: smartcontract.ReadStates, DisallowCallback: true},
|
||||
{Name: interopnames.SystemStoragePut, Func: storagePut, Price: 0, RequiredFlags: smartcontract.WriteStates,
|
||||
ParamCount: 3, DisallowCallback: true}, // These don't have static price in C# code.
|
||||
{Name: interopnames.SystemStoragePutEx, Func: storagePutEx, Price: 0, RequiredFlags: smartcontract.WriteStates,
|
||||
ParamCount: 4, DisallowCallback: true},
|
||||
RequiredFlags: callflag.ReadStates},
|
||||
{Name: interopnames.SystemStoragePut, Func: storagePut, Price: 0, RequiredFlags: callflag.WriteStates,
|
||||
ParamCount: 3}, // These don't have static price in C# code.
|
||||
{Name: interopnames.SystemStoragePutEx, Func: storagePutEx, Price: 0, RequiredFlags: callflag.WriteStates,
|
||||
ParamCount: 4},
|
||||
{Name: interopnames.SystemStorageAsReadOnly, Func: storageContextAsReadOnly, Price: 1 << 4,
|
||||
RequiredFlags: smartcontract.ReadStates, ParamCount: 1, DisallowCallback: true},
|
||||
RequiredFlags: callflag.ReadStates, ParamCount: 1},
|
||||
}
|
||||
|
||||
var neoInterops = []interop.Function{
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -78,13 +79,13 @@ func newDesignate(p2pSigExtensionsEnabled bool) *Designate {
|
|||
desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType,
|
||||
manifest.NewParameter("role", smartcontract.IntegerType),
|
||||
manifest.NewParameter("index", smartcontract.IntegerType))
|
||||
md := newMethodAndPrice(s.getDesignatedByRole, 1000000, smartcontract.ReadStates)
|
||||
md := newMethodAndPrice(s.getDesignatedByRole, 1000000, callflag.ReadStates)
|
||||
s.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("designateAsRole", smartcontract.VoidType,
|
||||
manifest.NewParameter("role", smartcontract.IntegerType),
|
||||
manifest.NewParameter("nodes", smartcontract.ArrayType))
|
||||
md = newMethodAndPrice(s.designateAsRole, 0, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(s.designateAsRole, 0, callflag.WriteStates)
|
||||
s.AddMethod(md, desc)
|
||||
|
||||
return s
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
// Call calls specified native contract method.
|
||||
|
@ -27,7 +28,6 @@ func Call(ic *interop.Context) error {
|
|||
return errors.New("it is not allowed to use Neo.Native.Call directly to call native contracts. System.Contract.Call should be used")
|
||||
}
|
||||
operation := ic.VM.Estack().Pop().String()
|
||||
args := ic.VM.Estack().Pop().Array()
|
||||
m, ok := c.Metadata().Methods[operation]
|
||||
if !ok {
|
||||
return fmt.Errorf("method %s not found", operation)
|
||||
|
@ -40,6 +40,10 @@ func Call(ic *interop.Context) error {
|
|||
return errors.New("gas limit exceeded")
|
||||
}
|
||||
ctx := ic.VM.Context()
|
||||
args := make([]stackitem.Item, len(m.MD.Parameters))
|
||||
for i := range args {
|
||||
args[i] = ic.VM.Estack().Pop().Item()
|
||||
}
|
||||
result := m.Func(ic, args)
|
||||
if m.MD.ReturnType != smartcontract.VoidType {
|
||||
ctx.Estack().PushVal(result)
|
||||
|
|
|
@ -17,10 +17,10 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
|
@ -65,32 +65,32 @@ func newManagement() *Management {
|
|||
|
||||
desc := newDescriptor("getContract", smartcontract.ArrayType,
|
||||
manifest.NewParameter("hash", smartcontract.Hash160Type))
|
||||
md := newMethodAndPrice(m.getContract, 1000000, smartcontract.ReadStates)
|
||||
md := newMethodAndPrice(m.getContract, 1000000, callflag.ReadStates)
|
||||
m.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("deploy", smartcontract.ArrayType,
|
||||
manifest.NewParameter("script", smartcontract.ByteArrayType),
|
||||
manifest.NewParameter("manifest", smartcontract.ByteArrayType))
|
||||
md = newMethodAndPrice(m.deploy, 0, smartcontract.WriteStates|smartcontract.AllowNotify)
|
||||
md = newMethodAndPrice(m.deploy, 0, callflag.WriteStates|callflag.AllowNotify)
|
||||
m.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("update", smartcontract.VoidType,
|
||||
manifest.NewParameter("script", smartcontract.ByteArrayType),
|
||||
manifest.NewParameter("manifest", smartcontract.ByteArrayType))
|
||||
md = newMethodAndPrice(m.update, 0, smartcontract.WriteStates|smartcontract.AllowNotify)
|
||||
md = newMethodAndPrice(m.update, 0, callflag.WriteStates|callflag.AllowNotify)
|
||||
m.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("destroy", smartcontract.VoidType)
|
||||
md = newMethodAndPrice(m.destroy, 1000000, smartcontract.WriteStates|smartcontract.AllowNotify)
|
||||
md = newMethodAndPrice(m.destroy, 1000000, callflag.WriteStates|callflag.AllowNotify)
|
||||
m.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getMinimumDeploymentFee", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(m.getMinimumDeploymentFee, 100_0000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(m.getMinimumDeploymentFee, 100_0000, callflag.ReadStates)
|
||||
m.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setMinimumDeploymentFee", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(m.setMinimumDeploymentFee, 300_0000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(m.setMinimumDeploymentFee, 300_0000, callflag.WriteStates)
|
||||
m.AddMethod(md, desc)
|
||||
|
||||
hashParam := manifest.NewParameter("Hash", smartcontract.Hash160Type)
|
||||
|
@ -221,7 +221,7 @@ func (m *Management) deploy(ic *interop.Context, args []stackitem.Item) stackite
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
callDeploy(ic, newcontract, false)
|
||||
m.callDeploy(ic, newcontract, false)
|
||||
m.emitNotification(ic, contractDeployNotificationName, newcontract.Hash)
|
||||
return contractToStack(newcontract)
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ func (m *Management) update(ic *interop.Context, args []stackitem.Item) stackite
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
callDeploy(ic, contract, true)
|
||||
m.callDeploy(ic, contract, true)
|
||||
m.emitNotification(ic, contractUpdateNotificationName, contract.Hash)
|
||||
return stackitem.Null{}
|
||||
}
|
||||
|
@ -379,11 +379,11 @@ func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackit
|
|||
return stackitem.NewBool(true)
|
||||
}
|
||||
|
||||
func callDeploy(ic *interop.Context, cs *state.Contract, isUpdate bool) {
|
||||
func (m *Management) callDeploy(ic *interop.Context, cs *state.Contract, isUpdate bool) {
|
||||
md := cs.Manifest.ABI.GetMethod(manifest.MethodDeploy)
|
||||
if md != nil {
|
||||
err := contract.CallExInternal(ic, cs, manifest.MethodDeploy,
|
||||
[]stackitem.Item{stackitem.NewBool(isUpdate)}, smartcontract.All, vm.EnsureIsEmpty)
|
||||
err := contract.CallFromNative(ic, m.Hash, cs, manifest.MethodDeploy,
|
||||
[]stackitem.Item{stackitem.NewBool(isUpdate)}, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -110,44 +111,44 @@ func newNEO() *NEO {
|
|||
desc := newDescriptor("unclaimedGas", smartcontract.IntegerType,
|
||||
manifest.NewParameter("account", smartcontract.Hash160Type),
|
||||
manifest.NewParameter("end", smartcontract.IntegerType))
|
||||
md := newMethodAndPrice(n.unclaimedGas, 3000000, smartcontract.ReadStates)
|
||||
md := newMethodAndPrice(n.unclaimedGas, 3000000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("registerCandidate", smartcontract.BoolType,
|
||||
manifest.NewParameter("pubkey", smartcontract.ByteArrayType))
|
||||
md = newMethodAndPrice(n.registerCandidate, 5000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.registerCandidate, 5000000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("unregisterCandidate", smartcontract.BoolType,
|
||||
manifest.NewParameter("pubkey", smartcontract.ByteArrayType))
|
||||
md = newMethodAndPrice(n.unregisterCandidate, 5000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.unregisterCandidate, 5000000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("vote", smartcontract.BoolType,
|
||||
manifest.NewParameter("account", smartcontract.Hash160Type),
|
||||
manifest.NewParameter("pubkey", smartcontract.ByteArrayType))
|
||||
md = newMethodAndPrice(n.vote, 5000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.vote, 5000000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getCandidates", smartcontract.ArrayType)
|
||||
md = newMethodAndPrice(n.getCandidatesCall, 100000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.getCandidatesCall, 100000000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getСommittee", smartcontract.ArrayType)
|
||||
md = newMethodAndPrice(n.getCommittee, 100000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.getCommittee, 100000000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getNextBlockValidators", smartcontract.ArrayType)
|
||||
md = newMethodAndPrice(n.getNextBlockValidators, 100000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.getNextBlockValidators, 100000000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getGasPerBlock", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(n.getGASPerBlock, 100_0000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.getGASPerBlock, 100_0000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setGasPerBlock", smartcontract.BoolType,
|
||||
manifest.NewParameter("gasPerBlock", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(n.setGASPerBlock, 500_0000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.setGASPerBlock, 500_0000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
return n
|
||||
|
|
|
@ -12,9 +12,9 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
|
@ -47,20 +47,20 @@ func newNEP17Native(name string) *nep17TokenNative {
|
|||
n.Manifest.SupportedStandards = []string{manifest.NEP17StandardName}
|
||||
|
||||
desc := newDescriptor("symbol", smartcontract.StringType)
|
||||
md := newMethodAndPrice(n.Symbol, 0, smartcontract.NoneFlag)
|
||||
md := newMethodAndPrice(n.Symbol, 0, callflag.NoneFlag)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("decimals", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(n.Decimals, 0, smartcontract.NoneFlag)
|
||||
md = newMethodAndPrice(n.Decimals, 0, callflag.NoneFlag)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("totalSupply", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(n.TotalSupply, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.TotalSupply, 1000000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("balanceOf", smartcontract.IntegerType,
|
||||
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(n.balanceOf, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.balanceOf, 1000000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
transferParams := []manifest.Parameter{
|
||||
|
@ -71,7 +71,7 @@ func newNEP17Native(name string) *nep17TokenNative {
|
|||
desc = newDescriptor("transfer", smartcontract.BoolType,
|
||||
append(transferParams, manifest.NewParameter("data", smartcontract.AnyType))...,
|
||||
)
|
||||
md = newMethodAndPrice(n.Transfer, 9000000, smartcontract.WriteStates|smartcontract.AllowCall|smartcontract.AllowNotify)
|
||||
md = newMethodAndPrice(n.Transfer, 9000000, callflag.WriteStates|callflag.AllowCall|callflag.AllowNotify)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
n.AddEvent("Transfer", transferParams...)
|
||||
|
@ -143,7 +143,7 @@ func (c *nep17TokenNative) postTransfer(ic *interop.Context, from, to *util.Uint
|
|||
stackitem.NewBigInteger(amount),
|
||||
data,
|
||||
}
|
||||
if err := contract.CallFromNative(ic, c.Hash, cs, manifest.MethodOnPayment, args, vm.EnsureIsEmpty); err != nil {
|
||||
if err := contract.CallFromNative(ic, c.Hash, cs, manifest.MethodOnPayment, args, false); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ func newDescriptor(name string, ret smartcontract.ParamType, ps ...manifest.Para
|
|||
}
|
||||
}
|
||||
|
||||
func newMethodAndPrice(f interop.Method, price int64, flags smartcontract.CallFlag) *interop.MethodAndPrice {
|
||||
func newMethodAndPrice(f interop.Method, price int64, flags callflag.CallFlag) *interop.MethodAndPrice {
|
||||
return &interop.MethodAndPrice{
|
||||
Func: f,
|
||||
Price: price,
|
||||
|
|
|
@ -17,9 +17,9 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
|
@ -59,43 +59,43 @@ func newNotary() *Notary {
|
|||
manifest.NewParameter("from", smartcontract.Hash160Type),
|
||||
manifest.NewParameter("amount", smartcontract.IntegerType),
|
||||
manifest.NewParameter("data", smartcontract.AnyType))
|
||||
md := newMethodAndPrice(n.onPayment, 100_0000, smartcontract.WriteStates)
|
||||
md := newMethodAndPrice(n.onPayment, 100_0000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("lockDepositUntil", smartcontract.BoolType,
|
||||
manifest.NewParameter("address", smartcontract.Hash160Type),
|
||||
manifest.NewParameter("till", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(n.lockDepositUntil, 100_0000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.lockDepositUntil, 100_0000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("withdraw", smartcontract.BoolType,
|
||||
manifest.NewParameter("from", smartcontract.Hash160Type),
|
||||
manifest.NewParameter("to", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(n.withdraw, 100_0000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.withdraw, 100_0000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("balanceOf", smartcontract.IntegerType,
|
||||
manifest.NewParameter("addr", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(n.balanceOf, 100_0000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.balanceOf, 100_0000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("expirationOf", smartcontract.IntegerType,
|
||||
manifest.NewParameter("addr", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(n.expirationOf, 100_0000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.expirationOf, 100_0000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("verify", smartcontract.BoolType,
|
||||
manifest.NewParameter("signature", smartcontract.SignatureType))
|
||||
md = newMethodAndPrice(n.verify, 100_0000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.verify, 100_0000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getMaxNotValidBeforeDelta", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(n.getMaxNotValidBeforeDelta, 100_0000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(n.getMaxNotValidBeforeDelta, 100_0000, callflag.ReadStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setMaxNotValidBeforeDelta", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(n.setMaxNotValidBeforeDelta, 300_0000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(n.setMaxNotValidBeforeDelta, 300_0000, callflag.WriteStates)
|
||||
n.AddMethod(md, desc)
|
||||
|
||||
return n
|
||||
|
@ -276,7 +276,7 @@ func (n *Notary) withdraw(ic *interop.Context, args []stackitem.Item) stackitem.
|
|||
panic(fmt.Errorf("failed to get GAS contract state: %w", err))
|
||||
}
|
||||
transferArgs := []stackitem.Item{stackitem.NewByteArray(n.Hash.BytesBE()), stackitem.NewByteArray(to.BytesBE()), stackitem.NewBigInteger(deposit.Amount), stackitem.Null{}}
|
||||
err = contract.CallFromNative(ic, n.Hash, cs, "transfer", transferArgs, vm.EnsureNotEmpty)
|
||||
err = contract.CallFromNative(ic, n.Hash, cs, "transfer", transferArgs, true)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to transfer GAS from Notary account: %w", err))
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -56,6 +56,7 @@ func init() {
|
|||
w := io.NewBufBinWriter()
|
||||
emit.Int(w.BinWriter, 0)
|
||||
emit.Opcodes(w.BinWriter, opcode.NEWARRAY)
|
||||
emit.Int(w.BinWriter, int64(callflag.All))
|
||||
emit.String(w.BinWriter, "finish")
|
||||
emit.Bytes(w.BinWriter, h.BytesBE())
|
||||
emit.Syscall(w.BinWriter, interopnames.SystemContractCall)
|
||||
|
@ -94,15 +95,15 @@ func newOracle() *Oracle {
|
|||
manifest.NewParameter("callback", smartcontract.StringType),
|
||||
manifest.NewParameter("userData", smartcontract.AnyType),
|
||||
manifest.NewParameter("gasForResponse", smartcontract.IntegerType))
|
||||
md := newMethodAndPrice(o.request, oracleRequestPrice, smartcontract.WriteStates|smartcontract.AllowNotify)
|
||||
md := newMethodAndPrice(o.request, oracleRequestPrice, callflag.WriteStates|callflag.AllowNotify)
|
||||
o.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("finish", smartcontract.VoidType)
|
||||
md = newMethodAndPrice(o.finish, 0, smartcontract.WriteStates|smartcontract.AllowCall|smartcontract.AllowNotify)
|
||||
md = newMethodAndPrice(o.finish, 0, callflag.WriteStates|callflag.AllowCall|callflag.AllowNotify)
|
||||
o.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("verify", smartcontract.BoolType)
|
||||
md = newMethodAndPrice(o.verify, 100_0000, smartcontract.NoneFlag)
|
||||
md = newMethodAndPrice(o.verify, 100_0000, callflag.NoneFlag)
|
||||
o.AddMethod(md, desc)
|
||||
|
||||
o.AddEvent("OracleRequest", manifest.NewParameter("Id", smartcontract.IntegerType),
|
||||
|
@ -238,7 +239,7 @@ func (o *Oracle) FinishInternal(ic *interop.Context) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return contract.CallFromNative(ic, o.Hash, cs, req.CallbackMethod, args, vm.EnsureIsEmpty)
|
||||
return contract.CallFromNative(ic, o.Hash, cs, req.CallbackMethod, args, false)
|
||||
}
|
||||
|
||||
func (o *Oracle) request(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -85,72 +86,72 @@ func newPolicy() *Policy {
|
|||
p.ContractID = policyContractID
|
||||
|
||||
desc := newDescriptor("getMaxTransactionsPerBlock", smartcontract.IntegerType)
|
||||
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, smartcontract.ReadStates)
|
||||
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getMaxBlockSize", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(p.getMaxBlockSize, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(p.getMaxBlockSize, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getFeePerByte", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(p.getFeePerByte, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(p.getFeePerByte, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("isBlocked", smartcontract.BoolType,
|
||||
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(p.isBlocked, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(p.isBlocked, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getMaxBlockSystemFee", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(p.getMaxBlockSystemFee, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(p.getMaxBlockSystemFee, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getExecFeeFactor", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(p.getExecFeeFactor, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(p.getExecFeeFactor, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setExecFeeFactor", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(p.setExecFeeFactor, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.setExecFeeFactor, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("getStoragePrice", smartcontract.IntegerType)
|
||||
md = newMethodAndPrice(p.getStoragePrice, 1000000, smartcontract.ReadStates)
|
||||
md = newMethodAndPrice(p.getStoragePrice, 1000000, callflag.ReadStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setStoragePrice", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(p.setStoragePrice, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.setStoragePrice, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setMaxBlockSize", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(p.setMaxBlockSize, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.setMaxBlockSize, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setMaxTransactionsPerBlock", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(p.setMaxTransactionsPerBlock, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.setMaxTransactionsPerBlock, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setFeePerByte", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(p.setFeePerByte, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.setFeePerByte, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("setMaxBlockSystemFee", smartcontract.BoolType,
|
||||
manifest.NewParameter("value", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(p.setMaxBlockSystemFee, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.setMaxBlockSystemFee, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("blockAccount", smartcontract.BoolType,
|
||||
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(p.blockAccount, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.blockAccount, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("unblockAccount", smartcontract.BoolType,
|
||||
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||
md = newMethodAndPrice(p.unblockAccount, 3000000, smartcontract.WriteStates)
|
||||
md = newMethodAndPrice(p.unblockAccount, 3000000, callflag.WriteStates)
|
||||
p.AddMethod(md, desc)
|
||||
|
||||
return p
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"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/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -75,7 +76,7 @@ func newTestNative() *testNative {
|
|||
md := &interop.MethodAndPrice{
|
||||
Func: tn.sum,
|
||||
Price: testSumPrice,
|
||||
RequiredFlags: smartcontract.NoneFlag,
|
||||
RequiredFlags: callflag.NoneFlag,
|
||||
}
|
||||
tn.meta.AddMethod(md, desc)
|
||||
|
||||
|
@ -92,7 +93,7 @@ func newTestNative() *testNative {
|
|||
md = &interop.MethodAndPrice{
|
||||
Func: tn.callOtherContractNoReturn,
|
||||
Price: testSumPrice,
|
||||
RequiredFlags: smartcontract.NoneFlag}
|
||||
RequiredFlags: callflag.NoneFlag}
|
||||
tn.meta.AddMethod(md, desc)
|
||||
|
||||
desc = &manifest.Method{
|
||||
|
@ -107,7 +108,7 @@ func newTestNative() *testNative {
|
|||
md = &interop.MethodAndPrice{
|
||||
Func: tn.callOtherContractWithReturn,
|
||||
Price: testSumPrice,
|
||||
RequiredFlags: smartcontract.NoneFlag}
|
||||
RequiredFlags: callflag.NoneFlag}
|
||||
tn.meta.AddMethod(md, desc)
|
||||
|
||||
return tn
|
||||
|
@ -137,7 +138,7 @@ func toUint160(item stackitem.Item) util.Uint160 {
|
|||
return u
|
||||
}
|
||||
|
||||
func (tn *testNative) call(ic *interop.Context, args []stackitem.Item, checkReturn vm.CheckReturnState) {
|
||||
func (tn *testNative) call(ic *interop.Context, args []stackitem.Item, hasReturn bool) {
|
||||
cs, err := ic.GetContract(toUint160(args[0]))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -146,19 +147,19 @@ func (tn *testNative) call(ic *interop.Context, args []stackitem.Item, checkRetu
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = contract.CallFromNative(ic, tn.meta.Hash, cs, string(bs), args[2].Value().([]stackitem.Item), checkReturn)
|
||||
err = contract.CallFromNative(ic, tn.meta.Hash, cs, string(bs), args[2].Value().([]stackitem.Item), hasReturn)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (tn *testNative) callOtherContractNoReturn(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
tn.call(ic, args, vm.EnsureIsEmpty)
|
||||
tn.call(ic, args, false)
|
||||
return stackitem.Null{}
|
||||
}
|
||||
|
||||
func (tn *testNative) callOtherContractWithReturn(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
tn.call(ic, args, vm.EnsureNotEmpty)
|
||||
tn.call(ic, args, true)
|
||||
bi := ic.VM.Estack().Pop().BigInt()
|
||||
return stackitem.Make(bi.Add(bi, big.NewInt(1)))
|
||||
}
|
||||
|
@ -183,6 +184,7 @@ func TestNativeContract_Invoke(t *testing.T) {
|
|||
price += 3 * fee.Opcode(chain.GetBaseExecFee(), opcode.PUSHINT8, opcode.PUSHDATA1)
|
||||
price += 2 * fee.Opcode(chain.GetBaseExecFee(), opcode.SYSCALL)
|
||||
price += fee.Opcode(chain.GetBaseExecFee(), opcode.PACK)
|
||||
price += fee.Opcode(chain.GetBaseExecFee(), opcode.PUSHINT8)
|
||||
res, err := invokeContractMethod(chain, price, tn.Metadata().Hash, "sum", int64(14), int64(28))
|
||||
require.NoError(t, err)
|
||||
checkResult(t, res, stackitem.Make(42))
|
||||
|
@ -220,8 +222,9 @@ func TestNativeContract_InvokeInternal(t *testing.T) {
|
|||
v := ic.SpawnVM()
|
||||
|
||||
t.Run("fail, bad current script hash", func(t *testing.T) {
|
||||
v.LoadScriptWithHash([]byte{1}, util.Uint160{1, 2, 3}, smartcontract.All)
|
||||
v.Estack().PushVal(stackitem.NewArray([]stackitem.Item{stackitem.NewBigInteger(big.NewInt(14)), stackitem.NewBigInteger(big.NewInt(28))}))
|
||||
v.LoadScriptWithHash([]byte{1}, util.Uint160{1, 2, 3}, callflag.All)
|
||||
v.Estack().PushVal(14)
|
||||
v.Estack().PushVal(28)
|
||||
v.Estack().PushVal("sum")
|
||||
v.Estack().PushVal(tn.Metadata().Name)
|
||||
|
||||
|
@ -230,8 +233,9 @@ func TestNativeContract_InvokeInternal(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
v.LoadScriptWithHash([]byte{1}, tn.Metadata().Hash, smartcontract.All)
|
||||
v.Estack().PushVal(stackitem.NewArray([]stackitem.Item{stackitem.NewBigInteger(big.NewInt(14)), stackitem.NewBigInteger(big.NewInt(28))}))
|
||||
v.LoadScriptWithHash([]byte{1}, tn.Metadata().Hash, callflag.All)
|
||||
v.Estack().PushVal(14)
|
||||
v.Estack().PushVal(28)
|
||||
v.Estack().PushVal("sum")
|
||||
v.Estack().PushVal(tn.Metadata().Name)
|
||||
|
||||
|
@ -272,6 +276,7 @@ func TestNativeContract_InvokeOtherContract(t *testing.T) {
|
|||
res, err := invokeContractMethod(chain, testSumPrice*4+10000, tn.Metadata().Hash, "callOtherContractNoReturn", cs.Hash, "justReturn", []interface{}{})
|
||||
require.NoError(t, err)
|
||||
drainTN(t)
|
||||
require.Equal(t, vm.HaltState, res.VMState, res.FaultException)
|
||||
checkResult(t, res, stackitem.Null{}) // simple call is done with EnsureNotEmpty
|
||||
})
|
||||
t.Run("non-native, with return", func(t *testing.T) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
|
@ -29,8 +30,7 @@ func (bc *Blockchain) setNodesByRole(t *testing.T, ok bool, r native.Role, nodes
|
|||
emit.Int(w.BinWriter, int64(r))
|
||||
emit.Int(w.BinWriter, 2)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.String(w.BinWriter, "designateAsRole")
|
||||
emit.AppCall(w.BinWriter, bc.contracts.Designate.Hash)
|
||||
emit.AppCallNoArgs(w.BinWriter, bc.contracts.Designate.Hash, "designateAsRole", callflag.All)
|
||||
require.NoError(t, w.Err)
|
||||
tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 0)
|
||||
tx.NetworkFee = 10_000_000
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"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"
|
||||
|
@ -75,11 +76,11 @@ func TestNEO_Vote(t *testing.T) {
|
|||
|
||||
to := accs[i].Contract.ScriptHash()
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.contracts.NEO.Hash, "transfer",
|
||||
emit.AppCall(w.BinWriter, bc.contracts.NEO.Hash, "transfer", callflag.All,
|
||||
neoOwner.BytesBE(), to.BytesBE(),
|
||||
big.NewInt(int64(sz-i)*1000000).Int64(), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.contracts.GAS.Hash, "transfer",
|
||||
emit.AppCall(w.BinWriter, bc.contracts.GAS.Hash, "transfer", callflag.All,
|
||||
neoOwner.BytesBE(), to.BytesBE(),
|
||||
int64(1_000_000_000), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
|
@ -141,7 +142,7 @@ func TestNEO_Vote(t *testing.T) {
|
|||
h := accs[i].PrivateKey().GetScriptHash()
|
||||
gasBalance[i] = bc.GetUtilityTokenBalance(h)
|
||||
neoBalance[i], _ = bc.GetGoverningTokenBalance(h)
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, bc.contracts.NEO.Hash, "transfer",
|
||||
emit.AppCall(w.BinWriter, bc.contracts.NEO.Hash, "transfer", callflag.All,
|
||||
h.BytesBE(), h.BytesBE(), int64(1), nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
require.NoError(t, w.Err)
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"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"
|
||||
|
@ -174,7 +175,8 @@ func TestNotaryContractPipeline(t *testing.T) {
|
|||
|
||||
// `withdraw`: bad witness
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, notaryHash, "withdraw", testchain.MultisigScriptHash(), acc.PrivateKey().PublicKey().GetScriptHash())
|
||||
emit.AppCall(w.BinWriter, notaryHash, "withdraw", callflag.All,
|
||||
testchain.MultisigScriptHash(), acc.PrivateKey().PublicKey().GetScriptHash())
|
||||
require.NoError(t, w.Err)
|
||||
script := w.Bytes()
|
||||
withdrawTx := transaction.New(chain.GetConfig().Magic, script, 10000000)
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
|
@ -32,9 +33,11 @@ func getOracleContractState(h util.Uint160) *state.Contract {
|
|||
w := io.NewBufBinWriter()
|
||||
emit.Int(w.BinWriter, 5)
|
||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||
emit.Int(w.BinWriter, int64(callflag.All))
|
||||
emit.String(w.BinWriter, "request")
|
||||
emit.Bytes(w.BinWriter, h.BytesBE())
|
||||
emit.Syscall(w.BinWriter, interopnames.SystemContractCall)
|
||||
emit.Opcodes(w.BinWriter, opcode.DROP)
|
||||
emit.Opcodes(w.BinWriter, opcode.RET)
|
||||
|
||||
// `handle` method aborts if len(userData) == 2
|
||||
|
@ -171,7 +174,7 @@ func TestOracle_Request(t *testing.T) {
|
|||
|
||||
// We need to ensure that callback is called thus, executing full script is necessary.
|
||||
resp.ID = 1
|
||||
ic.VM.LoadScriptWithFlags(tx.Script, smartcontract.All)
|
||||
ic.VM.LoadScriptWithFlags(tx.Script, callflag.All)
|
||||
require.NoError(t, ic.VM.Run())
|
||||
|
||||
si := ic.DAO.GetStorageItem(cs.ID, []byte("lastOracleResponse"))
|
||||
|
@ -211,7 +214,7 @@ func TestOracle_Request(t *testing.T) {
|
|||
}}
|
||||
ic := bc.newInteropContext(trigger.Application, bc.dao, bc.newBlock(tx), tx)
|
||||
ic.VM = ic.SpawnVM()
|
||||
ic.VM.LoadScriptWithFlags(tx.Script, smartcontract.All)
|
||||
ic.VM.LoadScriptWithFlags(tx.Script, callflag.All)
|
||||
require.Error(t, ic.VM.Run())
|
||||
|
||||
// Request is cleaned up even if callback failed.
|
||||
|
|
|
@ -40,17 +40,9 @@ func GetCallFlags() int64 {
|
|||
}
|
||||
|
||||
// Call executes previously deployed blockchain contract with specified hash
|
||||
// (20 bytes in BE form) using provided arguments.
|
||||
// It returns whatever this contract returns. This function uses
|
||||
// `System.Contract.Call` syscall.
|
||||
func Call(scriptHash interop.Hash160, method string, args ...interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CallEx executes previously deployed blockchain contract with specified hash
|
||||
// (20 bytes in BE form) using provided arguments and call flags.
|
||||
// It returns whatever this contract returns. This function uses
|
||||
// `System.Contract.CallEx` syscall.
|
||||
func CallEx(f CallFlag, scriptHash interop.Hash160, method string, args ...interface{}) interface{} {
|
||||
// `System.Contract.Call` syscall.
|
||||
func Call(scriptHash interop.Hash160, method string, f CallFlag, args ...interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -120,8 +121,8 @@ func (c *Client) CreateNEP17MultiTransferTx(acc *wallet.Account, gas int64, reci
|
|||
}
|
||||
w := io.NewBufBinWriter()
|
||||
for i := range recipients {
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, recipients[i].Token, "transfer", from,
|
||||
recipients[i].Address, recipients[i].Amount, nil)
|
||||
emit.AppCall(w.BinWriter, recipients[i].Token, "transfer",
|
||||
callflag.WriteStates|callflag.AllowCall|callflag.AllowNotify, from, recipients[i].Address, recipients[i].Amount, nil)
|
||||
emit.Opcodes(w.BinWriter, opcode.ASSERT)
|
||||
}
|
||||
accAddr, err := address.StringToUint160(acc.Address)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
|
@ -101,7 +102,7 @@ func expandArrayIntoScript(script *io.BinWriter, slice []Param) error {
|
|||
|
||||
// CreateFunctionInvocationScript creates a script to invoke given contract with
|
||||
// given parameters.
|
||||
func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byte, error) {
|
||||
func CreateFunctionInvocationScript(contract util.Uint160, method string, params Params) ([]byte, error) {
|
||||
script := io.NewBufBinWriter()
|
||||
for i := len(params) - 1; i >= 0; i-- {
|
||||
switch params[i].Type {
|
||||
|
@ -127,6 +128,6 @@ func CreateFunctionInvocationScript(contract util.Uint160, params Params) ([]byt
|
|||
}
|
||||
}
|
||||
|
||||
emit.AppCall(script.BinWriter, contract)
|
||||
emit.AppCallNoArgs(script.BinWriter, contract, method, callflag.All)
|
||||
return script.Bytes(), nil
|
||||
}
|
||||
|
|
|
@ -21,46 +21,44 @@ func TestInvocationScriptCreationGood(t *testing.T) {
|
|||
ps Params
|
||||
script string
|
||||
}{{
|
||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "transfer"}},
|
||||
script: "0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "1f0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: NumberT, Value: 42}},
|
||||
script: "0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "1f0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{}}},
|
||||
script: "10c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "10c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}}}}}},
|
||||
script: "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.SignatureType, Value: Param{Type: StringT, Value: "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}}}}}},
|
||||
script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.StringType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
|
||||
script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash160Type, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}},
|
||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.Hash256Type, Value: Param{Type: StringT, Value: "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}}}}}},
|
||||
script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.PublicKeyType, Value: Param{Type: StringT, Value: "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}}}}}},
|
||||
script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.IntegerType, Value: Param{Type: NumberT, Value: 42}}}}}},
|
||||
script: "002a11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "002a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "true"}}}}}},
|
||||
script: "1111c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}, {
|
||||
ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.BoolType, Value: Param{Type: StringT, Value: "false"}}}}}},
|
||||
script: "1011c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
script: "1011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
||||
}}
|
||||
for _, ps := range paramScripts {
|
||||
script, err := CreateFunctionInvocationScript(contract, ps.ps)
|
||||
script, err := CreateFunctionInvocationScript(contract, ps.ps[0].String(), ps.ps[1:])
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ps.script, hex.EncodeToString(script))
|
||||
}
|
||||
|
@ -86,7 +84,7 @@ func TestInvocationScriptCreationBad(t *testing.T) {
|
|||
{{Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.UnknownType, Value: Param{}}}}}},
|
||||
}
|
||||
for _, ps := range testParams {
|
||||
_, err := CreateFunctionInvocationScript(contract, ps)
|
||||
_, err := CreateFunctionInvocationScript(contract, "", ps)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"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/opcode"
|
||||
|
@ -276,7 +277,7 @@ func TestCreateNEP17TransferTx(t *testing.T) {
|
|||
require.NoError(t, acc.SignTx(tx))
|
||||
require.NoError(t, chain.VerifyTx(tx))
|
||||
v := chain.GetTestVM(trigger.Application, tx, nil)
|
||||
v.LoadScriptWithFlags(tx.Script, smartcontract.All)
|
||||
v.LoadScriptWithFlags(tx.Script, callflag.All)
|
||||
require.NoError(t, v.Run())
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -1097,7 +1097,7 @@ func (s *Server) invokeFunction(reqParams request.Params) (interface{}, *respons
|
|||
if len(tx.Signers) == 0 {
|
||||
tx.Signers = []transaction.Signer{{Account: util.Uint160{}, Scopes: transaction.None}}
|
||||
}
|
||||
script, err := request.CreateFunctionInvocationScript(scriptHash, reqParams[1:checkWitnessHashesIndex])
|
||||
script, err := request.CreateFunctionInvocationScript(scriptHash, reqParams[1].String(), reqParams[2:checkWitnessHashesIndex])
|
||||
if err != nil {
|
||||
return nil, response.NewInternalServerError("can't create invocation script", err)
|
||||
}
|
||||
|
@ -1138,14 +1138,7 @@ func (s *Server) invokeContractVerify(reqParams request.Params) (interface{}, *r
|
|||
return nil, responseErr
|
||||
}
|
||||
|
||||
args := make(request.Params, 1)
|
||||
args[0] = request.Param{
|
||||
Type: request.StringT,
|
||||
Value: manifest.MethodVerify,
|
||||
}
|
||||
if len(reqParams) > 1 {
|
||||
args = append(args, reqParams[1])
|
||||
}
|
||||
args := reqParams[1:2]
|
||||
var tx *transaction.Transaction
|
||||
if len(reqParams) > 2 {
|
||||
signers, witnesses, err := reqParams[2].GetSignersWithWitnesses()
|
||||
|
@ -1162,7 +1155,7 @@ func (s *Server) invokeContractVerify(reqParams request.Params) (interface{}, *r
|
|||
if cs == nil {
|
||||
return nil, response.NewRPCError("unknown contract", scriptHash.StringBE(), nil)
|
||||
}
|
||||
script, err := request.CreateFunctionInvocationScript(cs.Hash, args)
|
||||
script, err := request.CreateFunctionInvocationScript(cs.Hash, manifest.MethodVerify, args)
|
||||
if err != nil {
|
||||
return nil, response.NewInternalServerError("can't create invocation script", err)
|
||||
}
|
||||
|
@ -1188,7 +1181,7 @@ func (s *Server) runScriptInVM(t trigger.Type, script []byte, tx *transaction.Tr
|
|||
|
||||
vm := s.chain.GetTestVM(t, tx, b)
|
||||
vm.GasLimit = int64(s.config.MaxGasInvoke)
|
||||
vm.LoadScriptWithFlags(script, smartcontract.All)
|
||||
vm.LoadScriptWithFlags(script, callflag.All)
|
||||
err = vm.Run()
|
||||
var faultException string
|
||||
if err != nil {
|
||||
|
|
|
@ -57,7 +57,7 @@ type rpcTestCase struct {
|
|||
}
|
||||
|
||||
const testContractHash = "743ed26f78e29ecd595535b74a943b1f9ccbc444"
|
||||
const deploymentTxHash = "a4644e08389ced59e875a8d5bdcb8fdded7507ed7dc3915a37e5be71736ac7b4"
|
||||
const deploymentTxHash = "2aef5684c6cf60884cc00400b78c65c5105ed4261a4f614bce74c74927a66bf3"
|
||||
const genesisBlockHash = "0542f4350c6e236d0509bcd98188b0034bfbecc1a0c7fcdb8e4295310d468b70"
|
||||
|
||||
const verifyContractHash = "a2eb22340979804cb10cc1add0b8822c201f4d8a"
|
||||
|
@ -1408,7 +1408,7 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
|
|||
},
|
||||
{
|
||||
Asset: e.chain.UtilityTokenHash(),
|
||||
Amount: "80006564770",
|
||||
Amount: "80006675650",
|
||||
LastUpdated: 7,
|
||||
}},
|
||||
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
|
||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
package smartcontract
|
||||
package callflag
|
||||
|
||||
// CallFlag represents call flag.
|
||||
type CallFlag byte
|
|
@ -1,4 +1,4 @@
|
|||
package smartcontract
|
||||
package callflag
|
||||
|
||||
import (
|
||||
"testing"
|
|
@ -6,7 +6,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -46,10 +46,12 @@ type Context struct {
|
|||
isDeployed bool
|
||||
|
||||
// Call flags this context was created with.
|
||||
callFlag smartcontract.CallFlag
|
||||
callFlag callflag.CallFlag
|
||||
|
||||
// CheckReturn specifies if amount of return values needs to be checked.
|
||||
CheckReturn CheckReturnState
|
||||
// ParamCount specifies number of parameters.
|
||||
ParamCount int
|
||||
// RetCount specifies number of return values.
|
||||
RetCount int
|
||||
}
|
||||
|
||||
// CheckReturnState represents possible states of stack after opcode.RET was processed.
|
||||
|
@ -69,9 +71,18 @@ var errNoInstParam = errors.New("failed to read instruction parameter")
|
|||
|
||||
// NewContext returns a new Context object.
|
||||
func NewContext(b []byte) *Context {
|
||||
return NewContextWithParams(b, 0, -1, 0)
|
||||
}
|
||||
|
||||
// NewContextWithParams creates new Context objects using script, parameter count,
|
||||
// return value count and initial position in script.
|
||||
func NewContextWithParams(b []byte, pcount int, rvcount int, pos int) *Context {
|
||||
return &Context{
|
||||
prog: b,
|
||||
breakPoints: []int{},
|
||||
ParamCount: pcount,
|
||||
RetCount: rvcount,
|
||||
nextip: pos,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +205,7 @@ func (c *Context) Copy() *Context {
|
|||
}
|
||||
|
||||
// GetCallFlags returns calling flags context was created with.
|
||||
func (c *Context) GetCallFlags() smartcontract.CallFlag {
|
||||
func (c *Context) GetCallFlags() callflag.CallFlag {
|
||||
return c.callFlag
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -150,17 +151,18 @@ func Jmp(w *io.BinWriter, op opcode.Opcode, label uint16) {
|
|||
Instruction(w, op, buf)
|
||||
}
|
||||
|
||||
// AppCall emits call to provided contract.
|
||||
func AppCall(w *io.BinWriter, scriptHash util.Uint160) {
|
||||
// AppCallNoArgs emits call to provided contract.
|
||||
func AppCallNoArgs(w *io.BinWriter, scriptHash util.Uint160, operation string, f callflag.CallFlag) {
|
||||
Int(w, int64(f))
|
||||
String(w, operation)
|
||||
Bytes(w, scriptHash.BytesBE())
|
||||
Syscall(w, interopnames.SystemContractCall)
|
||||
}
|
||||
|
||||
// AppCallWithOperationAndArgs emits an APPCALL with the given operation and arguments.
|
||||
func AppCallWithOperationAndArgs(w *io.BinWriter, scriptHash util.Uint160, operation string, args ...interface{}) {
|
||||
// AppCall emits an APPCALL with the default parameters given operation and arguments.
|
||||
func AppCall(w *io.BinWriter, scriptHash util.Uint160, operation string, f callflag.CallFlag, args ...interface{}) {
|
||||
Array(w, args...)
|
||||
String(w, operation)
|
||||
AppCall(w, scriptHash)
|
||||
AppCallNoArgs(w, scriptHash, operation, f)
|
||||
}
|
||||
|
||||
func isInstructionJmp(op opcode.Opcode) bool {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
|
@ -15,7 +15,7 @@ type interopIDFuncPrice struct {
|
|||
ID uint32
|
||||
Func func(vm *VM) error
|
||||
Price int64
|
||||
RequiredFlags smartcontract.CallFlag
|
||||
RequiredFlags callflag.CallFlag
|
||||
}
|
||||
|
||||
var defaultVMInterops = []interopIDFuncPrice{
|
||||
|
@ -24,9 +24,9 @@ var defaultVMInterops = []interopIDFuncPrice{
|
|||
{ID: interopnames.ToID([]byte(interopnames.SystemBinarySerialize)),
|
||||
Func: RuntimeSerialize, Price: 1 << 12},
|
||||
{ID: interopnames.ToID([]byte(interopnames.SystemRuntimeLog)),
|
||||
Func: runtimeLog, Price: 1 << 15, RequiredFlags: smartcontract.AllowNotify},
|
||||
Func: runtimeLog, Price: 1 << 15, RequiredFlags: callflag.AllowNotify},
|
||||
{ID: interopnames.ToID([]byte(interopnames.SystemRuntimeNotify)),
|
||||
Func: runtimeNotify, Price: 1 << 15, RequiredFlags: smartcontract.AllowNotify},
|
||||
Func: runtimeNotify, Price: 1 << 15, RequiredFlags: callflag.AllowNotify},
|
||||
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorCreate)),
|
||||
Func: EnumeratorCreate, Price: 1 << 4},
|
||||
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorNext)),
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -114,7 +114,7 @@ func testSyscallHandler(v *VM, id uint32) error {
|
|||
case 0x77777777:
|
||||
v.Estack().PushVal(stackitem.NewInterop(new(int)))
|
||||
case 0x66666666:
|
||||
if !v.Context().callFlag.Has(smartcontract.ReadOnly) {
|
||||
if !v.Context().callFlag.Has(callflag.ReadOnly) {
|
||||
return errors.New("invalid call flags")
|
||||
}
|
||||
v.Estack().PushVal(stackitem.NewInterop(new(int)))
|
||||
|
|
40
pkg/vm/vm.go
40
pkg/vm/vm.go
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -272,13 +272,13 @@ func (v *VM) Load(prog []byte) {
|
|||
// will immediately push a new context created from this script to
|
||||
// the invocation stack and starts executing it.
|
||||
func (v *VM) LoadScript(b []byte) {
|
||||
v.LoadScriptWithFlags(b, smartcontract.NoneFlag)
|
||||
v.LoadScriptWithFlags(b, callflag.NoneFlag)
|
||||
}
|
||||
|
||||
// LoadScriptWithFlags loads script and sets call flag to f.
|
||||
func (v *VM) LoadScriptWithFlags(b []byte, f smartcontract.CallFlag) {
|
||||
func (v *VM) LoadScriptWithFlags(b []byte, f callflag.CallFlag) {
|
||||
v.checkInvocationStackSize()
|
||||
ctx := NewContext(b)
|
||||
ctx := NewContextWithParams(b, 0, -1, 0)
|
||||
v.estack = v.newItemStack("estack")
|
||||
ctx.estack = v.estack
|
||||
ctx.tryStack = NewStack("exception")
|
||||
|
@ -294,19 +294,26 @@ func (v *VM) LoadScriptWithFlags(b []byte, f smartcontract.CallFlag) {
|
|||
// assumes that it is used for deployed contracts setting context's parameters
|
||||
// accordingly). It's up to user of this function to make sure the script and hash match
|
||||
// each other.
|
||||
func (v *VM) LoadScriptWithHash(b []byte, hash util.Uint160, f smartcontract.CallFlag) {
|
||||
func (v *VM) LoadScriptWithHash(b []byte, hash util.Uint160, f callflag.CallFlag) {
|
||||
shash := v.GetCurrentScriptHash()
|
||||
v.LoadScriptWithCallingHash(shash, b, hash, f)
|
||||
v.LoadScriptWithCallingHash(shash, b, hash, f, true, 0)
|
||||
}
|
||||
|
||||
// LoadScriptWithCallingHash is similar to LoadScriptWithHash but sets calling hash explicitly.
|
||||
// It should be used for calling from native contracts.
|
||||
func (v *VM) LoadScriptWithCallingHash(caller util.Uint160, b []byte, hash util.Uint160, f smartcontract.CallFlag) {
|
||||
func (v *VM) LoadScriptWithCallingHash(caller util.Uint160, b []byte, hash util.Uint160,
|
||||
f callflag.CallFlag, hasReturn bool, paramCount uint16) {
|
||||
v.LoadScriptWithFlags(b, f)
|
||||
ctx := v.Context()
|
||||
ctx.isDeployed = true
|
||||
ctx.scriptHash = hash
|
||||
ctx.callingScriptHash = caller
|
||||
if hasReturn {
|
||||
ctx.RetCount = 1
|
||||
} else {
|
||||
ctx.RetCount = 0
|
||||
}
|
||||
ctx.ParamCount = int(paramCount)
|
||||
}
|
||||
|
||||
// Context returns the current executed context. Nil if there is no context,
|
||||
|
@ -1274,6 +1281,10 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
|
||||
newEstack := v.Context().estack
|
||||
if oldEstack != newEstack {
|
||||
if oldCtx.RetCount >= 0 && oldEstack.Len() != oldCtx.RetCount {
|
||||
panic(fmt.Errorf("invalid return values count: expected %d, got %d",
|
||||
oldCtx.RetCount, oldEstack.Len()))
|
||||
}
|
||||
rvcount := oldEstack.Len()
|
||||
for i := rvcount; i > 0; i-- {
|
||||
elem := oldEstack.RemoveAt(i - 1)
|
||||
|
@ -1425,19 +1436,6 @@ func (v *VM) unloadContext(ctx *Context) {
|
|||
if ctx.static != nil && currCtx != nil && ctx.static != currCtx.static {
|
||||
ctx.static.Clear()
|
||||
}
|
||||
switch ctx.CheckReturn {
|
||||
case NoCheck:
|
||||
case EnsureIsEmpty:
|
||||
if currCtx != nil && ctx.estack.len != 0 {
|
||||
panic("return value amount is > 0")
|
||||
}
|
||||
case EnsureNotEmpty:
|
||||
if currCtx != nil && ctx.estack.len == 0 {
|
||||
currCtx.estack.PushVal(stackitem.Null{})
|
||||
} else if ctx.estack.len > 1 {
|
||||
panic("return value amount is > 1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getTryParams splits TRY(L) instruction parameter into offsets for catch and finally blocks.
|
||||
|
@ -1494,7 +1492,7 @@ func (v *VM) Call(ctx *Context, offset int) {
|
|||
func (v *VM) call(ctx *Context, offset int) {
|
||||
v.checkInvocationStackSize()
|
||||
newCtx := ctx.Copy()
|
||||
newCtx.CheckReturn = NoCheck
|
||||
newCtx.RetCount = -1
|
||||
newCtx.local = nil
|
||||
newCtx.arguments = nil
|
||||
newCtx.tryStack = NewStack("exception")
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
|
@ -805,7 +805,7 @@ func TestSerializeInterop(t *testing.T) {
|
|||
require.True(t, vm.HasFailed())
|
||||
}
|
||||
|
||||
func getTestCallFlagsFunc(syscall []byte, flags smartcontract.CallFlag, result interface{}) func(t *testing.T) {
|
||||
func getTestCallFlagsFunc(syscall []byte, flags callflag.CallFlag, result interface{}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
script := append([]byte{byte(opcode.SYSCALL)}, syscall...)
|
||||
v := newTestVM()
|
||||
|
@ -823,11 +823,11 @@ func getTestCallFlagsFunc(syscall []byte, flags smartcontract.CallFlag, result i
|
|||
func TestCallFlags(t *testing.T) {
|
||||
noFlags := []byte{0x77, 0x77, 0x77, 0x77}
|
||||
readOnly := []byte{0x66, 0x66, 0x66, 0x66}
|
||||
t.Run("NoFlagsNoRequired", getTestCallFlagsFunc(noFlags, smartcontract.NoneFlag, new(int)))
|
||||
t.Run("ProvideFlagsNoRequired", getTestCallFlagsFunc(noFlags, smartcontract.AllowCall, new(int)))
|
||||
t.Run("NoFlagsSomeRequired", getTestCallFlagsFunc(readOnly, smartcontract.NoneFlag, nil))
|
||||
t.Run("OnlyOneProvided", getTestCallFlagsFunc(readOnly, smartcontract.AllowCall, nil))
|
||||
t.Run("AllFlagsProvided", getTestCallFlagsFunc(readOnly, smartcontract.ReadOnly, new(int)))
|
||||
t.Run("NoFlagsNoRequired", getTestCallFlagsFunc(noFlags, callflag.NoneFlag, new(int)))
|
||||
t.Run("ProvideFlagsNoRequired", getTestCallFlagsFunc(noFlags, callflag.AllowCall, new(int)))
|
||||
t.Run("NoFlagsSomeRequired", getTestCallFlagsFunc(readOnly, callflag.NoneFlag, nil))
|
||||
t.Run("OnlyOneProvided", getTestCallFlagsFunc(readOnly, callflag.AllowCall, nil))
|
||||
t.Run("AllFlagsProvided", getTestCallFlagsFunc(readOnly, callflag.ReadOnly, new(int)))
|
||||
}
|
||||
|
||||
func callNTimes(n uint16) []byte {
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"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"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"go.uber.org/zap"
|
||||
|
@ -95,7 +96,7 @@ func main() {
|
|||
rand.Read(value)
|
||||
|
||||
w := io.NewBufBinWriter()
|
||||
emit.AppCallWithOperationAndArgs(w.BinWriter, contractHash, "put", key, value)
|
||||
emit.AppCall(w.BinWriter, contractHash, "put", callflag.All, key, value)
|
||||
handleError("can't create transaction", w.Err)
|
||||
|
||||
tx := transaction.New(netmode.UnitTestNet, w.Bytes(), 4_000_000)
|
||||
|
|
Loading…
Reference in a new issue