mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-27 03:58:06 +00:00
Merge pull request #1544 from nspcc-dev/remove-contract-features
Remove contract features
This commit is contained in:
commit
7b1902f513
35 changed files with 58 additions and 267 deletions
|
@ -404,7 +404,6 @@ func contractCompile(ctx *cli.Context) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.ContractFeatures = conf.GetFeatures()
|
||||
o.ContractEvents = conf.Events
|
||||
o.ContractSupportedStandards = conf.SupportedStandards
|
||||
}
|
||||
|
@ -632,24 +631,10 @@ func testInvokeScript(ctx *cli.Context) error {
|
|||
|
||||
// ProjectConfig contains project metadata.
|
||||
type ProjectConfig struct {
|
||||
HasStorage bool
|
||||
IsPayable bool
|
||||
SupportedStandards []string
|
||||
Events []manifest.Event
|
||||
}
|
||||
|
||||
// GetFeatures returns smartcontract features from the config.
|
||||
func (p *ProjectConfig) GetFeatures() smartcontract.PropertyState {
|
||||
var fs smartcontract.PropertyState
|
||||
if p.IsPayable {
|
||||
fs |= smartcontract.IsPayable
|
||||
}
|
||||
if p.HasStorage {
|
||||
fs |= smartcontract.HasStorage
|
||||
}
|
||||
return fs
|
||||
}
|
||||
|
||||
func inspect(ctx *cli.Context) error {
|
||||
in := ctx.String("in")
|
||||
compile := ctx.Bool("compile")
|
||||
|
|
|
@ -58,9 +58,7 @@ func RuntimeNotify(args []interface{}) {
|
|||
manifest, err := ioutil.ReadFile(contractName + "/" + files[1].Name())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t,
|
||||
`hasstorage: false
|
||||
ispayable: false
|
||||
supportedstandards: []
|
||||
`supportedstandards: []
|
||||
events:
|
||||
- name: Hello world!
|
||||
parameters:
|
||||
|
@ -69,15 +67,6 @@ events:
|
|||
`, string(manifest))
|
||||
}
|
||||
|
||||
func TestGetFeatures(t *testing.T) {
|
||||
cfg := ProjectConfig{
|
||||
IsPayable: true,
|
||||
HasStorage: true,
|
||||
}
|
||||
f := cfg.GetFeatures()
|
||||
require.Equal(t, smartcontract.IsPayable|smartcontract.HasStorage, f)
|
||||
}
|
||||
|
||||
func TestParseCosigner(t *testing.T) {
|
||||
acc := util.Uint160{1, 3, 5, 7}
|
||||
testCases := map[string]transaction.Signer{
|
||||
|
|
1
cli/testdata/deploy/neo-go.yml
vendored
1
cli/testdata/deploy/neo-go.yml
vendored
|
@ -1 +0,0 @@
|
|||
hasstorage: true
|
2
cli/testdata/verify.manifest.json
vendored
2
cli/testdata/verify.manifest.json
vendored
|
@ -1 +1 @@
|
|||
{"abi":{"hash":"0x8dff9f223e4622961f410c015dd37052a59892bb","methods":[{"name":"verify","offset":0,"parameters":[],"returntype":"Boolean"}],"events":[]},"groups":[],"features":{"payable":true,"storage":false},"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":[],"trusts":[],"safemethods":[],"extra":null}
|
||||
{"abi":{"hash":"0x8dff9f223e4622961f410c015dd37052a59892bb","methods":[{"name":"verify","offset":0,"parameters":[],"returntype":"Boolean"}],"events":[]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":[],"trusts":[],"safemethods":[],"extra":null}
|
||||
|
|
|
@ -145,17 +145,12 @@ Deploying a contract to blockchain with neo-go requires a configuration file
|
|||
with contract's metadata in YAML format, like the following:
|
||||
|
||||
```
|
||||
project:
|
||||
author: Jack Smith
|
||||
email: jack@example.com
|
||||
version: 1.0
|
||||
name: 'Smart contract'
|
||||
description: 'Even smarter than Jack himself'
|
||||
hasstorage: true
|
||||
hasdynamicinvocation: false
|
||||
ispayable: false
|
||||
returntype: ByteArray
|
||||
parameters: ['String', 'Array']
|
||||
supportedstandards: []
|
||||
events:
|
||||
- name: info
|
||||
parameters:
|
||||
- name: message
|
||||
type: ByteString
|
||||
```
|
||||
|
||||
It's passed to the `deploy` command via `-c` option:
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
hasstorage: false
|
||||
ispayable: false
|
||||
supportedstandards: []
|
||||
events:
|
||||
- name: Tx
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
hasstorage: true
|
||||
ispayable: false
|
||||
supportedstandards: []
|
||||
events:
|
||||
- name: found storage values
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
hasstorage: false
|
||||
ispayable: false
|
||||
supportedstandards: []
|
||||
events:
|
||||
- name: Event
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
hasstorage: true
|
||||
ispayable: false
|
||||
supportedstandards: []
|
||||
events: []
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
hasstorage: true
|
||||
ispayable: false
|
||||
supportedstandards: []
|
||||
events: []
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
hasstorage: true
|
||||
ispayable: false
|
||||
supportedstandards: ["NEP-5"]
|
||||
events: []
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
hasstorage: true
|
||||
ispayable: false
|
||||
supportedstandards: ["NEP-5"]
|
||||
events:
|
||||
- name: transfer
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||
"golang.org/x/tools/go/loader"
|
||||
|
@ -35,9 +34,6 @@ type Options struct {
|
|||
// The name of the output for contract manifest file.
|
||||
ManifestFile string
|
||||
|
||||
// Contract features.
|
||||
ContractFeatures smartcontract.PropertyState
|
||||
|
||||
// Runtime notifications.
|
||||
ContractEvents []manifest.Event
|
||||
|
||||
|
@ -211,7 +207,7 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
|
|||
}
|
||||
|
||||
if o.ManifestFile != "" {
|
||||
m, err := di.ConvertToManifest(o.ContractFeatures, o.ContractEvents, o.ContractSupportedStandards...)
|
||||
m, err := di.ConvertToManifest(o.ContractEvents, o.ContractSupportedStandards...)
|
||||
if err != nil {
|
||||
return b, fmt.Errorf("failed to convert debug info to manifest: %w", err)
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ func parsePairJSON(data []byte, sep string) (string, string, error) {
|
|||
|
||||
// ConvertToManifest converts contract to the manifest.Manifest struct for debugger.
|
||||
// Note: manifest is taken from the external source, however it can be generated ad-hoc. See #1038.
|
||||
func (di *DebugInfo) ConvertToManifest(fs smartcontract.PropertyState, events []manifest.Event, supportedStandards ...string) (*manifest.Manifest, error) {
|
||||
func (di *DebugInfo) ConvertToManifest(events []manifest.Event, supportedStandards ...string) (*manifest.Manifest, error) {
|
||||
if di.MainPkg == "" {
|
||||
return nil, errors.New("no Main method was found")
|
||||
}
|
||||
|
@ -425,7 +425,6 @@ func (di *DebugInfo) ConvertToManifest(fs smartcontract.PropertyState, events []
|
|||
}
|
||||
|
||||
result := manifest.NewManifest(di.Hash)
|
||||
result.Features = fs
|
||||
if supportedStandards != nil {
|
||||
result.SupportedStandards = supportedStandards
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ func _deploy(isUpdate bool) {}
|
|||
}
|
||||
|
||||
t.Run("convert to Manifest", func(t *testing.T) {
|
||||
actual, err := d.ConvertToManifest(smartcontract.HasStorage, nil)
|
||||
actual, err := d.ConvertToManifest(nil)
|
||||
require.NoError(t, err)
|
||||
// note: offsets are hard to predict, so we just take them from the output
|
||||
expected := &manifest.Manifest{
|
||||
|
@ -244,8 +244,7 @@ func _deploy(isUpdate bool) {}
|
|||
},
|
||||
Events: []manifest.Event{},
|
||||
},
|
||||
Groups: []manifest.Group{},
|
||||
Features: smartcontract.HasStorage,
|
||||
Groups: []manifest.Group{},
|
||||
Permissions: []manifest.Permission{
|
||||
{
|
||||
Contract: manifest.PermissionDesc{
|
||||
|
@ -266,7 +265,6 @@ func _deploy(isUpdate bool) {}
|
|||
require.ElementsMatch(t, expected.ABI.Methods, actual.ABI.Methods)
|
||||
require.Equal(t, expected.ABI.Events, actual.ABI.Events)
|
||||
require.Equal(t, expected.Groups, actual.Groups)
|
||||
require.Equal(t, expected.Features, actual.Features)
|
||||
require.Equal(t, expected.Permissions, actual.Permissions)
|
||||
require.Equal(t, expected.Trusts, actual.Trusts)
|
||||
require.Equal(t, expected.SafeMethods, actual.SafeMethods)
|
||||
|
|
|
@ -101,7 +101,7 @@ func TestAppCall(t *testing.T) {
|
|||
|
||||
inner, di, err := compiler.CompileWithDebugInfo("foo.go", strings.NewReader(srcInner))
|
||||
require.NoError(t, err)
|
||||
m, err := di.ConvertToManifest(smartcontract.NoProperties, nil)
|
||||
m, err := di.ConvertToManifest(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
ih := hash.Hash160(inner)
|
||||
|
|
|
@ -377,9 +377,9 @@ func newDeployTx(t *testing.T, name string) (*transaction.Transaction, []byte) {
|
|||
t.Logf("contractScript: %x", avm)
|
||||
|
||||
script := io.NewBufBinWriter()
|
||||
m, err := di.ConvertToManifest(smartcontract.HasStorage, nil)
|
||||
m, err := di.ConvertToManifest(nil)
|
||||
require.NoError(t, err)
|
||||
bs, err := m.MarshalJSON()
|
||||
bs, err := json.Marshal(m)
|
||||
require.NoError(t, err)
|
||||
emit.Bytes(script.BinWriter, bs)
|
||||
emit.Bytes(script.BinWriter, avm)
|
||||
|
|
|
@ -3,6 +3,7 @@ package core
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
@ -75,7 +76,7 @@ func createContractStateFromVM(ic *interop.Context) (*state.Contract, error) {
|
|||
return nil, errGasLimitExceeded
|
||||
}
|
||||
var m manifest.Manifest
|
||||
err := m.UnmarshalJSON(manifestBytes)
|
||||
err := json.Unmarshal(manifestBytes, &m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to retrieve manifest from stack: %w", err)
|
||||
}
|
||||
|
@ -173,7 +174,7 @@ func contractUpdate(ic *interop.Context) error {
|
|||
// storage items if needed
|
||||
if manifestBytes != nil {
|
||||
var newManifest manifest.Manifest
|
||||
err := newManifest.UnmarshalJSON(manifestBytes)
|
||||
err := json.Unmarshal(manifestBytes, &newManifest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to retrieve manifest from stack: %w", err)
|
||||
}
|
||||
|
@ -182,15 +183,6 @@ func contractUpdate(ic *interop.Context) error {
|
|||
if !contract.Manifest.IsValid(contract.ScriptHash()) {
|
||||
return errors.New("failed to check contract script hash against new manifest")
|
||||
}
|
||||
if !contract.HasStorage() {
|
||||
siMap, err := ic.DAO.GetStorageItems(contract.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update manifest: %w", err)
|
||||
}
|
||||
if len(siMap) != 0 {
|
||||
return errors.New("old contract shouldn't have storage")
|
||||
}
|
||||
}
|
||||
if err := ic.DAO.PutContractState(contract); err != nil {
|
||||
return fmt.Errorf("failed to update manifest: %w", err)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"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/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
@ -295,7 +294,6 @@ func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop
|
|||
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
|
||||
script := []byte("testscript")
|
||||
m := manifest.NewManifest(hash.Hash160(script))
|
||||
m.Features = smartcontract.HasStorage
|
||||
contractState := &state.Contract{
|
||||
Script: script,
|
||||
Manifest: *m,
|
||||
|
|
|
@ -2,6 +2,7 @@ package core
|
|||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
@ -99,15 +100,13 @@ func bcGetBlock(ic *interop.Context) error {
|
|||
|
||||
// contractToStackItem converts state.Contract to stackitem.Item
|
||||
func contractToStackItem(cs *state.Contract) (stackitem.Item, error) {
|
||||
manifest, err := cs.Manifest.MarshalJSON()
|
||||
manifest, err := json.Marshal(cs.Manifest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return stackitem.NewArray([]stackitem.Item{
|
||||
stackitem.NewByteArray(cs.Script),
|
||||
stackitem.NewByteArray(manifest),
|
||||
stackitem.NewBool(cs.HasStorage()),
|
||||
stackitem.NewBool(cs.IsPayable()),
|
||||
}), nil
|
||||
}
|
||||
|
||||
|
@ -365,9 +364,6 @@ func storageGetContextInternal(ic *interop.Context, isReadOnly bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !contract.HasStorage() {
|
||||
return errors.New("contract is not allowed to use storage")
|
||||
}
|
||||
sc := &StorageContext{
|
||||
ID: contract.ID,
|
||||
ReadOnly: isReadOnly,
|
||||
|
@ -464,14 +460,12 @@ func contractDestroy(ic *interop.Context) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cs.HasStorage() {
|
||||
siMap, err := ic.DAO.GetStorageItems(cs.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k := range siMap {
|
||||
_ = ic.DAO.DeleteStorageItem(cs.ID, []byte(k))
|
||||
}
|
||||
siMap, err := ic.DAO.GetStorageItems(cs.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k := range siMap {
|
||||
_ = ic.DAO.DeleteStorageItem(cs.ID, []byte(k))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
@ -411,7 +412,6 @@ func getTestContractState() (*state.Contract, *state.Contract) {
|
|||
script := w.Bytes()
|
||||
h := hash.Hash160(script)
|
||||
m := manifest.NewManifest(h)
|
||||
m.Features = smartcontract.HasStorage
|
||||
m.ABI.Methods = []manifest.Method{
|
||||
{
|
||||
Name: "add",
|
||||
|
@ -638,7 +638,7 @@ func TestContractCreate(t *testing.T) {
|
|||
defer bc.Close()
|
||||
|
||||
putArgsOnStack := func() {
|
||||
manifest, err := cs.Manifest.MarshalJSON()
|
||||
manifest, err := json.Marshal(cs.Manifest)
|
||||
require.NoError(t, err)
|
||||
v.Estack().PushVal(manifest)
|
||||
v.Estack().PushVal(cs.Script)
|
||||
|
@ -672,18 +672,12 @@ func compareContractStates(t *testing.T, expected *state.Contract, actual stacki
|
|||
act, ok := actual.Value().([]stackitem.Item)
|
||||
require.True(t, ok)
|
||||
|
||||
expectedManifest, err := expected.Manifest.MarshalJSON()
|
||||
expectedManifest, err := json.Marshal(expected.Manifest)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 4, len(act))
|
||||
require.Equal(t, 2, len(act))
|
||||
require.Equal(t, expected.Script, act[0].Value().([]byte))
|
||||
require.Equal(t, expectedManifest, act[1].Value().([]byte))
|
||||
hasstorage, err := act[2].TryBool()
|
||||
require.NoError(t, err)
|
||||
ispayable, err := act[3].TryBool()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expected.HasStorage(), hasstorage)
|
||||
require.Equal(t, expected.IsPayable(), ispayable)
|
||||
}
|
||||
|
||||
func TestContractUpdate(t *testing.T) {
|
||||
|
@ -806,27 +800,7 @@ func TestContractUpdate(t *testing.T) {
|
|||
Hash: util.Uint160{4, 5, 6},
|
||||
},
|
||||
}
|
||||
manifestBytes, err := manifest.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
putArgsOnStack(stackitem.Null{}, manifestBytes)
|
||||
|
||||
require.Error(t, contractUpdate(ic))
|
||||
})
|
||||
|
||||
t.Run("update manifest, old contract shouldn't have storage", func(t *testing.T) {
|
||||
cs.Manifest.Features |= smartcontract.HasStorage
|
||||
require.NoError(t, ic.DAO.PutContractState(cs))
|
||||
require.NoError(t, ic.DAO.PutStorageItem(cs.ID, []byte("my_item"), &state.StorageItem{
|
||||
Value: []byte{1, 2, 3},
|
||||
IsConst: false,
|
||||
}))
|
||||
v.LoadScriptWithHash([]byte{byte(opcode.RET)}, cs.ScriptHash(), smartcontract.All)
|
||||
manifest := &manifest.Manifest{
|
||||
ABI: manifest.ABI{
|
||||
Hash: cs.ScriptHash(),
|
||||
},
|
||||
}
|
||||
manifestBytes, err := manifest.MarshalJSON()
|
||||
manifestBytes, err := json.Marshal(manifest)
|
||||
require.NoError(t, err)
|
||||
putArgsOnStack(stackitem.Null{}, manifestBytes)
|
||||
|
||||
|
@ -834,15 +808,13 @@ func TestContractUpdate(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("update manifest, positive", func(t *testing.T) {
|
||||
cs.Manifest.Features = smartcontract.NoProperties
|
||||
require.NoError(t, ic.DAO.PutContractState(cs))
|
||||
manifest := &manifest.Manifest{
|
||||
ABI: manifest.ABI{
|
||||
Hash: cs.ScriptHash(),
|
||||
},
|
||||
Features: smartcontract.HasStorage,
|
||||
}
|
||||
manifestBytes, err := manifest.MarshalJSON()
|
||||
manifestBytes, err := json.Marshal(manifest)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("empty script", func(t *testing.T) {
|
||||
|
@ -875,9 +847,8 @@ func TestContractUpdate(t *testing.T) {
|
|||
ABI: manifest.ABI{
|
||||
Hash: hash.Hash160(newScript),
|
||||
},
|
||||
Features: smartcontract.HasStorage,
|
||||
}
|
||||
newManifestBytes, err := newManifest.MarshalJSON()
|
||||
newManifestBytes, err := json.Marshal(newManifest)
|
||||
require.NoError(t, err)
|
||||
|
||||
putArgsOnStack(newScript, newManifestBytes)
|
||||
|
@ -910,7 +881,7 @@ func TestContractCreateDeploy(t *testing.T) {
|
|||
v.GasLimit = -1
|
||||
|
||||
putArgs := func(cs *state.Contract) {
|
||||
rawManifest, err := cs.Manifest.MarshalJSON()
|
||||
rawManifest, err := json.Marshal(cs.Manifest)
|
||||
require.NoError(t, err)
|
||||
v.Estack().PushVal(rawManifest)
|
||||
v.Estack().PushVal(cs.Script)
|
||||
|
|
|
@ -69,7 +69,6 @@ func isValidRole(r Role) bool {
|
|||
func newDesignate() *Designate {
|
||||
s := &Designate{ContractMD: *interop.NewContractMD(designateName)}
|
||||
s.ContractID = designateContractID
|
||||
s.Manifest.Features = smartcontract.HasStorage
|
||||
|
||||
desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType,
|
||||
manifest.NewParameter("role", smartcontract.IntegerType),
|
||||
|
|
|
@ -104,7 +104,6 @@ func GetOracleResponseScript() []byte {
|
|||
func newOracle() *Oracle {
|
||||
o := &Oracle{ContractMD: *interop.NewContractMD(oracleName)}
|
||||
o.ContractID = oracleContractID
|
||||
o.Manifest.Features = smartcontract.HasStorage
|
||||
|
||||
desc := newDescriptor("request", smartcontract.VoidType,
|
||||
manifest.NewParameter("url", smartcontract.StringType),
|
||||
|
|
|
@ -74,7 +74,6 @@ func newPolicy() *Policy {
|
|||
p := &Policy{ContractMD: *interop.NewContractMD(policyName)}
|
||||
|
||||
p.ContractID = policyContractID
|
||||
p.Manifest.Features |= smartcontract.HasStorage
|
||||
|
||||
desc := newDescriptor("getMaxTransactionsPerBlock", smartcontract.IntegerType)
|
||||
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, smartcontract.AllowStates)
|
||||
|
|
|
@ -50,7 +50,6 @@ func getOracleContractState(h util.Uint160) *state.Contract {
|
|||
emit.Opcodes(w.BinWriter, opcode.RET)
|
||||
|
||||
m := manifest.NewManifest(h)
|
||||
m.Features = smartcontract.HasStorage
|
||||
m.ABI.Methods = []manifest.Method{
|
||||
{
|
||||
Name: "requestURL",
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -48,16 +47,6 @@ func (cs *Contract) createHash() {
|
|||
cs.scriptHash = hash.Hash160(cs.Script)
|
||||
}
|
||||
|
||||
// HasStorage checks whether the contract has storage property set.
|
||||
func (cs *Contract) HasStorage() bool {
|
||||
return (cs.Manifest.Features & smartcontract.HasStorage) != 0
|
||||
}
|
||||
|
||||
// IsPayable checks whether the contract has payable property set.
|
||||
func (cs *Contract) IsPayable() bool {
|
||||
return (cs.Manifest.Features & smartcontract.IsPayable) != 0
|
||||
}
|
||||
|
||||
type contractJSON struct {
|
||||
ID int32 `json:"id"`
|
||||
Script []byte `json:"script"`
|
||||
|
|
|
@ -29,7 +29,6 @@ func TestEncodeDecodeContractState(t *testing.T) {
|
|||
},
|
||||
ReturnType: smartcontract.BoolType,
|
||||
}}
|
||||
m.Features = smartcontract.HasStorage
|
||||
contract := &Contract{
|
||||
ID: 123,
|
||||
Script: script,
|
||||
|
|
|
@ -10,10 +10,8 @@ import "github.com/nspcc-dev/neo-go/pkg/interop"
|
|||
// this package. It's similar in function to the Contract class in the Neo .net
|
||||
// framework.
|
||||
type Contract struct {
|
||||
Script []byte
|
||||
Manifest []byte
|
||||
HasStorage bool
|
||||
IsPayable bool
|
||||
Script []byte
|
||||
Manifest []byte
|
||||
}
|
||||
|
||||
// Create creates a new contract using a set of input parameters:
|
||||
|
|
|
@ -327,14 +327,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
}
|
||||
return c.GetContractStateByHash(hash)
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"abi":{"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","methods":[],"events":[]},"groups":[],"features":{"payable":false,"storage":true},"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"abi":{"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := manifest.NewManifest(hash.Hash160(script))
|
||||
m.Features = smartcontract.HasStorage
|
||||
cs := &state.Contract{
|
||||
ID: 0,
|
||||
Script: script,
|
||||
|
@ -349,14 +348,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetContractStateByAddressOrName("NWiu5oejTu925aeL9Hc1LX8SvaJhE23h15")
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"abi":{"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","methods":[],"events":[]},"groups":[],"features":{"payable":false,"storage":true},"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"abi":{"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := manifest.NewManifest(hash.Hash160(script))
|
||||
m.Features = smartcontract.HasStorage
|
||||
cs := &state.Contract{
|
||||
ID: 0,
|
||||
Script: script,
|
||||
|
@ -371,14 +369,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetContractStateByID(0)
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"abi":{"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","methods":[],"events":[]},"groups":[],"features":{"payable":false,"storage":true},"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"id":0,"script":"VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==","manifest":{"abi":{"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","methods":[],"events":[]},"groups":[],"permissions":null,"trusts":[],"supportedstandards":[],"safemethods":[],"extra":null},"hash":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := manifest.NewManifest(hash.Hash160(script))
|
||||
m.Features = smartcontract.HasStorage
|
||||
cs := &state.Contract{
|
||||
ID: 0,
|
||||
Script: script,
|
||||
|
@ -1466,9 +1463,9 @@ func wrapInitResponse(r *request.In, resp string) string {
|
|||
}
|
||||
switch name {
|
||||
case "neo":
|
||||
response = `{"id":1,"jsonrpc":"2.0","result":{"id":-1,"script":"DANORU9Ba2d4Cw==","manifest":{"abi":{"hash":"0xde5f57d430d3dece511cf975a8d37848cb9e0525","methods":[{"name":"name","offset":0,"parameters":null,"returntype":"String"},{"name":"symbol","offset":0,"parameters":null,"returntype":"String"},{"name":"decimals","offset":0,"parameters":null,"returntype":"Integer"},{"name":"totalSupply","offset":0,"parameters":null,"returntype":"Integer"},{"name":"balanceOf","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer"},{"name":"transfer","offset":0,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Boolean"},{"name":"onPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"postPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"unclaimedGas","offset":0,"parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer"},{"name":"registerCandidate","offset":0,"parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"unregisterCandidate","offset":0,"parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"vote","offset":0,"parameters":[{"name":"account","type":"Hash160"},{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"getCandidates","offset":0,"parameters":null,"returntype":"Array"},{"name":"getСommittee","offset":0,"parameters":null,"returntype":"Array"},{"name":"getNextBlockValidators","offset":0,"parameters":null,"returntype":"Array"},{"name":"getGasPerBlock","offset":0,"parameters":null,"returntype":"Integer"},{"name":"setGasPerBlock","offset":0,"parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Boolean"}],"events":[{"name":"Transfer","parameters":null}]},"groups":[],"features":{"payable":false,"storage":false},"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":["NEP-5"],"trusts":[],"safemethods":["name","symbol","decimals","totalSupply","balanceOf","unclaimedGas","getCandidates","getСommittee","getNextBlockValidators"],"extra":null},"hash":"0xde5f57d430d3dece511cf975a8d37848cb9e0525"}}`
|
||||
response = `{"id":1,"jsonrpc":"2.0","result":{"id":-1,"script":"DANORU9Ba2d4Cw==","manifest":{"abi":{"hash":"0xde5f57d430d3dece511cf975a8d37848cb9e0525","methods":[{"name":"name","offset":0,"parameters":null,"returntype":"String"},{"name":"symbol","offset":0,"parameters":null,"returntype":"String"},{"name":"decimals","offset":0,"parameters":null,"returntype":"Integer"},{"name":"totalSupply","offset":0,"parameters":null,"returntype":"Integer"},{"name":"balanceOf","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer"},{"name":"transfer","offset":0,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Boolean"},{"name":"onPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"postPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"unclaimedGas","offset":0,"parameters":[{"name":"account","type":"Hash160"},{"name":"end","type":"Integer"}],"returntype":"Integer"},{"name":"registerCandidate","offset":0,"parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"unregisterCandidate","offset":0,"parameters":[{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"vote","offset":0,"parameters":[{"name":"account","type":"Hash160"},{"name":"pubkey","type":"PublicKey"}],"returntype":"Boolean"},{"name":"getCandidates","offset":0,"parameters":null,"returntype":"Array"},{"name":"getСommittee","offset":0,"parameters":null,"returntype":"Array"},{"name":"getNextBlockValidators","offset":0,"parameters":null,"returntype":"Array"},{"name":"getGasPerBlock","offset":0,"parameters":null,"returntype":"Integer"},{"name":"setGasPerBlock","offset":0,"parameters":[{"name":"gasPerBlock","type":"Integer"}],"returntype":"Boolean"}],"events":[{"name":"Transfer","parameters":null}]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":["NEP-5"],"trusts":[],"safemethods":["name","symbol","decimals","totalSupply","balanceOf","unclaimedGas","getCandidates","getСommittee","getNextBlockValidators"],"extra":null},"hash":"0xde5f57d430d3dece511cf975a8d37848cb9e0525"}}`
|
||||
case "gas":
|
||||
response = `{"id":1,"jsonrpc":"2.0","result":{"id":-2,"script":"DANHQVNBa2d4Cw==","manifest":{"abi":{"hash":"0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","methods":[{"name":"name","offset":0,"parameters":null,"returntype":"String"},{"name":"symbol","offset":0,"parameters":null,"returntype":"String"},{"name":"decimals","offset":0,"parameters":null,"returntype":"Integer"},{"name":"totalSupply","offset":0,"parameters":null,"returntype":"Integer"},{"name":"balanceOf","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer"},{"name":"transfer","offset":0,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Boolean"},{"name":"onPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"postPersist","offset":0,"parameters":null,"returntype":"Void"}],"events":[{"name":"Transfer","parameters":null}]},"groups":[],"features":{"payable":false,"storage":false},"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":["NEP-5"],"trusts":[],"safemethods":["name","symbol","decimals","totalSupply","balanceOf"],"extra":null},"hash":"0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"}}`
|
||||
response = `{"id":1,"jsonrpc":"2.0","result":{"id":-2,"script":"DANHQVNBa2d4Cw==","manifest":{"abi":{"hash":"0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","methods":[{"name":"name","offset":0,"parameters":null,"returntype":"String"},{"name":"symbol","offset":0,"parameters":null,"returntype":"String"},{"name":"decimals","offset":0,"parameters":null,"returntype":"Integer"},{"name":"totalSupply","offset":0,"parameters":null,"returntype":"Integer"},{"name":"balanceOf","offset":0,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer"},{"name":"transfer","offset":0,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Boolean"},{"name":"onPersist","offset":0,"parameters":null,"returntype":"Void"},{"name":"postPersist","offset":0,"parameters":null,"returntype":"Void"}],"events":[{"name":"Transfer","parameters":null}]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":["NEP-5"],"trusts":[],"safemethods":["name","symbol","decimals","totalSupply","balanceOf"],"extra":null},"hash":"0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"}}`
|
||||
default:
|
||||
response = resp
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
@ -19,7 +20,7 @@ import (
|
|||
// with its metadata.
|
||||
func CreateDeploymentScript(avm []byte, manif *manifest.Manifest) ([]byte, error) {
|
||||
script := io.NewBufBinWriter()
|
||||
rawManifest, err := manif.MarshalJSON()
|
||||
rawManifest, err := json.Marshal(manif)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package smartcontract
|
||||
|
||||
// ContractDetails contains contract metadata.
|
||||
type ContractDetails struct {
|
||||
Author string
|
||||
Email string
|
||||
Version string
|
||||
ProjectName string `yaml:"name"`
|
||||
Description string
|
||||
HasStorage bool
|
||||
HasDynamicInvocation bool
|
||||
IsPayable bool
|
||||
ReturnType ParamType
|
||||
Parameters []ParamType
|
||||
}
|
|
@ -66,7 +66,7 @@ func (c *WildStrings) Add(v string) { c.Value = append(c.Value, v) }
|
|||
func (c *WildUint160s) Add(v util.Uint160) { c.Value = append(c.Value, v) }
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (c *WildStrings) MarshalJSON() ([]byte, error) {
|
||||
func (c WildStrings) MarshalJSON() ([]byte, error) {
|
||||
if c.IsWildcard() {
|
||||
return []byte(`"*"`), nil
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func (c *WildStrings) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (c *WildUint160s) MarshalJSON() ([]byte, error) {
|
||||
func (c WildUint160s) MarshalJSON() ([]byte, error) {
|
||||
if c.IsWildcard() {
|
||||
return []byte(`"*"`), nil
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
|
@ -37,31 +36,18 @@ type ABI struct {
|
|||
// Manifest represens contract metadata.
|
||||
type Manifest struct {
|
||||
// ABI is a contract's ABI.
|
||||
ABI ABI
|
||||
ABI ABI `json:"abi"`
|
||||
// Groups is a set of groups to which a contract belongs.
|
||||
Groups []Group
|
||||
// Features is a set of contract's features.
|
||||
Features smartcontract.PropertyState
|
||||
Permissions []Permission
|
||||
Groups []Group `json:"groups"`
|
||||
Permissions []Permission `json:"permissions"`
|
||||
// SupportedStandards is a list of standards supported by the contract.
|
||||
SupportedStandards []string
|
||||
SupportedStandards []string `json:"supportedstandards"`
|
||||
// Trusts is a set of hashes to a which contract trusts.
|
||||
Trusts WildUint160s
|
||||
Trusts WildUint160s `json:"trusts"`
|
||||
// SafeMethods is a set of names of safe methods.
|
||||
SafeMethods WildStrings
|
||||
SafeMethods WildStrings `json:"safemethods"`
|
||||
// Extra is an implementation-defined user data.
|
||||
Extra interface{}
|
||||
}
|
||||
|
||||
type manifestAux struct {
|
||||
ABI *ABI `json:"abi"`
|
||||
Groups []Group `json:"groups"`
|
||||
Features map[string]bool `json:"features"`
|
||||
Permissions []Permission `json:"permissions"`
|
||||
SupportedStandards []string `json:"supportedstandards"`
|
||||
Trusts *WildUint160s `json:"trusts"`
|
||||
SafeMethods *WildStrings `json:"safemethods"`
|
||||
Extra interface{} `json:"extra"`
|
||||
Extra interface{} `json:"extra"`
|
||||
}
|
||||
|
||||
// NewManifest returns new manifest with necessary fields initialized.
|
||||
|
@ -73,7 +59,6 @@ func NewManifest(h util.Uint160) *Manifest {
|
|||
Events: []Event{},
|
||||
},
|
||||
Groups: []Group{},
|
||||
Features: smartcontract.NoProperties,
|
||||
SupportedStandards: []string{},
|
||||
}
|
||||
m.Trusts.Restrict()
|
||||
|
@ -127,51 +112,6 @@ func (m *Manifest) IsValid(hash util.Uint160) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (m *Manifest) MarshalJSON() ([]byte, error) {
|
||||
features := make(map[string]bool)
|
||||
features["storage"] = m.Features&smartcontract.HasStorage != 0
|
||||
features["payable"] = m.Features&smartcontract.IsPayable != 0
|
||||
aux := &manifestAux{
|
||||
ABI: &m.ABI,
|
||||
Groups: m.Groups,
|
||||
Features: features,
|
||||
Permissions: m.Permissions,
|
||||
SupportedStandards: m.SupportedStandards,
|
||||
Trusts: &m.Trusts,
|
||||
SafeMethods: &m.SafeMethods,
|
||||
Extra: m.Extra,
|
||||
}
|
||||
return json.Marshal(aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface.
|
||||
func (m *Manifest) UnmarshalJSON(data []byte) error {
|
||||
aux := &manifestAux{
|
||||
ABI: &m.ABI,
|
||||
Trusts: &m.Trusts,
|
||||
SafeMethods: &m.SafeMethods,
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, aux); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if aux.Features["storage"] {
|
||||
m.Features |= smartcontract.HasStorage
|
||||
}
|
||||
if aux.Features["payable"] {
|
||||
m.Features |= smartcontract.IsPayable
|
||||
}
|
||||
|
||||
m.Groups = aux.Groups
|
||||
m.Permissions = aux.Permissions
|
||||
m.SupportedStandards = aux.SupportedStandards
|
||||
m.Extra = aux.Extra
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeBinary implements io.Serializable.
|
||||
func (m *Manifest) EncodeBinary(w *io.BinWriter) {
|
||||
data, err := json.Marshal(m)
|
||||
|
|
|
@ -13,39 +13,33 @@ import (
|
|||
// https://github.com/neo-project/neo/blob/master/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs#L10
|
||||
func TestManifest_MarshalJSON(t *testing.T) {
|
||||
t.Run("default", func(t *testing.T) {
|
||||
s := `{"groups":[],"features":{"storage":false,"payable":false},"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
s := `{"groups":[],"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
m := testUnmarshalMarshalManifest(t, s)
|
||||
require.Equal(t, DefaultManifest(util.Uint160{}), m)
|
||||
})
|
||||
|
||||
// this vector is missing from original repo
|
||||
t.Run("features", func(t *testing.T) {
|
||||
s := `{"groups":[],"features":{"storage":true,"payable":true},"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
testUnmarshalMarshalManifest(t, s)
|
||||
})
|
||||
|
||||
t.Run("permissions", func(t *testing.T) {
|
||||
s := `{"groups":[],"features":{"storage":false,"payable":false},"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"0x0000000000000000000000000000000000000000","methods":["method1","method2"]}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
s := `{"groups":[],"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"0x0000000000000000000000000000000000000000","methods":["method1","method2"]}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
testUnmarshalMarshalManifest(t, s)
|
||||
})
|
||||
|
||||
t.Run("safe methods", func(t *testing.T) {
|
||||
s := `{"groups":[],"features":{"storage":false,"payable":false},"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":["balanceOf"],"extra":null}`
|
||||
s := `{"groups":[],"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":["balanceOf"],"extra":null}`
|
||||
testUnmarshalMarshalManifest(t, s)
|
||||
})
|
||||
|
||||
t.Run("trust", func(t *testing.T) {
|
||||
s := `{"groups":[],"features":{"storage":false,"payable":false},"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":["0x0000000000000000000000000000000000000001"],"safemethods":[],"extra":null}`
|
||||
s := `{"groups":[],"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":["0x0000000000000000000000000000000000000001"],"safemethods":[],"extra":null}`
|
||||
testUnmarshalMarshalManifest(t, s)
|
||||
})
|
||||
|
||||
t.Run("groups", func(t *testing.T) {
|
||||
s := `{"groups":[{"pubkey":"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c","signature":"QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ=="}],"supportedstandards":[],"features":{"storage":false,"payable":false},"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
s := `{"groups":[{"pubkey":"03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c","signature":"QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ=="}],"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":null}`
|
||||
testUnmarshalMarshalManifest(t, s)
|
||||
})
|
||||
|
||||
t.Run("extra", func(t *testing.T) {
|
||||
s := `{"groups":[],"features":{"storage":false,"payable":false},"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":{"key":"value"}}`
|
||||
s := `{"groups":[],"supportedstandards":[],"abi":{"hash":"0x0000000000000000000000000000000000000000","methods":[],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"safemethods":[],"extra":{"key":"value"}}`
|
||||
testUnmarshalMarshalManifest(t, s)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,16 +17,6 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// PropertyState represents contract properties (flags).
|
||||
type PropertyState byte
|
||||
|
||||
// List of supported properties.
|
||||
const (
|
||||
HasStorage PropertyState = 1 << iota
|
||||
IsPayable PropertyState = 1 << 2
|
||||
NoProperties = 0
|
||||
)
|
||||
|
||||
// Parameter represents a smart contract parameter.
|
||||
type Parameter struct {
|
||||
// Type of the parameter.
|
||||
|
|
Loading…
Reference in a new issue