diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index bb4054401..a311f0993 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -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") diff --git a/cli/smartcontract/smart_contract_test.go b/cli/smartcontract/smart_contract_test.go index 1d0b92b23..b8c019b73 100644 --- a/cli/smartcontract/smart_contract_test.go +++ b/cli/smartcontract/smart_contract_test.go @@ -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{ diff --git a/cli/testdata/deploy/neo-go.yml b/cli/testdata/deploy/neo-go.yml index 3a9140d76..e69de29bb 100644 --- a/cli/testdata/deploy/neo-go.yml +++ b/cli/testdata/deploy/neo-go.yml @@ -1 +0,0 @@ -hasstorage: true diff --git a/cli/testdata/verify.manifest.json b/cli/testdata/verify.manifest.json index 970102f7c..910fce3b8 100755 --- a/cli/testdata/verify.manifest.json +++ b/cli/testdata/verify.manifest.json @@ -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} \ No newline at end of file +{"abi":{"hash":"0x8dff9f223e4622961f410c015dd37052a59892bb","methods":[{"name":"verify","offset":0,"parameters":[],"returntype":"Boolean"}],"events":[]},"groups":[],"permissions":[{"contract":"*","methods":"*"}],"supportedstandards":[],"trusts":[],"safemethods":[],"extra":null} diff --git a/docs/compiler.md b/docs/compiler.md index 382aa0d93..f61305ea9 100644 --- a/docs/compiler.md +++ b/docs/compiler.md @@ -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: diff --git a/examples/engine/engine.yml b/examples/engine/engine.yml index 1fa77b421..2bf0986ef 100644 --- a/examples/engine/engine.yml +++ b/examples/engine/engine.yml @@ -1,5 +1,3 @@ -hasstorage: false -ispayable: false supportedstandards: [] events: - name: Tx diff --git a/examples/iterator/iterator.yml b/examples/iterator/iterator.yml index af36a5660..b81bef6f6 100644 --- a/examples/iterator/iterator.yml +++ b/examples/iterator/iterator.yml @@ -1,5 +1,3 @@ -hasstorage: true -ispayable: false supportedstandards: [] events: - name: found storage values diff --git a/examples/runtime/runtime.yml b/examples/runtime/runtime.yml index 3f206d027..25adbd20f 100644 --- a/examples/runtime/runtime.yml +++ b/examples/runtime/runtime.yml @@ -1,5 +1,3 @@ -hasstorage: false -ispayable: false supportedstandards: [] events: - name: Event diff --git a/examples/storage/storage.yml b/examples/storage/storage.yml index d9b6984cf..d25be3663 100644 --- a/examples/storage/storage.yml +++ b/examples/storage/storage.yml @@ -1,4 +1,2 @@ -hasstorage: true -ispayable: false supportedstandards: [] events: [] diff --git a/examples/timer/timer.yml b/examples/timer/timer.yml index d9b6984cf..d25be3663 100644 --- a/examples/timer/timer.yml +++ b/examples/timer/timer.yml @@ -1,4 +1,2 @@ -hasstorage: true -ispayable: false supportedstandards: [] events: [] diff --git a/examples/token-sale/token_sale.yml b/examples/token-sale/token_sale.yml index 50258d5c2..a50d94c56 100644 --- a/examples/token-sale/token_sale.yml +++ b/examples/token-sale/token_sale.yml @@ -1,4 +1,2 @@ -hasstorage: true -ispayable: false supportedstandards: ["NEP-5"] events: [] diff --git a/examples/token/token.yml b/examples/token/token.yml index f8476fbf9..5c565f98e 100644 --- a/examples/token/token.yml +++ b/examples/token/token.yml @@ -1,5 +1,3 @@ -hasstorage: true -ispayable: false supportedstandards: ["NEP-5"] events: - name: transfer diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 16c28d146..eb81462e3 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -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) } diff --git a/pkg/compiler/debug.go b/pkg/compiler/debug.go index bd51eb8ee..2cf71ff7e 100644 --- a/pkg/compiler/debug.go +++ b/pkg/compiler/debug.go @@ -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 } diff --git a/pkg/compiler/debug_test.go b/pkg/compiler/debug_test.go index 6eabaf703..83d0f0e35 100644 --- a/pkg/compiler/debug_test.go +++ b/pkg/compiler/debug_test.go @@ -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) diff --git a/pkg/compiler/interop_test.go b/pkg/compiler/interop_test.go index 5bcd269a2..901217b96 100644 --- a/pkg/compiler/interop_test.go +++ b/pkg/compiler/interop_test.go @@ -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) diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index f41c09d24..ad8205e81 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -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) diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index e1a8be374..35f9e9f0e 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -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) } diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index 64dde00ce..a04fd3f12 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -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, diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 76cd9dc4c..60c722418 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -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 } diff --git a/pkg/core/interop_system_test.go b/pkg/core/interop_system_test.go index 0eaf8e274..8f60fc075 100644 --- a/pkg/core/interop_system_test.go +++ b/pkg/core/interop_system_test.go @@ -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) diff --git a/pkg/core/native/designate.go b/pkg/core/native/designate.go index 6c3724dc0..7440d8213 100644 --- a/pkg/core/native/designate.go +++ b/pkg/core/native/designate.go @@ -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), diff --git a/pkg/core/native/oracle.go b/pkg/core/native/oracle.go index 4088899e5..599c3dc99 100644 --- a/pkg/core/native/oracle.go +++ b/pkg/core/native/oracle.go @@ -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), diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index 0761e8447..f6a9f6395 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -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) diff --git a/pkg/core/native_oracle_test.go b/pkg/core/native_oracle_test.go index b1bb18b93..0c2aca4a5 100644 --- a/pkg/core/native_oracle_test.go +++ b/pkg/core/native_oracle_test.go @@ -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", diff --git a/pkg/core/state/contract.go b/pkg/core/state/contract.go index 227b13ab7..ea9570b38 100644 --- a/pkg/core/state/contract.go +++ b/pkg/core/state/contract.go @@ -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"` diff --git a/pkg/core/state/contract_test.go b/pkg/core/state/contract_test.go index 052f11c39..cc2936fea 100644 --- a/pkg/core/state/contract_test.go +++ b/pkg/core/state/contract_test.go @@ -29,7 +29,6 @@ func TestEncodeDecodeContractState(t *testing.T) { }, ReturnType: smartcontract.BoolType, }} - m.Features = smartcontract.HasStorage contract := &Contract{ ID: 123, Script: script, diff --git a/pkg/interop/contract/contract.go b/pkg/interop/contract/contract.go index 30930a08a..89862018a 100644 --- a/pkg/interop/contract/contract.go +++ b/pkg/interop/contract/contract.go @@ -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: diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index 7ee11d0b6..0ca265f13 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -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 } diff --git a/pkg/rpc/request/txBuilder.go b/pkg/rpc/request/txBuilder.go index 610b9fc7b..a096e99f2 100644 --- a/pkg/rpc/request/txBuilder.go +++ b/pkg/rpc/request/txBuilder.go @@ -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 } diff --git a/pkg/smartcontract/contract_details.go b/pkg/smartcontract/contract_details.go deleted file mode 100644 index 05132f0c8..000000000 --- a/pkg/smartcontract/contract_details.go +++ /dev/null @@ -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 -} diff --git a/pkg/smartcontract/manifest/container.go b/pkg/smartcontract/manifest/container.go index 77f88de5e..3424d9e51 100644 --- a/pkg/smartcontract/manifest/container.go +++ b/pkg/smartcontract/manifest/container.go @@ -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 } diff --git a/pkg/smartcontract/manifest/manifest.go b/pkg/smartcontract/manifest/manifest.go index 40680dad1..9c3b56fad 100644 --- a/pkg/smartcontract/manifest/manifest.go +++ b/pkg/smartcontract/manifest/manifest.go @@ -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) diff --git a/pkg/smartcontract/manifest/manifest_test.go b/pkg/smartcontract/manifest/manifest_test.go index ce9728f03..cb48c1edb 100644 --- a/pkg/smartcontract/manifest/manifest_test.go +++ b/pkg/smartcontract/manifest/manifest_test.go @@ -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) }) } diff --git a/pkg/smartcontract/parameter.go b/pkg/smartcontract/parameter.go index 116d98eaf..08d453916 100644 --- a/pkg/smartcontract/parameter.go +++ b/pkg/smartcontract/parameter.go @@ -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.