smartcontract: remove contract features
We're featureless now, all contracts have access to storage and payable status is to be determined via new NEP. Follow neo-project/neo#2060.
This commit is contained in:
parent
112fa5b92d
commit
286d9185f4
32 changed files with 36 additions and 187 deletions
|
@ -404,7 +404,6 @@ func contractCompile(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.ContractFeatures = conf.GetFeatures()
|
|
||||||
o.ContractEvents = conf.Events
|
o.ContractEvents = conf.Events
|
||||||
o.ContractSupportedStandards = conf.SupportedStandards
|
o.ContractSupportedStandards = conf.SupportedStandards
|
||||||
}
|
}
|
||||||
|
@ -632,24 +631,10 @@ func testInvokeScript(ctx *cli.Context) error {
|
||||||
|
|
||||||
// ProjectConfig contains project metadata.
|
// ProjectConfig contains project metadata.
|
||||||
type ProjectConfig struct {
|
type ProjectConfig struct {
|
||||||
HasStorage bool
|
|
||||||
IsPayable bool
|
|
||||||
SupportedStandards []string
|
SupportedStandards []string
|
||||||
Events []manifest.Event
|
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 {
|
func inspect(ctx *cli.Context) error {
|
||||||
in := ctx.String("in")
|
in := ctx.String("in")
|
||||||
compile := ctx.Bool("compile")
|
compile := ctx.Bool("compile")
|
||||||
|
|
|
@ -58,9 +58,7 @@ func RuntimeNotify(args []interface{}) {
|
||||||
manifest, err := ioutil.ReadFile(contractName + "/" + files[1].Name())
|
manifest, err := ioutil.ReadFile(contractName + "/" + files[1].Name())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
`hasstorage: false
|
`supportedstandards: []
|
||||||
ispayable: false
|
|
||||||
supportedstandards: []
|
|
||||||
events:
|
events:
|
||||||
- name: Hello world!
|
- name: Hello world!
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -69,15 +67,6 @@ events:
|
||||||
`, string(manifest))
|
`, 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) {
|
func TestParseCosigner(t *testing.T) {
|
||||||
acc := util.Uint160{1, 3, 5, 7}
|
acc := util.Uint160{1, 3, 5, 7}
|
||||||
testCases := map[string]transaction.Signer{
|
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}
|
||||||
|
|
|
@ -151,9 +151,7 @@ project:
|
||||||
version: 1.0
|
version: 1.0
|
||||||
name: 'Smart contract'
|
name: 'Smart contract'
|
||||||
description: 'Even smarter than Jack himself'
|
description: 'Even smarter than Jack himself'
|
||||||
hasstorage: true
|
|
||||||
hasdynamicinvocation: false
|
hasdynamicinvocation: false
|
||||||
ispayable: false
|
|
||||||
returntype: ByteArray
|
returntype: ByteArray
|
||||||
parameters: ['String', 'Array']
|
parameters: ['String', 'Array']
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
hasstorage: false
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: []
|
supportedstandards: []
|
||||||
events:
|
events:
|
||||||
- name: Tx
|
- name: Tx
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
hasstorage: true
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: []
|
supportedstandards: []
|
||||||
events:
|
events:
|
||||||
- name: found storage values
|
- name: found storage values
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
hasstorage: false
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: []
|
supportedstandards: []
|
||||||
events:
|
events:
|
||||||
- name: Event
|
- name: Event
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
hasstorage: true
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: []
|
supportedstandards: []
|
||||||
events: []
|
events: []
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
hasstorage: true
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: []
|
supportedstandards: []
|
||||||
events: []
|
events: []
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
hasstorage: true
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: ["NEP-5"]
|
supportedstandards: ["NEP-5"]
|
||||||
events: []
|
events: []
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
hasstorage: true
|
|
||||||
ispayable: false
|
|
||||||
supportedstandards: ["NEP-5"]
|
supportedstandards: ["NEP-5"]
|
||||||
events:
|
events:
|
||||||
- name: transfer
|
- name: transfer
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"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/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
|
@ -35,9 +34,6 @@ type Options struct {
|
||||||
// The name of the output for contract manifest file.
|
// The name of the output for contract manifest file.
|
||||||
ManifestFile string
|
ManifestFile string
|
||||||
|
|
||||||
// Contract features.
|
|
||||||
ContractFeatures smartcontract.PropertyState
|
|
||||||
|
|
||||||
// Runtime notifications.
|
// Runtime notifications.
|
||||||
ContractEvents []manifest.Event
|
ContractEvents []manifest.Event
|
||||||
|
|
||||||
|
@ -211,7 +207,7 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.ManifestFile != "" {
|
if o.ManifestFile != "" {
|
||||||
m, err := di.ConvertToManifest(o.ContractFeatures, o.ContractEvents, o.ContractSupportedStandards...)
|
m, err := di.ConvertToManifest(o.ContractEvents, o.ContractSupportedStandards...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return b, fmt.Errorf("failed to convert debug info to manifest: %w", err)
|
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.
|
// 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.
|
// 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 == "" {
|
if di.MainPkg == "" {
|
||||||
return nil, errors.New("no Main method was found")
|
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 := manifest.NewManifest(di.Hash)
|
||||||
result.Features = fs
|
|
||||||
if supportedStandards != nil {
|
if supportedStandards != nil {
|
||||||
result.SupportedStandards = supportedStandards
|
result.SupportedStandards = supportedStandards
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ func _deploy(isUpdate bool) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("convert to Manifest", func(t *testing.T) {
|
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)
|
require.NoError(t, err)
|
||||||
// note: offsets are hard to predict, so we just take them from the output
|
// note: offsets are hard to predict, so we just take them from the output
|
||||||
expected := &manifest.Manifest{
|
expected := &manifest.Manifest{
|
||||||
|
@ -244,8 +244,7 @@ func _deploy(isUpdate bool) {}
|
||||||
},
|
},
|
||||||
Events: []manifest.Event{},
|
Events: []manifest.Event{},
|
||||||
},
|
},
|
||||||
Groups: []manifest.Group{},
|
Groups: []manifest.Group{},
|
||||||
Features: smartcontract.HasStorage,
|
|
||||||
Permissions: []manifest.Permission{
|
Permissions: []manifest.Permission{
|
||||||
{
|
{
|
||||||
Contract: manifest.PermissionDesc{
|
Contract: manifest.PermissionDesc{
|
||||||
|
@ -266,7 +265,6 @@ func _deploy(isUpdate bool) {}
|
||||||
require.ElementsMatch(t, expected.ABI.Methods, actual.ABI.Methods)
|
require.ElementsMatch(t, expected.ABI.Methods, actual.ABI.Methods)
|
||||||
require.Equal(t, expected.ABI.Events, actual.ABI.Events)
|
require.Equal(t, expected.ABI.Events, actual.ABI.Events)
|
||||||
require.Equal(t, expected.Groups, actual.Groups)
|
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.Permissions, actual.Permissions)
|
||||||
require.Equal(t, expected.Trusts, actual.Trusts)
|
require.Equal(t, expected.Trusts, actual.Trusts)
|
||||||
require.Equal(t, expected.SafeMethods, actual.SafeMethods)
|
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))
|
inner, di, err := compiler.CompileWithDebugInfo("foo.go", strings.NewReader(srcInner))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
m, err := di.ConvertToManifest(smartcontract.NoProperties, nil)
|
m, err := di.ConvertToManifest(nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ih := hash.Hash160(inner)
|
ih := hash.Hash160(inner)
|
||||||
|
|
|
@ -377,7 +377,7 @@ func newDeployTx(t *testing.T, name string) (*transaction.Transaction, []byte) {
|
||||||
t.Logf("contractScript: %x", avm)
|
t.Logf("contractScript: %x", avm)
|
||||||
|
|
||||||
script := io.NewBufBinWriter()
|
script := io.NewBufBinWriter()
|
||||||
m, err := di.ConvertToManifest(smartcontract.HasStorage, nil)
|
m, err := di.ConvertToManifest(nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
bs, err := m.MarshalJSON()
|
bs, err := m.MarshalJSON()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -182,15 +182,6 @@ func contractUpdate(ic *interop.Context) error {
|
||||||
if !contract.Manifest.IsValid(contract.ScriptHash()) {
|
if !contract.Manifest.IsValid(contract.ScriptHash()) {
|
||||||
return errors.New("failed to check contract script hash against new manifest")
|
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 {
|
if err := ic.DAO.PutContractState(contract); err != nil {
|
||||||
return fmt.Errorf("failed to update manifest: %w", err)
|
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/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"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/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/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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) {
|
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
|
||||||
script := []byte("testscript")
|
script := []byte("testscript")
|
||||||
m := manifest.NewManifest(hash.Hash160(script))
|
m := manifest.NewManifest(hash.Hash160(script))
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
contractState := &state.Contract{
|
contractState := &state.Contract{
|
||||||
Script: script,
|
Script: script,
|
||||||
Manifest: *m,
|
Manifest: *m,
|
||||||
|
|
|
@ -106,8 +106,6 @@ func contractToStackItem(cs *state.Contract) (stackitem.Item, error) {
|
||||||
return stackitem.NewArray([]stackitem.Item{
|
return stackitem.NewArray([]stackitem.Item{
|
||||||
stackitem.NewByteArray(cs.Script),
|
stackitem.NewByteArray(cs.Script),
|
||||||
stackitem.NewByteArray(manifest),
|
stackitem.NewByteArray(manifest),
|
||||||
stackitem.NewBool(cs.HasStorage()),
|
|
||||||
stackitem.NewBool(cs.IsPayable()),
|
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,9 +363,6 @@ func storageGetContextInternal(ic *interop.Context, isReadOnly bool) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !contract.HasStorage() {
|
|
||||||
return errors.New("contract is not allowed to use storage")
|
|
||||||
}
|
|
||||||
sc := &StorageContext{
|
sc := &StorageContext{
|
||||||
ID: contract.ID,
|
ID: contract.ID,
|
||||||
ReadOnly: isReadOnly,
|
ReadOnly: isReadOnly,
|
||||||
|
@ -464,14 +459,12 @@ func contractDestroy(ic *interop.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cs.HasStorage() {
|
siMap, err := ic.DAO.GetStorageItems(cs.ID)
|
||||||
siMap, err := ic.DAO.GetStorageItems(cs.ID)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
for k := range siMap {
|
||||||
for k := range siMap {
|
_ = ic.DAO.DeleteStorageItem(cs.ID, []byte(k))
|
||||||
_ = ic.DAO.DeleteStorageItem(cs.ID, []byte(k))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,7 +411,6 @@ func getTestContractState() (*state.Contract, *state.Contract) {
|
||||||
script := w.Bytes()
|
script := w.Bytes()
|
||||||
h := hash.Hash160(script)
|
h := hash.Hash160(script)
|
||||||
m := manifest.NewManifest(h)
|
m := manifest.NewManifest(h)
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
m.ABI.Methods = []manifest.Method{
|
m.ABI.Methods = []manifest.Method{
|
||||||
{
|
{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
|
@ -675,15 +674,9 @@ func compareContractStates(t *testing.T, expected *state.Contract, actual stacki
|
||||||
expectedManifest, err := expected.Manifest.MarshalJSON()
|
expectedManifest, err := expected.Manifest.MarshalJSON()
|
||||||
require.NoError(t, err)
|
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, expected.Script, act[0].Value().([]byte))
|
||||||
require.Equal(t, expectedManifest, act[1].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) {
|
func TestContractUpdate(t *testing.T) {
|
||||||
|
@ -813,34 +806,12 @@ func TestContractUpdate(t *testing.T) {
|
||||||
require.Error(t, contractUpdate(ic))
|
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()
|
|
||||||
require.NoError(t, err)
|
|
||||||
putArgsOnStack(stackitem.Null{}, manifestBytes)
|
|
||||||
|
|
||||||
require.Error(t, contractUpdate(ic))
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("update manifest, positive", func(t *testing.T) {
|
t.Run("update manifest, positive", func(t *testing.T) {
|
||||||
cs.Manifest.Features = smartcontract.NoProperties
|
|
||||||
require.NoError(t, ic.DAO.PutContractState(cs))
|
require.NoError(t, ic.DAO.PutContractState(cs))
|
||||||
manifest := &manifest.Manifest{
|
manifest := &manifest.Manifest{
|
||||||
ABI: manifest.ABI{
|
ABI: manifest.ABI{
|
||||||
Hash: cs.ScriptHash(),
|
Hash: cs.ScriptHash(),
|
||||||
},
|
},
|
||||||
Features: smartcontract.HasStorage,
|
|
||||||
}
|
}
|
||||||
manifestBytes, err := manifest.MarshalJSON()
|
manifestBytes, err := manifest.MarshalJSON()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -875,7 +846,6 @@ func TestContractUpdate(t *testing.T) {
|
||||||
ABI: manifest.ABI{
|
ABI: manifest.ABI{
|
||||||
Hash: hash.Hash160(newScript),
|
Hash: hash.Hash160(newScript),
|
||||||
},
|
},
|
||||||
Features: smartcontract.HasStorage,
|
|
||||||
}
|
}
|
||||||
newManifestBytes, err := newManifest.MarshalJSON()
|
newManifestBytes, err := newManifest.MarshalJSON()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -69,7 +69,6 @@ func isValidRole(r Role) bool {
|
||||||
func newDesignate() *Designate {
|
func newDesignate() *Designate {
|
||||||
s := &Designate{ContractMD: *interop.NewContractMD(designateName)}
|
s := &Designate{ContractMD: *interop.NewContractMD(designateName)}
|
||||||
s.ContractID = designateContractID
|
s.ContractID = designateContractID
|
||||||
s.Manifest.Features = smartcontract.HasStorage
|
|
||||||
|
|
||||||
desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType,
|
desc := newDescriptor("getDesignatedByRole", smartcontract.ArrayType,
|
||||||
manifest.NewParameter("role", smartcontract.IntegerType),
|
manifest.NewParameter("role", smartcontract.IntegerType),
|
||||||
|
|
|
@ -104,7 +104,6 @@ func GetOracleResponseScript() []byte {
|
||||||
func newOracle() *Oracle {
|
func newOracle() *Oracle {
|
||||||
o := &Oracle{ContractMD: *interop.NewContractMD(oracleName)}
|
o := &Oracle{ContractMD: *interop.NewContractMD(oracleName)}
|
||||||
o.ContractID = oracleContractID
|
o.ContractID = oracleContractID
|
||||||
o.Manifest.Features = smartcontract.HasStorage
|
|
||||||
|
|
||||||
desc := newDescriptor("request", smartcontract.VoidType,
|
desc := newDescriptor("request", smartcontract.VoidType,
|
||||||
manifest.NewParameter("url", smartcontract.StringType),
|
manifest.NewParameter("url", smartcontract.StringType),
|
||||||
|
|
|
@ -74,7 +74,6 @@ func newPolicy() *Policy {
|
||||||
p := &Policy{ContractMD: *interop.NewContractMD(policyName)}
|
p := &Policy{ContractMD: *interop.NewContractMD(policyName)}
|
||||||
|
|
||||||
p.ContractID = policyContractID
|
p.ContractID = policyContractID
|
||||||
p.Manifest.Features |= smartcontract.HasStorage
|
|
||||||
|
|
||||||
desc := newDescriptor("getMaxTransactionsPerBlock", smartcontract.IntegerType)
|
desc := newDescriptor("getMaxTransactionsPerBlock", smartcontract.IntegerType)
|
||||||
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, smartcontract.AllowStates)
|
md := newMethodAndPrice(p.getMaxTransactionsPerBlock, 1000000, smartcontract.AllowStates)
|
||||||
|
|
|
@ -50,7 +50,6 @@ func getOracleContractState(h util.Uint160) *state.Contract {
|
||||||
emit.Opcodes(w.BinWriter, opcode.RET)
|
emit.Opcodes(w.BinWriter, opcode.RET)
|
||||||
|
|
||||||
m := manifest.NewManifest(h)
|
m := manifest.NewManifest(h)
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
m.ABI.Methods = []manifest.Method{
|
m.ABI.Methods = []manifest.Method{
|
||||||
{
|
{
|
||||||
Name: "requestURL",
|
Name: "requestURL",
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"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/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
@ -48,16 +47,6 @@ func (cs *Contract) createHash() {
|
||||||
cs.scriptHash = hash.Hash160(cs.Script)
|
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 {
|
type contractJSON struct {
|
||||||
ID int32 `json:"id"`
|
ID int32 `json:"id"`
|
||||||
Script []byte `json:"script"`
|
Script []byte `json:"script"`
|
||||||
|
|
|
@ -29,7 +29,6 @@ func TestEncodeDecodeContractState(t *testing.T) {
|
||||||
},
|
},
|
||||||
ReturnType: smartcontract.BoolType,
|
ReturnType: smartcontract.BoolType,
|
||||||
}}
|
}}
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
contract := &Contract{
|
contract := &Contract{
|
||||||
ID: 123,
|
ID: 123,
|
||||||
Script: script,
|
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
|
// this package. It's similar in function to the Contract class in the Neo .net
|
||||||
// framework.
|
// framework.
|
||||||
type Contract struct {
|
type Contract struct {
|
||||||
Script []byte
|
Script []byte
|
||||||
Manifest []byte
|
Manifest []byte
|
||||||
HasStorage bool
|
|
||||||
IsPayable bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new contract using a set of input parameters:
|
// Create creates a new contract using a set of input parameters:
|
||||||
|
|
|
@ -327,14 +327,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
}
|
}
|
||||||
return c.GetContractStateByHash(hash)
|
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{} {
|
result: func(c *Client) interface{} {
|
||||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
m := manifest.NewManifest(hash.Hash160(script))
|
m := manifest.NewManifest(hash.Hash160(script))
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
cs := &state.Contract{
|
cs := &state.Contract{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Script: script,
|
Script: script,
|
||||||
|
@ -349,14 +348,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.GetContractStateByAddressOrName("NWiu5oejTu925aeL9Hc1LX8SvaJhE23h15")
|
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{} {
|
result: func(c *Client) interface{} {
|
||||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
m := manifest.NewManifest(hash.Hash160(script))
|
m := manifest.NewManifest(hash.Hash160(script))
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
cs := &state.Contract{
|
cs := &state.Contract{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Script: script,
|
Script: script,
|
||||||
|
@ -371,14 +369,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.GetContractStateByID(0)
|
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{} {
|
result: func(c *Client) interface{} {
|
||||||
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
script, err := base64.StdEncoding.DecodeString("VgJXHwIMDWNvbnRyYWN0IGNhbGx4eVMTwEEFB5IWIXhKDANQdXSXJyQAAAAQVUGEGNYNIXJqeRDOeRHOU0FSoUH1IUURQCOPAgAASgwLdG90YWxTdXBwbHmXJxEAAABFAkBCDwBAI28CAABKDAhkZWNpbWFsc5cnDQAAAEUSQCNWAgAASgwEbmFtZZcnEgAAAEUMBFJ1YmxAIzwCAABKDAZzeW1ib2yXJxEAAABFDANSVUJAIyECAABKDAliYWxhbmNlT2aXJ2IAAAAQVUGEGNYNIXN5EM50bMoAFLQnIwAAAAwPaW52YWxpZCBhZGRyZXNzEVVBNtNSBiFFENsgQGtsUEEfLnsHIXUMCWJhbGFuY2VPZmxtUxPAQQUHkhYhRW1AI7IBAABKDAh0cmFuc2ZlcpcnKwEAABBVQYQY1g0hdnkQzncHbwfKABS0JyoAAAAMFmludmFsaWQgJ2Zyb20nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRHOdwhvCMoAFLQnKAAAAAwUaW52YWxpZCAndG8nIGFkZHJlc3MRVUE201IGIUUQ2yBAeRLOdwlvCRC1JyIAAAAMDmludmFsaWQgYW1vdW50EVVBNtNSBiFFENsgQG5vB1BBHy57ByF3Cm8Kbwm1JyYAAAAMEmluc3VmZmljaWVudCBmdW5kcxFVQTbTUgYhRRDbIEBvCm8Jn3cKbm8HbwpTQVKhQfUhbm8IUEEfLnsHIXcLbwtvCZ53C25vCG8LU0FSoUH1IQwIdHJhbnNmZXJvB28IbwlUFMBBBQeSFiFFEUAjewAAAEoMBGluaXSXJ1AAAAAQVUGEGNYNIXcMEFVBh8PSZCF3DQJAQg8Adw5vDG8Nbw5TQVKhQfUhDAh0cmFuc2ZlcgwA2zBvDW8OVBTAQQUHkhYhRRFAIyMAAAAMEWludmFsaWQgb3BlcmF0aW9uQTbTUgY6IwUAAABFQA==")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
m := manifest.NewManifest(hash.Hash160(script))
|
m := manifest.NewManifest(hash.Hash160(script))
|
||||||
m.Features = smartcontract.HasStorage
|
|
||||||
cs := &state.Contract{
|
cs := &state.Contract{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Script: script,
|
Script: script,
|
||||||
|
@ -1466,9 +1463,9 @@ func wrapInitResponse(r *request.In, resp string) string {
|
||||||
}
|
}
|
||||||
switch name {
|
switch name {
|
||||||
case "neo":
|
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":
|
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:
|
default:
|
||||||
response = resp
|
response = resp
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,9 +38,7 @@ type Manifest struct {
|
||||||
// ABI is a contract's ABI.
|
// ABI is a contract's ABI.
|
||||||
ABI ABI
|
ABI ABI
|
||||||
// Groups is a set of groups to which a contract belongs.
|
// Groups is a set of groups to which a contract belongs.
|
||||||
Groups []Group
|
Groups []Group
|
||||||
// Features is a set of contract's features.
|
|
||||||
Features smartcontract.PropertyState
|
|
||||||
Permissions []Permission
|
Permissions []Permission
|
||||||
// SupportedStandards is a list of standards supported by the contract.
|
// SupportedStandards is a list of standards supported by the contract.
|
||||||
SupportedStandards []string
|
SupportedStandards []string
|
||||||
|
@ -54,14 +51,13 @@ type Manifest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type manifestAux struct {
|
type manifestAux struct {
|
||||||
ABI *ABI `json:"abi"`
|
ABI *ABI `json:"abi"`
|
||||||
Groups []Group `json:"groups"`
|
Groups []Group `json:"groups"`
|
||||||
Features map[string]bool `json:"features"`
|
Permissions []Permission `json:"permissions"`
|
||||||
Permissions []Permission `json:"permissions"`
|
SupportedStandards []string `json:"supportedstandards"`
|
||||||
SupportedStandards []string `json:"supportedstandards"`
|
Trusts *WildUint160s `json:"trusts"`
|
||||||
Trusts *WildUint160s `json:"trusts"`
|
SafeMethods *WildStrings `json:"safemethods"`
|
||||||
SafeMethods *WildStrings `json:"safemethods"`
|
Extra interface{} `json:"extra"`
|
||||||
Extra interface{} `json:"extra"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManifest returns new manifest with necessary fields initialized.
|
// NewManifest returns new manifest with necessary fields initialized.
|
||||||
|
@ -73,7 +69,6 @@ func NewManifest(h util.Uint160) *Manifest {
|
||||||
Events: []Event{},
|
Events: []Event{},
|
||||||
},
|
},
|
||||||
Groups: []Group{},
|
Groups: []Group{},
|
||||||
Features: smartcontract.NoProperties,
|
|
||||||
SupportedStandards: []string{},
|
SupportedStandards: []string{},
|
||||||
}
|
}
|
||||||
m.Trusts.Restrict()
|
m.Trusts.Restrict()
|
||||||
|
@ -129,13 +124,9 @@ func (m *Manifest) IsValid(hash util.Uint160) bool {
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler interface.
|
// MarshalJSON implements json.Marshaler interface.
|
||||||
func (m *Manifest) MarshalJSON() ([]byte, error) {
|
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{
|
aux := &manifestAux{
|
||||||
ABI: &m.ABI,
|
ABI: &m.ABI,
|
||||||
Groups: m.Groups,
|
Groups: m.Groups,
|
||||||
Features: features,
|
|
||||||
Permissions: m.Permissions,
|
Permissions: m.Permissions,
|
||||||
SupportedStandards: m.SupportedStandards,
|
SupportedStandards: m.SupportedStandards,
|
||||||
Trusts: &m.Trusts,
|
Trusts: &m.Trusts,
|
||||||
|
@ -157,13 +148,6 @@ func (m *Manifest) UnmarshalJSON(data []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if aux.Features["storage"] {
|
|
||||||
m.Features |= smartcontract.HasStorage
|
|
||||||
}
|
|
||||||
if aux.Features["payable"] {
|
|
||||||
m.Features |= smartcontract.IsPayable
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Groups = aux.Groups
|
m.Groups = aux.Groups
|
||||||
m.Permissions = aux.Permissions
|
m.Permissions = aux.Permissions
|
||||||
m.SupportedStandards = aux.SupportedStandards
|
m.SupportedStandards = aux.SupportedStandards
|
||||||
|
|
|
@ -13,39 +13,33 @@ import (
|
||||||
// https://github.com/neo-project/neo/blob/master/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs#L10
|
// https://github.com/neo-project/neo/blob/master/tests/neo.UnitTests/SmartContract/Manifest/UT_ContractManifest.cs#L10
|
||||||
func TestManifest_MarshalJSON(t *testing.T) {
|
func TestManifest_MarshalJSON(t *testing.T) {
|
||||||
t.Run("default", func(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)
|
m := testUnmarshalMarshalManifest(t, s)
|
||||||
require.Equal(t, DefaultManifest(util.Uint160{}), m)
|
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) {
|
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)
|
testUnmarshalMarshalManifest(t, s)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("safe methods", func(t *testing.T) {
|
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)
|
testUnmarshalMarshalManifest(t, s)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("trust", func(t *testing.T) {
|
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)
|
testUnmarshalMarshalManifest(t, s)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("groups", func(t *testing.T) {
|
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)
|
testUnmarshalMarshalManifest(t, s)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("extra", func(t *testing.T) {
|
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)
|
testUnmarshalMarshalManifest(t, s)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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.
|
// Parameter represents a smart contract parameter.
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
// Type of the parameter.
|
// Type of the parameter.
|
||||||
|
|
Loading…
Reference in a new issue