core: update *.Contract.* interops
1. Remove GetScript, IsPayable, GetStorageContext.
2. Revert 82319538
related to GetStorageContext.
3. Rename Migrate to Update.
4. Move remaining to System.Contract.*.
Related #1031.
This commit is contained in:
parent
c69f8a2fa3
commit
f8a11f61b6
12 changed files with 18 additions and 119 deletions
|
@ -37,12 +37,9 @@ var syscalls = map[string]map[string]string{
|
|||
"GetTransactionHeight": "System.Blockchain.GetTransactionHeight",
|
||||
},
|
||||
"contract": {
|
||||
"GetScript": "Neo.Contract.GetScript",
|
||||
"IsPayable": "Neo.Contract.IsPayable",
|
||||
"Create": "Neo.Contract.Create",
|
||||
"Destroy": "Neo.Contract.Destroy",
|
||||
"Migrate": "Neo.Contract.Migrate",
|
||||
"GetStorageContext": "Neo.Contract.GetStorageContext",
|
||||
"Create": "System.Contract.Create",
|
||||
"Destroy": "System.Contract.Destroy",
|
||||
"Update": "System.Contract.Update",
|
||||
},
|
||||
"engine": {
|
||||
"GetScriptContainer": "System.ExecutionEngine.GetScriptContainer",
|
||||
|
|
|
@ -236,7 +236,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
emit.Bytes(script.BinWriter, bs)
|
||||
emit.Bytes(script.BinWriter, avm)
|
||||
emit.Syscall(script.BinWriter, "Neo.Contract.Create")
|
||||
emit.Syscall(script.BinWriter, "System.Contract.Create")
|
||||
txScript := script.Bytes()
|
||||
|
||||
invFee := util.Fixed8FromFloat(100)
|
||||
|
|
|
@ -28,7 +28,6 @@ type Context struct {
|
|||
Block *block.Block
|
||||
Tx *transaction.Transaction
|
||||
DAO *dao.Cached
|
||||
LowerDAO dao.DAO
|
||||
Notifications []state.NotificationEvent
|
||||
Log *zap.Logger
|
||||
}
|
||||
|
@ -44,7 +43,6 @@ func NewContext(trigger trigger.Type, bc blockchainer.Blockchainer, d dao.DAO, n
|
|||
Block: block,
|
||||
Tx: tx,
|
||||
DAO: dao,
|
||||
LowerDAO: d,
|
||||
Notifications: nes,
|
||||
Log: log,
|
||||
}
|
||||
|
|
|
@ -114,30 +114,8 @@ func contractCreate(ic *interop.Context, v *vm.VM) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// contractGetScript returns a script associated with a contract.
|
||||
func contractGetScript(ic *interop.Context, v *vm.VM) error {
|
||||
csInterface := v.Estack().Pop().Value()
|
||||
cs, ok := csInterface.(*state.Contract)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T is not a contract state", cs)
|
||||
}
|
||||
v.Estack().PushVal(cs.Script)
|
||||
return nil
|
||||
}
|
||||
|
||||
// contractIsPayable returns whether contract is payable.
|
||||
func contractIsPayable(ic *interop.Context, v *vm.VM) error {
|
||||
csInterface := v.Estack().Pop().Value()
|
||||
cs, ok := csInterface.(*state.Contract)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T is not a contract state", cs)
|
||||
}
|
||||
v.Estack().PushVal(cs.IsPayable())
|
||||
return nil
|
||||
}
|
||||
|
||||
// contractMigrate migrates a contract.
|
||||
func contractMigrate(ic *interop.Context, v *vm.VM) error {
|
||||
// contractUpdate migrates a contract.
|
||||
func contractUpdate(ic *interop.Context, v *vm.VM) error {
|
||||
contract, err := ic.DAO.GetContractState(v.GetCurrentScriptHash())
|
||||
if contract == nil {
|
||||
return errors.New("contract doesn't exist")
|
||||
|
|
|
@ -212,28 +212,6 @@ func TestECDSAVerify(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestContractGetScript(t *testing.T) {
|
||||
v, contractState, context, chain := createVMAndContractState(t)
|
||||
defer chain.Close()
|
||||
v.Estack().PushVal(stackitem.NewInterop(contractState))
|
||||
|
||||
err := contractGetScript(context, v)
|
||||
require.NoError(t, err)
|
||||
script := v.Estack().Pop().Value()
|
||||
require.Equal(t, contractState.Script, script)
|
||||
}
|
||||
|
||||
func TestContractIsPayable(t *testing.T) {
|
||||
v, contractState, context, chain := createVMAndContractState(t)
|
||||
defer chain.Close()
|
||||
v.Estack().PushVal(stackitem.NewInterop(contractState))
|
||||
|
||||
err := contractIsPayable(context, v)
|
||||
require.NoError(t, err)
|
||||
isPayable := v.Estack().Pop().Value()
|
||||
require.Equal(t, contractState.IsPayable(), isPayable)
|
||||
}
|
||||
|
||||
// Helper functions to create VM, InteropContext, TX, Account, Contract.
|
||||
|
||||
func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
|
||||
|
|
|
@ -529,25 +529,3 @@ func contractDestroy(ic *interop.Context, v *vm.VM) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// contractGetStorageContext retrieves StorageContext of a contract.
|
||||
func contractGetStorageContext(ic *interop.Context, v *vm.VM) error {
|
||||
csInterface := v.Estack().Pop().Value()
|
||||
cs, ok := csInterface.(*state.Contract)
|
||||
if !ok {
|
||||
return fmt.Errorf("%T is not a contract state", cs)
|
||||
}
|
||||
_, err := ic.DAO.GetContractState(cs.ScriptHash())
|
||||
if err != nil {
|
||||
return fmt.Errorf("non-existent contract")
|
||||
}
|
||||
_, err = ic.LowerDAO.GetContractState(cs.ScriptHash())
|
||||
if err == nil {
|
||||
return fmt.Errorf("contract was not created in this transaction")
|
||||
}
|
||||
stc := &StorageContext{
|
||||
ScriptHash: cs.ScriptHash(),
|
||||
}
|
||||
v.Estack().PushVal(stackitem.NewInterop(stc))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -70,8 +70,9 @@ var systemInterops = []interop.Function{
|
|||
{Name: "System.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 100},
|
||||
{Name: "System.Contract.Call", Func: contractCall, Price: 1},
|
||||
{Name: "System.Contract.CallEx", Func: contractCallEx, Price: 1},
|
||||
{Name: "System.Contract.Create", Func: contractCreate, Price: 0},
|
||||
{Name: "System.Contract.Destroy", Func: contractDestroy, Price: 1},
|
||||
{Name: "System.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
|
||||
{Name: "System.Contract.Update", Func: contractUpdate, Price: 0},
|
||||
{Name: "System.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
|
||||
{Name: "System.Enumerator.Create", Func: enumerator.Create, Price: 1},
|
||||
{Name: "System.Enumerator.Next", Func: enumerator.Next, Price: 1},
|
||||
|
@ -104,12 +105,6 @@ var systemInterops = []interop.Function{
|
|||
}
|
||||
|
||||
var neoInterops = []interop.Function{
|
||||
{Name: "Neo.Contract.Create", Func: contractCreate, Price: 0},
|
||||
{Name: "Neo.Contract.Destroy", Func: contractDestroy, Price: 1},
|
||||
{Name: "Neo.Contract.GetScript", Func: contractGetScript, Price: 1},
|
||||
{Name: "Neo.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
|
||||
{Name: "Neo.Contract.IsPayable", Func: contractIsPayable, Price: 1},
|
||||
{Name: "Neo.Contract.Migrate", Func: contractMigrate, Price: 0},
|
||||
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: 1},
|
||||
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 1},
|
||||
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1},
|
||||
|
|
|
@ -32,9 +32,6 @@ func TestUnexpectedNonInterops(t *testing.T) {
|
|||
|
||||
// All of these functions expect an interop item on the stack.
|
||||
funcs := []func(*interop.Context, *vm.VM) error{
|
||||
contractGetScript,
|
||||
contractGetStorageContext,
|
||||
contractIsPayable,
|
||||
storageContextAsReadOnly,
|
||||
storageDelete,
|
||||
storageFind,
|
||||
|
|
|
@ -3,54 +3,32 @@ Package contract provides functions to work with contracts.
|
|||
*/
|
||||
package contract
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
||||
|
||||
// Contract represents a Neo contract and is used in interop functions. It's
|
||||
// an opaque data structure that you can manipulate with using functions from
|
||||
// this package. It's similar in function to the Contract class in the Neo .net
|
||||
// framework.
|
||||
type Contract struct{}
|
||||
|
||||
// GetScript returns the script of the given contract. It uses
|
||||
// `Neo.Contract.GetScript` syscall.
|
||||
func GetScript(c Contract) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsPayable returns whether the given contract is payable (able to accept
|
||||
// asset transfers to its address). It uses `Neo.Contract.IsPayable` syscall.
|
||||
func IsPayable(c Contract) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetStorageContext returns storage context for the given contract. It only
|
||||
// works for contracts created in this transaction (so you can't take a storage
|
||||
// context for arbitrary contract). Refer to the `storage` package on how to
|
||||
// use this context. This function uses `Neo.Contract.GetStorageContext` syscall.
|
||||
func GetStorageContext(c Contract) storage.Context {
|
||||
return storage.Context{}
|
||||
}
|
||||
|
||||
// Create creates a new contract using a set of input parameters:
|
||||
// script contract's bytecode (limited in length by 1M)
|
||||
// manifest contract's manifest (limited in length by 2 KiB)
|
||||
// It returns this new created Contract when successful (and fails transaction
|
||||
// if not). It uses `Neo.Contract.Create` syscall.
|
||||
// if not). It uses `System.Contract.Create` syscall.
|
||||
func Create(script []byte, manifest []byte) Contract {
|
||||
return Contract{}
|
||||
}
|
||||
|
||||
// Migrate migrates calling contract (that is the one that calls Migrate) to
|
||||
// the new contract. Its parameters have exactly the same semantics as for
|
||||
// Update updates script and manifest of the calling contract (that is the one that calls Update)
|
||||
// to the new ones. Its parameters have exactly the same semantics as for
|
||||
// Create. The old contract will be deleted by this call, if it has any storage
|
||||
// associated it will be migrated to the new contract. New contract is returned.
|
||||
// This function uses `Neo.Contract.Migrate` syscall.
|
||||
func Migrate(script []byte, manifest []byte) Contract {
|
||||
// This function uses `System.Contract.Update` syscall.
|
||||
func Update(script []byte, manifest []byte) Contract {
|
||||
return Contract{}
|
||||
}
|
||||
|
||||
// Destroy deletes calling contract (the one that calls Destroy) from the
|
||||
// blockchain, so it's only possible to do that from the contract itself and
|
||||
// not by any outside code. When contract is deleted all associated storage
|
||||
// items are deleted too. This function uses `Neo.Contract.Destroy` syscall.
|
||||
// items are deleted too. This function uses `System.Contract.Destroy` syscall.
|
||||
func Destroy() {}
|
||||
|
|
|
@ -24,7 +24,7 @@ func CreateDeploymentScript(avm []byte, manif *manifest.Manifest) ([]byte, util.
|
|||
rawManifest := w.Bytes()
|
||||
emit.Bytes(script.BinWriter, rawManifest)
|
||||
emit.Bytes(script.BinWriter, avm)
|
||||
emit.Syscall(script.BinWriter, "Neo.Contract.Create")
|
||||
emit.Syscall(script.BinWriter, "System.Contract.Create")
|
||||
sysfee := util.Fixed8(core.StoragePrice * (len(avm) + len(rawManifest)))
|
||||
return script.Bytes(), sysfee, nil
|
||||
}
|
||||
|
|
|
@ -56,12 +56,12 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"getapplicationlog": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["9d84eee99b8fda7cba4931ae54b316c1c0468bd4526b8b4eb6cf62d771abe9c7"]`,
|
||||
params: `["136ef2ba8259d121a173da2588ae0fbb735f0f740820fded9cd8da8fee109b20"]`,
|
||||
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.ApplicationLog)
|
||||
require.True(t, ok)
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("9d84eee99b8fda7cba4931ae54b316c1c0468bd4526b8b4eb6cf62d771abe9c7")
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("136ef2ba8259d121a173da2588ae0fbb735f0f740820fded9cd8da8fee109b20")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, 1, len(res.Executions))
|
||||
|
@ -483,7 +483,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"gettransactionheight": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["9d84eee99b8fda7cba4931ae54b316c1c0468bd4526b8b4eb6cf62d771abe9c7"]`,
|
||||
params: `["136ef2ba8259d121a173da2588ae0fbb735f0f740820fded9cd8da8fee109b20"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
h := 0
|
||||
return &h
|
||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
Loading…
Reference in a new issue