diff --git a/cli/smartcontract/generate.go b/cli/smartcontract/generate.go index 47c662865..0831fd494 100644 --- a/cli/smartcontract/generate.go +++ b/cli/smartcontract/generate.go @@ -29,9 +29,8 @@ var generatorFlags = []cli.Flag{ Usage: "Output of the compiled wrapper", }, cli.StringFlag{ - Name: "hash", - Required: true, - Usage: "Smart-contract hash", + Name: "hash", + Usage: "Smart-contract hash", }, } @@ -53,21 +52,29 @@ var generateRPCWrapperCmd = cli.Command{ } func contractGenerateWrapper(ctx *cli.Context) error { - return contractGenerateSomething(ctx, binding.Generate) + return contractGenerateSomething(ctx, binding.Generate, false) } func contractGenerateRPCWrapper(ctx *cli.Context) error { - return contractGenerateSomething(ctx, rpcbinding.Generate) + return contractGenerateSomething(ctx, rpcbinding.Generate, true) } // contractGenerateSomething reads generator parameters and calls the given callback. -func contractGenerateSomething(ctx *cli.Context, cb func(binding.Config) error) error { +func contractGenerateSomething(ctx *cli.Context, cb func(binding.Config) error, allowEmptyHash bool) error { if err := cmdargs.EnsureNone(ctx); err != nil { return err } - h, err := util.Uint160DecodeStringLE(strings.TrimPrefix(ctx.String("hash"), "0x")) - if err != nil { - return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1) + var ( + h util.Uint160 + err error + ) + if hStr := ctx.String("hash"); len(hStr) != 0 { + h, err = util.Uint160DecodeStringLE(strings.TrimPrefix(hStr, "0x")) + if err != nil { + return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1) + } + } else if !allowEmptyHash { + return cli.NewExitError("contract hash must be provided via --hash flag", 1) } m, _, err := readManifest(ctx.String("manifest"), h) if err != nil { diff --git a/cli/smartcontract/generate_test.go b/cli/smartcontract/generate_test.go index 6c6a63f90..be3cd313e 100644 --- a/cli/smartcontract/generate_test.go +++ b/cli/smartcontract/generate_test.go @@ -3,6 +3,7 @@ package smartcontract import ( "bytes" "encoding/json" + "fmt" "os" "path/filepath" "strings" @@ -309,16 +310,18 @@ type Invoker interface { // ContractReader implements safe contract methods. type ContractReader struct { invoker Invoker + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{invoker} + var hash = Hash + return &ContractReader{invoker, hash} } // Get invokes `+"`get`"+` method of contract. func (c *ContractReader) Get() (*big.Int, error) { - return unwrap.BigInt(c.invoker.Call(Hash, "get")) + return unwrap.BigInt(c.invoker.Call(c.hash, "get")) } `, string(data)) } @@ -379,17 +382,20 @@ func TestAssistedRPCBindings(t *testing.T) { app := cli.NewApp() app.Commands = NewCommands() - var checkBinding = func(source string, guessEventTypes bool, suffix ...string) { + var checkBinding = func(source string, hasDefinedHash bool, guessEventTypes bool, suffix ...string) { testName := source if len(suffix) != 0 { testName += suffix[0] } + testName += fmt.Sprintf(", predefined hash: %t", hasDefinedHash) t.Run(testName, func(t *testing.T) { configFile := filepath.Join(source, "config.yml") expectedFile := filepath.Join(source, "rpcbindings.out") if len(suffix) != 0 { configFile = filepath.Join(source, "config"+suffix[0]+".yml") expectedFile = filepath.Join(source, "rpcbindings"+suffix[0]+".out") + } else if !hasDefinedHash { + expectedFile = filepath.Join(source, "rpcbindings_dynamic_hash.out") } manifestF := filepath.Join(tmpDir, "manifest.json") bindingF := filepath.Join(tmpDir, "binding.yml") @@ -405,15 +411,18 @@ func TestAssistedRPCBindings(t *testing.T) { cmd = append(cmd, "--guess-eventtypes") } require.NoError(t, app.Run(cmd)) - outFile := filepath.Join(tmpDir, "out.go") - require.NoError(t, app.Run([]string{"", "contract", "generate-rpcwrapper", + + cmds := []string{"", "contract", "generate-rpcwrapper", "--config", bindingF, "--manifest", manifestF, - "--out", outFile, - "--hash", "0x00112233445566778899aabbccddeeff00112233", - })) + "--out", expectedFile, + } + if hasDefinedHash { + cmds = append(cmds, "--hash", "0x00112233445566778899aabbccddeeff00112233") + } + require.NoError(t, app.Run(cmds)) - data, err := os.ReadFile(outFile) + data, err := os.ReadFile(expectedFile) require.NoError(t, err) data = bytes.ReplaceAll(data, []byte("\r"), []byte{}) // Windows. if rewriteExpectedOutputs { @@ -427,11 +436,13 @@ func TestAssistedRPCBindings(t *testing.T) { }) } - checkBinding(filepath.Join("testdata", "types"), false) - checkBinding(filepath.Join("testdata", "structs"), false) - checkBinding(filepath.Join("testdata", "notifications"), false) - checkBinding(filepath.Join("testdata", "notifications"), false, "_extended") - checkBinding(filepath.Join("testdata", "notifications"), true, "_guessed") + for _, hasDefinedHash := range []bool{true, false} { + checkBinding(filepath.Join("testdata", "types"), hasDefinedHash, false) + checkBinding(filepath.Join("testdata", "structs"), hasDefinedHash, false) + } + checkBinding(filepath.Join("testdata", "notifications"), true, false) + checkBinding(filepath.Join("testdata", "notifications"), true, false, "_extended") + checkBinding(filepath.Join("testdata", "notifications"), true, true, "_guessed") require.False(t, rewriteExpectedOutputs) } diff --git a/cli/smartcontract/testdata/gas/gas.go b/cli/smartcontract/testdata/gas/gas.go index d12bbb8ee..e83072fbb 100644 --- a/cli/smartcontract/testdata/gas/gas.go +++ b/cli/smartcontract/testdata/gas/gas.go @@ -25,6 +25,7 @@ type Actor interface { type ContractReader struct { nep17.TokenReader invoker Invoker + hash util.Uint160 } // Contract implements all contract methods. @@ -32,15 +33,18 @@ type Contract struct { ContractReader nep17.TokenWriter actor Actor + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{*nep17.NewReader(invoker, Hash), invoker} + var hash = Hash + return &ContractReader{*nep17.NewReader(invoker, hash), invoker, hash} } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - var nep17t = nep17.New(actor, Hash) - return &Contract{ContractReader{nep17t.TokenReader, actor}, nep17t.TokenWriter, actor} + var hash = Hash + var nep17t = nep17.New(actor, hash) + return &Contract{ContractReader{nep17t.TokenReader, actor, hash}, nep17t.TokenWriter, actor, hash} } diff --git a/cli/smartcontract/testdata/nameservice/nns.go b/cli/smartcontract/testdata/nameservice/nns.go index 3636fd333..da5f0311a 100644 --- a/cli/smartcontract/testdata/nameservice/nns.go +++ b/cli/smartcontract/testdata/nameservice/nns.go @@ -56,6 +56,7 @@ type Actor interface { type ContractReader struct { nep11.NonDivisibleReader invoker Invoker + hash util.Uint160 } // Contract implements all contract methods. @@ -63,22 +64,25 @@ type Contract struct { ContractReader nep11.BaseWriter actor Actor + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{*nep11.NewNonDivisibleReader(invoker, Hash), invoker} + var hash = Hash + return &ContractReader{*nep11.NewNonDivisibleReader(invoker, hash), invoker, hash} } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - var nep11ndt = nep11.NewNonDivisible(actor, Hash) - return &Contract{ContractReader{nep11ndt.NonDivisibleReader, actor}, nep11ndt.BaseWriter, actor} + var hash = Hash + var nep11ndt = nep11.NewNonDivisible(actor, hash) + return &Contract{ContractReader{nep11ndt.NonDivisibleReader, actor, hash}, nep11ndt.BaseWriter, actor, hash} } // Roots invokes `roots` method of contract. func (c *ContractReader) Roots() (uuid.UUID, result.Iterator, error) { - return unwrap.SessionIterator(c.invoker.Call(Hash, "roots")) + return unwrap.SessionIterator(c.invoker.Call(c.hash, "roots")) } // RootsExpanded is similar to Roots (uses the same contract @@ -87,27 +91,27 @@ func (c *ContractReader) Roots() (uuid.UUID, result.Iterator, error) { // number of result items from the iterator right in the VM and return them to // you. It's only limited by VM stack and GAS available for RPC invocations. func (c *ContractReader) RootsExpanded(_numOfIteratorItems int) ([]stackitem.Item, error) { - return unwrap.Array(c.invoker.CallAndExpandIterator(Hash, "roots", _numOfIteratorItems)) + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "roots", _numOfIteratorItems)) } // GetPrice invokes `getPrice` method of contract. func (c *ContractReader) GetPrice(length *big.Int) (*big.Int, error) { - return unwrap.BigInt(c.invoker.Call(Hash, "getPrice", length)) + return unwrap.BigInt(c.invoker.Call(c.hash, "getPrice", length)) } // IsAvailable invokes `isAvailable` method of contract. func (c *ContractReader) IsAvailable(name string) (bool, error) { - return unwrap.Bool(c.invoker.Call(Hash, "isAvailable", name)) + return unwrap.Bool(c.invoker.Call(c.hash, "isAvailable", name)) } // GetRecord invokes `getRecord` method of contract. func (c *ContractReader) GetRecord(name string, typev *big.Int) (string, error) { - return unwrap.UTF8String(c.invoker.Call(Hash, "getRecord", name, typev)) + return unwrap.UTF8String(c.invoker.Call(c.hash, "getRecord", name, typev)) } // GetAllRecords invokes `getAllRecords` method of contract. func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, error) { - return unwrap.SessionIterator(c.invoker.Call(Hash, "getAllRecords", name)) + return unwrap.SessionIterator(c.invoker.Call(c.hash, "getAllRecords", name)) } // GetAllRecordsExpanded is similar to GetAllRecords (uses the same contract @@ -116,26 +120,26 @@ func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, // number of result items from the iterator right in the VM and return them to // you. It's only limited by VM stack and GAS available for RPC invocations. func (c *ContractReader) GetAllRecordsExpanded(name string, _numOfIteratorItems int) ([]stackitem.Item, error) { - return unwrap.Array(c.invoker.CallAndExpandIterator(Hash, "getAllRecords", _numOfIteratorItems, name)) + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "getAllRecords", _numOfIteratorItems, name)) } // Resolve invokes `resolve` method of contract. func (c *ContractReader) Resolve(name string, typev *big.Int) (string, error) { - return unwrap.UTF8String(c.invoker.Call(Hash, "resolve", name, typev)) + return unwrap.UTF8String(c.invoker.Call(c.hash, "resolve", name, typev)) } // Update creates a transaction invoking `update` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Update(nef []byte, manifest string) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "update", nef, manifest) + return c.actor.SendCall(c.hash, "update", nef, manifest) } // UpdateTransaction creates a transaction invoking `update` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) UpdateTransaction(nef []byte, manifest string) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "update", nef, manifest) + return c.actor.MakeCall(c.hash, "update", nef, manifest) } // UpdateUnsigned creates a transaction invoking `update` method of the contract. @@ -143,21 +147,21 @@ func (c *Contract) UpdateTransaction(nef []byte, manifest string) (*transaction. // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) UpdateUnsigned(nef []byte, manifest string) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "update", nil, nef, manifest) + return c.actor.MakeUnsignedCall(c.hash, "update", nil, nef, manifest) } // AddRoot creates a transaction invoking `addRoot` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) AddRoot(root string) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "addRoot", root) + return c.actor.SendCall(c.hash, "addRoot", root) } // AddRootTransaction creates a transaction invoking `addRoot` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) AddRootTransaction(root string) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "addRoot", root) + return c.actor.MakeCall(c.hash, "addRoot", root) } // AddRootUnsigned creates a transaction invoking `addRoot` method of the contract. @@ -165,21 +169,21 @@ func (c *Contract) AddRootTransaction(root string) (*transaction.Transaction, er // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) AddRootUnsigned(root string) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "addRoot", nil, root) + return c.actor.MakeUnsignedCall(c.hash, "addRoot", nil, root) } // SetPrice creates a transaction invoking `setPrice` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) SetPrice(priceList []any) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "setPrice", priceList) + return c.actor.SendCall(c.hash, "setPrice", priceList) } // SetPriceTransaction creates a transaction invoking `setPrice` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) SetPriceTransaction(priceList []any) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "setPrice", priceList) + return c.actor.MakeCall(c.hash, "setPrice", priceList) } // SetPriceUnsigned creates a transaction invoking `setPrice` method of the contract. @@ -187,11 +191,11 @@ func (c *Contract) SetPriceTransaction(priceList []any) (*transaction.Transactio // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) SetPriceUnsigned(priceList []any) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "setPrice", nil, priceList) + return c.actor.MakeUnsignedCall(c.hash, "setPrice", nil, priceList) } func scriptForRegister(name string, owner util.Uint160) ([]byte, error) { - return smartcontract.CreateCallWithAssertScript(Hash, "register", name, owner) + return smartcontract.CreateCallWithAssertScript(c.hash, "register", name, owner) } // Register creates a transaction invoking `register` method of the contract. @@ -232,14 +236,14 @@ func (c *Contract) RegisterUnsigned(name string, owner util.Uint160) (*transacti // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Renew(name string) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "renew", name) + return c.actor.SendCall(c.hash, "renew", name) } // RenewTransaction creates a transaction invoking `renew` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) RenewTransaction(name string) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "renew", name) + return c.actor.MakeCall(c.hash, "renew", name) } // RenewUnsigned creates a transaction invoking `renew` method of the contract. @@ -247,21 +251,21 @@ func (c *Contract) RenewTransaction(name string) (*transaction.Transaction, erro // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) RenewUnsigned(name string) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "renew", nil, name) + return c.actor.MakeUnsignedCall(c.hash, "renew", nil, name) } // Renew_2 creates a transaction invoking `renew` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Renew_2(name string, years *big.Int) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "renew", name, years) + return c.actor.SendCall(c.hash, "renew", name, years) } // Renew_2Transaction creates a transaction invoking `renew` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) Renew_2Transaction(name string, years *big.Int) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "renew", name, years) + return c.actor.MakeCall(c.hash, "renew", name, years) } // Renew_2Unsigned creates a transaction invoking `renew` method of the contract. @@ -269,21 +273,21 @@ func (c *Contract) Renew_2Transaction(name string, years *big.Int) (*transaction // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) Renew_2Unsigned(name string, years *big.Int) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "renew", nil, name, years) + return c.actor.MakeUnsignedCall(c.hash, "renew", nil, name, years) } // SetAdmin creates a transaction invoking `setAdmin` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) SetAdmin(name string, admin util.Uint160) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "setAdmin", name, admin) + return c.actor.SendCall(c.hash, "setAdmin", name, admin) } // SetAdminTransaction creates a transaction invoking `setAdmin` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) SetAdminTransaction(name string, admin util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "setAdmin", name, admin) + return c.actor.MakeCall(c.hash, "setAdmin", name, admin) } // SetAdminUnsigned creates a transaction invoking `setAdmin` method of the contract. @@ -291,21 +295,21 @@ func (c *Contract) SetAdminTransaction(name string, admin util.Uint160) (*transa // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) SetAdminUnsigned(name string, admin util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "setAdmin", nil, name, admin) + return c.actor.MakeUnsignedCall(c.hash, "setAdmin", nil, name, admin) } // SetRecord creates a transaction invoking `setRecord` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) SetRecord(name string, typev *big.Int, data string) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "setRecord", name, typev, data) + return c.actor.SendCall(c.hash, "setRecord", name, typev, data) } // SetRecordTransaction creates a transaction invoking `setRecord` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) SetRecordTransaction(name string, typev *big.Int, data string) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "setRecord", name, typev, data) + return c.actor.MakeCall(c.hash, "setRecord", name, typev, data) } // SetRecordUnsigned creates a transaction invoking `setRecord` method of the contract. @@ -313,21 +317,21 @@ func (c *Contract) SetRecordTransaction(name string, typev *big.Int, data string // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) SetRecordUnsigned(name string, typev *big.Int, data string) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "setRecord", nil, name, typev, data) + return c.actor.MakeUnsignedCall(c.hash, "setRecord", nil, name, typev, data) } // DeleteRecord creates a transaction invoking `deleteRecord` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) DeleteRecord(name string, typev *big.Int) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "deleteRecord", name, typev) + return c.actor.SendCall(c.hash, "deleteRecord", name, typev) } // DeleteRecordTransaction creates a transaction invoking `deleteRecord` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) DeleteRecordTransaction(name string, typev *big.Int) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "deleteRecord", name, typev) + return c.actor.MakeCall(c.hash, "deleteRecord", name, typev) } // DeleteRecordUnsigned creates a transaction invoking `deleteRecord` method of the contract. @@ -335,7 +339,7 @@ func (c *Contract) DeleteRecordTransaction(name string, typev *big.Int) (*transa // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) DeleteRecordUnsigned(name string, typev *big.Int) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "deleteRecord", nil, name, typev) + return c.actor.MakeUnsignedCall(c.hash, "deleteRecord", nil, name, typev) } // SetAdminEventsFromApplicationLog retrieves a set of all emitted events diff --git a/cli/smartcontract/testdata/nex/nex.go b/cli/smartcontract/testdata/nex/nex.go index 32e7526c8..296a3d0e3 100644 --- a/cli/smartcontract/testdata/nex/nex.go +++ b/cli/smartcontract/testdata/nex/nex.go @@ -48,6 +48,7 @@ type Actor interface { type ContractReader struct { nep17.TokenReader invoker Invoker + hash util.Uint160 } // Contract implements all contract methods. @@ -55,51 +56,54 @@ type Contract struct { ContractReader nep17.TokenWriter actor Actor + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{*nep17.NewReader(invoker, Hash), invoker} + var hash = Hash + return &ContractReader{*nep17.NewReader(invoker, hash), invoker, hash} } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - var nep17t = nep17.New(actor, Hash) - return &Contract{ContractReader{nep17t.TokenReader, actor}, nep17t.TokenWriter, actor} + var hash = Hash + var nep17t = nep17.New(actor, hash) + return &Contract{ContractReader{nep17t.TokenReader, actor, hash}, nep17t.TokenWriter, actor, hash} } // Cap invokes `cap` method of contract. func (c *ContractReader) Cap() (*big.Int, error) { - return unwrap.BigInt(c.invoker.Call(Hash, "cap")) + return unwrap.BigInt(c.invoker.Call(c.hash, "cap")) } // GetMinter invokes `getMinter` method of contract. func (c *ContractReader) GetMinter() (*keys.PublicKey, error) { - return unwrap.PublicKey(c.invoker.Call(Hash, "getMinter")) + return unwrap.PublicKey(c.invoker.Call(c.hash, "getMinter")) } // GetOwner invokes `getOwner` method of contract. func (c *ContractReader) GetOwner() (util.Uint160, error) { - return unwrap.Uint160(c.invoker.Call(Hash, "getOwner")) + return unwrap.Uint160(c.invoker.Call(c.hash, "getOwner")) } // TotalMinted invokes `totalMinted` method of contract. func (c *ContractReader) TotalMinted() (*big.Int, error) { - return unwrap.BigInt(c.invoker.Call(Hash, "totalMinted")) + return unwrap.BigInt(c.invoker.Call(c.hash, "totalMinted")) } // ChangeMinter creates a transaction invoking `changeMinter` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) ChangeMinter(newMinter *keys.PublicKey) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "changeMinter", newMinter) + return c.actor.SendCall(c.hash, "changeMinter", newMinter) } // ChangeMinterTransaction creates a transaction invoking `changeMinter` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) ChangeMinterTransaction(newMinter *keys.PublicKey) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "changeMinter", newMinter) + return c.actor.MakeCall(c.hash, "changeMinter", newMinter) } // ChangeMinterUnsigned creates a transaction invoking `changeMinter` method of the contract. @@ -107,21 +111,21 @@ func (c *Contract) ChangeMinterTransaction(newMinter *keys.PublicKey) (*transact // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) ChangeMinterUnsigned(newMinter *keys.PublicKey) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "changeMinter", nil, newMinter) + return c.actor.MakeUnsignedCall(c.hash, "changeMinter", nil, newMinter) } // ChangeOwner creates a transaction invoking `changeOwner` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) ChangeOwner(newOwner util.Uint160) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "changeOwner", newOwner) + return c.actor.SendCall(c.hash, "changeOwner", newOwner) } // ChangeOwnerTransaction creates a transaction invoking `changeOwner` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) ChangeOwnerTransaction(newOwner util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "changeOwner", newOwner) + return c.actor.MakeCall(c.hash, "changeOwner", newOwner) } // ChangeOwnerUnsigned creates a transaction invoking `changeOwner` method of the contract. @@ -129,21 +133,21 @@ func (c *Contract) ChangeOwnerTransaction(newOwner util.Uint160) (*transaction.T // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) ChangeOwnerUnsigned(newOwner util.Uint160) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "changeOwner", nil, newOwner) + return c.actor.MakeUnsignedCall(c.hash, "changeOwner", nil, newOwner) } // Destroy creates a transaction invoking `destroy` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Destroy() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "destroy") + return c.actor.SendCall(c.hash, "destroy") } // DestroyTransaction creates a transaction invoking `destroy` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) DestroyTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "destroy") + return c.actor.MakeCall(c.hash, "destroy") } // DestroyUnsigned creates a transaction invoking `destroy` method of the contract. @@ -151,21 +155,21 @@ func (c *Contract) DestroyTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) DestroyUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "destroy", nil) + return c.actor.MakeUnsignedCall(c.hash, "destroy", nil) } // MaxSupply creates a transaction invoking `maxSupply` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) MaxSupply() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "maxSupply") + return c.actor.SendCall(c.hash, "maxSupply") } // MaxSupplyTransaction creates a transaction invoking `maxSupply` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) MaxSupplyTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "maxSupply") + return c.actor.MakeCall(c.hash, "maxSupply") } // MaxSupplyUnsigned creates a transaction invoking `maxSupply` method of the contract. @@ -173,21 +177,21 @@ func (c *Contract) MaxSupplyTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) MaxSupplyUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "maxSupply", nil) + return c.actor.MakeUnsignedCall(c.hash, "maxSupply", nil) } // Mint creates a transaction invoking `mint` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Mint(from util.Uint160, to util.Uint160, amount *big.Int, swapId *big.Int, signature []byte, data any) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "mint", from, to, amount, swapId, signature, data) + return c.actor.SendCall(c.hash, "mint", from, to, amount, swapId, signature, data) } // MintTransaction creates a transaction invoking `mint` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) MintTransaction(from util.Uint160, to util.Uint160, amount *big.Int, swapId *big.Int, signature []byte, data any) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "mint", from, to, amount, swapId, signature, data) + return c.actor.MakeCall(c.hash, "mint", from, to, amount, swapId, signature, data) } // MintUnsigned creates a transaction invoking `mint` method of the contract. @@ -195,21 +199,21 @@ func (c *Contract) MintTransaction(from util.Uint160, to util.Uint160, amount *b // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) MintUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, swapId *big.Int, signature []byte, data any) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "mint", nil, from, to, amount, swapId, signature, data) + return c.actor.MakeUnsignedCall(c.hash, "mint", nil, from, to, amount, swapId, signature, data) } // Update creates a transaction invoking `update` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Update(nef []byte, manifest []byte) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "update", nef, manifest) + return c.actor.SendCall(c.hash, "update", nef, manifest) } // UpdateTransaction creates a transaction invoking `update` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) UpdateTransaction(nef []byte, manifest []byte) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "update", nef, manifest) + return c.actor.MakeCall(c.hash, "update", nef, manifest) } // UpdateUnsigned creates a transaction invoking `update` method of the contract. @@ -217,21 +221,21 @@ func (c *Contract) UpdateTransaction(nef []byte, manifest []byte) (*transaction. // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) UpdateUnsigned(nef []byte, manifest []byte) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "update", nil, nef, manifest) + return c.actor.MakeUnsignedCall(c.hash, "update", nil, nef, manifest) } // UpdateCap creates a transaction invoking `updateCap` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) UpdateCap(newCap *big.Int) (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "updateCap", newCap) + return c.actor.SendCall(c.hash, "updateCap", newCap) } // UpdateCapTransaction creates a transaction invoking `updateCap` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) UpdateCapTransaction(newCap *big.Int) (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "updateCap", newCap) + return c.actor.MakeCall(c.hash, "updateCap", newCap) } // UpdateCapUnsigned creates a transaction invoking `updateCap` method of the contract. @@ -239,7 +243,7 @@ func (c *Contract) UpdateCapTransaction(newCap *big.Int) (*transaction.Transacti // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) UpdateCapUnsigned(newCap *big.Int) (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "updateCap", nil, newCap) + return c.actor.MakeUnsignedCall(c.hash, "updateCap", nil, newCap) } // OnMintEventsFromApplicationLog retrieves a set of all emitted events diff --git a/cli/smartcontract/testdata/nonepiter/iter.go b/cli/smartcontract/testdata/nonepiter/iter.go index f298ab8de..d9fac3f73 100644 --- a/cli/smartcontract/testdata/nonepiter/iter.go +++ b/cli/smartcontract/testdata/nonepiter/iter.go @@ -23,16 +23,18 @@ type Invoker interface { // ContractReader implements safe contract methods. type ContractReader struct { invoker Invoker + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{invoker} + var hash = Hash + return &ContractReader{invoker, hash} } // Tokens invokes `tokens` method of contract. func (c *ContractReader) Tokens() (uuid.UUID, result.Iterator, error) { - return unwrap.SessionIterator(c.invoker.Call(Hash, "tokens")) + return unwrap.SessionIterator(c.invoker.Call(c.hash, "tokens")) } // TokensExpanded is similar to Tokens (uses the same contract @@ -41,12 +43,12 @@ func (c *ContractReader) Tokens() (uuid.UUID, result.Iterator, error) { // number of result items from the iterator right in the VM and return them to // you. It's only limited by VM stack and GAS available for RPC invocations. func (c *ContractReader) TokensExpanded(_numOfIteratorItems int) ([]stackitem.Item, error) { - return unwrap.Array(c.invoker.CallAndExpandIterator(Hash, "tokens", _numOfIteratorItems)) + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "tokens", _numOfIteratorItems)) } // GetAllRecords invokes `getAllRecords` method of contract. func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, error) { - return unwrap.SessionIterator(c.invoker.Call(Hash, "getAllRecords", name)) + return unwrap.SessionIterator(c.invoker.Call(c.hash, "getAllRecords", name)) } // GetAllRecordsExpanded is similar to GetAllRecords (uses the same contract @@ -55,5 +57,5 @@ func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, // number of result items from the iterator right in the VM and return them to // you. It's only limited by VM stack and GAS available for RPC invocations. func (c *ContractReader) GetAllRecordsExpanded(name string, _numOfIteratorItems int) ([]stackitem.Item, error) { - return unwrap.Array(c.invoker.CallAndExpandIterator(Hash, "getAllRecords", _numOfIteratorItems, name)) + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "getAllRecords", _numOfIteratorItems, name)) } diff --git a/cli/smartcontract/testdata/notifications/rpcbindings.out b/cli/smartcontract/testdata/notifications/rpcbindings.out index a95cc1ea0..74c872833 100644 --- a/cli/smartcontract/testdata/notifications/rpcbindings.out +++ b/cli/smartcontract/testdata/notifications/rpcbindings.out @@ -110,25 +110,27 @@ type Actor interface { // Contract implements all contract methods. type Contract struct { actor Actor + hash util.Uint160 } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - return &Contract{actor} + var hash = Hash + return &Contract{actor, hash} } // Array creates a transaction invoking `array` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Array() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "array") + return c.actor.SendCall(c.hash, "array") } // ArrayTransaction creates a transaction invoking `array` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "array") + return c.actor.MakeCall(c.hash, "array") } // ArrayUnsigned creates a transaction invoking `array` method of the contract. @@ -136,21 +138,21 @@ func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) ArrayUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "array", nil) + return c.actor.MakeUnsignedCall(c.hash, "array", nil) } // CrazyMap creates a transaction invoking `crazyMap` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) CrazyMap() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "crazyMap") + return c.actor.SendCall(c.hash, "crazyMap") } // CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "crazyMap") + return c.actor.MakeCall(c.hash, "crazyMap") } // CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract. @@ -158,21 +160,21 @@ func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "crazyMap", nil) + return c.actor.MakeUnsignedCall(c.hash, "crazyMap", nil) } // Main creates a transaction invoking `main` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Main() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "main") + return c.actor.SendCall(c.hash, "main") } // MainTransaction creates a transaction invoking `main` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) MainTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "main") + return c.actor.MakeCall(c.hash, "main") } // MainUnsigned creates a transaction invoking `main` method of the contract. @@ -180,21 +182,21 @@ func (c *Contract) MainTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) MainUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "main", nil) + return c.actor.MakeUnsignedCall(c.hash, "main", nil) } // Struct creates a transaction invoking `struct` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Struct() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "struct") + return c.actor.SendCall(c.hash, "struct") } // StructTransaction creates a transaction invoking `struct` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) StructTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "struct") + return c.actor.MakeCall(c.hash, "struct") } // StructUnsigned creates a transaction invoking `struct` method of the contract. @@ -202,7 +204,7 @@ func (c *Contract) StructTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) StructUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "struct", nil) + return c.actor.MakeUnsignedCall(c.hash, "struct", nil) } // itemToLedgerBlock converts stack item into *LedgerBlock. diff --git a/cli/smartcontract/testdata/notifications/rpcbindings_extended.out b/cli/smartcontract/testdata/notifications/rpcbindings_extended.out index 818c91993..8a71c6b32 100755 --- a/cli/smartcontract/testdata/notifications/rpcbindings_extended.out +++ b/cli/smartcontract/testdata/notifications/rpcbindings_extended.out @@ -116,25 +116,27 @@ type Actor interface { // Contract implements all contract methods. type Contract struct { actor Actor + hash util.Uint160 } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - return &Contract{actor} + var hash = Hash + return &Contract{actor, hash} } // Array creates a transaction invoking `array` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Array() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "array") + return c.actor.SendCall(c.hash, "array") } // ArrayTransaction creates a transaction invoking `array` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "array") + return c.actor.MakeCall(c.hash, "array") } // ArrayUnsigned creates a transaction invoking `array` method of the contract. @@ -142,21 +144,21 @@ func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) ArrayUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "array", nil) + return c.actor.MakeUnsignedCall(c.hash, "array", nil) } // CrazyMap creates a transaction invoking `crazyMap` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) CrazyMap() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "crazyMap") + return c.actor.SendCall(c.hash, "crazyMap") } // CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "crazyMap") + return c.actor.MakeCall(c.hash, "crazyMap") } // CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract. @@ -164,21 +166,21 @@ func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "crazyMap", nil) + return c.actor.MakeUnsignedCall(c.hash, "crazyMap", nil) } // Main creates a transaction invoking `main` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Main() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "main") + return c.actor.SendCall(c.hash, "main") } // MainTransaction creates a transaction invoking `main` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) MainTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "main") + return c.actor.MakeCall(c.hash, "main") } // MainUnsigned creates a transaction invoking `main` method of the contract. @@ -186,21 +188,21 @@ func (c *Contract) MainTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) MainUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "main", nil) + return c.actor.MakeUnsignedCall(c.hash, "main", nil) } // Struct creates a transaction invoking `struct` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Struct() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "struct") + return c.actor.SendCall(c.hash, "struct") } // StructTransaction creates a transaction invoking `struct` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) StructTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "struct") + return c.actor.MakeCall(c.hash, "struct") } // StructUnsigned creates a transaction invoking `struct` method of the contract. @@ -208,7 +210,7 @@ func (c *Contract) StructTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) StructUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "struct", nil) + return c.actor.MakeUnsignedCall(c.hash, "struct", nil) } // itemToCrazyStruct converts stack item into *CrazyStruct. diff --git a/cli/smartcontract/testdata/notifications/rpcbindings_guessed.out b/cli/smartcontract/testdata/notifications/rpcbindings_guessed.out index 883283d09..eb5c650b1 100755 --- a/cli/smartcontract/testdata/notifications/rpcbindings_guessed.out +++ b/cli/smartcontract/testdata/notifications/rpcbindings_guessed.out @@ -116,25 +116,27 @@ type Actor interface { // Contract implements all contract methods. type Contract struct { actor Actor + hash util.Uint160 } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - return &Contract{actor} + var hash = Hash + return &Contract{actor, hash} } // Array creates a transaction invoking `array` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Array() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "array") + return c.actor.SendCall(c.hash, "array") } // ArrayTransaction creates a transaction invoking `array` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "array") + return c.actor.MakeCall(c.hash, "array") } // ArrayUnsigned creates a transaction invoking `array` method of the contract. @@ -142,21 +144,21 @@ func (c *Contract) ArrayTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) ArrayUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "array", nil) + return c.actor.MakeUnsignedCall(c.hash, "array", nil) } // CrazyMap creates a transaction invoking `crazyMap` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) CrazyMap() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "crazyMap") + return c.actor.SendCall(c.hash, "crazyMap") } // CrazyMapTransaction creates a transaction invoking `crazyMap` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "crazyMap") + return c.actor.MakeCall(c.hash, "crazyMap") } // CrazyMapUnsigned creates a transaction invoking `crazyMap` method of the contract. @@ -164,21 +166,21 @@ func (c *Contract) CrazyMapTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) CrazyMapUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "crazyMap", nil) + return c.actor.MakeUnsignedCall(c.hash, "crazyMap", nil) } // Main creates a transaction invoking `main` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Main() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "main") + return c.actor.SendCall(c.hash, "main") } // MainTransaction creates a transaction invoking `main` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) MainTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "main") + return c.actor.MakeCall(c.hash, "main") } // MainUnsigned creates a transaction invoking `main` method of the contract. @@ -186,21 +188,21 @@ func (c *Contract) MainTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) MainUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "main", nil) + return c.actor.MakeUnsignedCall(c.hash, "main", nil) } // Struct creates a transaction invoking `struct` method of the contract. // This transaction is signed and immediately sent to the network. // The values returned are its hash, ValidUntilBlock value and error if any. func (c *Contract) Struct() (util.Uint256, uint32, error) { - return c.actor.SendCall(Hash, "struct") + return c.actor.SendCall(c.hash, "struct") } // StructTransaction creates a transaction invoking `struct` method of the contract. // This transaction is signed, but not sent to the network, instead it's // returned to the caller. func (c *Contract) StructTransaction() (*transaction.Transaction, error) { - return c.actor.MakeCall(Hash, "struct") + return c.actor.MakeCall(c.hash, "struct") } // StructUnsigned creates a transaction invoking `struct` method of the contract. @@ -208,7 +210,7 @@ func (c *Contract) StructTransaction() (*transaction.Transaction, error) { // Any fields of it that do not affect fees can be changed (ValidUntilBlock, // Nonce), fee values (NetworkFee, SystemFee) can be increased as well. func (c *Contract) StructUnsigned() (*transaction.Transaction, error) { - return c.actor.MakeUnsignedCall(Hash, "struct", nil) + return c.actor.MakeUnsignedCall(c.hash, "struct", nil) } // itemToLedgerBlock converts stack item into *LedgerBlock. diff --git a/cli/smartcontract/testdata/structs/rpcbindings.out b/cli/smartcontract/testdata/structs/rpcbindings.out index ba503be59..32acf3089 100644 --- a/cli/smartcontract/testdata/structs/rpcbindings.out +++ b/cli/smartcontract/testdata/structs/rpcbindings.out @@ -162,31 +162,33 @@ type Invoker interface { // ContractReader implements safe contract methods. type ContractReader struct { invoker Invoker + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{invoker} + var hash = Hash + return &ContractReader{invoker, hash} } // Block invokes `block` method of contract. func (c *ContractReader) Block(b *LedgerBlock) (*LedgerBlock, error) { - return itemToLedgerBlock(unwrap.Item(c.invoker.Call(Hash, "block", b))) + return itemToLedgerBlock(unwrap.Item(c.invoker.Call(c.hash, "block", b))) } // Contract invokes `contract` method of contract. func (c *ContractReader) Contract(mc *ManagementContract) (*ManagementContract, error) { - return itemToManagementContract(unwrap.Item(c.invoker.Call(Hash, "contract", mc))) + return itemToManagementContract(unwrap.Item(c.invoker.Call(c.hash, "contract", mc))) } // Struct invokes `struct` method of contract. func (c *ContractReader) Struct(s *StructsInternal) (*StructsInternal, error) { - return itemToStructsInternal(unwrap.Item(c.invoker.Call(Hash, "struct", s))) + return itemToStructsInternal(unwrap.Item(c.invoker.Call(c.hash, "struct", s))) } // Transaction invokes `transaction` method of contract. func (c *ContractReader) Transaction(t *LedgerTransaction) (*LedgerTransaction, error) { - return itemToLedgerTransaction(unwrap.Item(c.invoker.Call(Hash, "transaction", t))) + return itemToLedgerTransaction(unwrap.Item(c.invoker.Call(c.hash, "transaction", t))) } // itemToLedgerBlock converts stack item into *LedgerBlock. diff --git a/cli/smartcontract/testdata/structs/rpcbindings_dynamic_hash.out b/cli/smartcontract/testdata/structs/rpcbindings_dynamic_hash.out new file mode 100755 index 000000000..69558da30 --- /dev/null +++ b/cli/smartcontract/testdata/structs/rpcbindings_dynamic_hash.out @@ -0,0 +1,1622 @@ +// Package structs contains RPC wrappers for Types contract. +package structs + +import ( + "crypto/elliptic" + "errors" + "fmt" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/neorpc/result" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + "math/big" + "unicode/utf8" +) + +// LedgerBlock is a contract-specific ledger.Block type used by its methods. +type LedgerBlock struct { + Hash util.Uint256 + Version *big.Int + PrevHash util.Uint256 + MerkleRoot util.Uint256 + Timestamp *big.Int + Nonce *big.Int + Index *big.Int + NextConsensus util.Uint160 + TransactionsLength *big.Int +} + +// LedgerBlockSR is a contract-specific ledger.BlockSR type used by its methods. +type LedgerBlockSR struct { + Hash util.Uint256 + Version *big.Int + PrevHash util.Uint256 + MerkleRoot util.Uint256 + Timestamp *big.Int + Nonce *big.Int + Index *big.Int + NextConsensus util.Uint160 + TransactionsLength *big.Int + PrevStateRoot util.Uint256 +} + +// LedgerTransaction is a contract-specific ledger.Transaction type used by its methods. +type LedgerTransaction struct { + Hash util.Uint256 + Version *big.Int + Nonce *big.Int + Sender util.Uint160 + SysFee *big.Int + NetFee *big.Int + ValidUntilBlock *big.Int + Script []byte +} + +// LedgerTransactionSigner is a contract-specific ledger.TransactionSigner type used by its methods. +type LedgerTransactionSigner struct { + Account util.Uint160 + Scopes *big.Int + AllowedContracts []util.Uint160 + AllowedGroups keys.PublicKeys + Rules []*LedgerWitnessRule +} + +// LedgerWitnessCondition is a contract-specific ledger.WitnessCondition type used by its methods. +type LedgerWitnessCondition struct { + Type *big.Int + Value any +} + +// LedgerWitnessRule is a contract-specific ledger.WitnessRule type used by its methods. +type LedgerWitnessRule struct { + Action *big.Int + Condition *LedgerWitnessCondition +} + +// ManagementABI is a contract-specific management.ABI type used by its methods. +type ManagementABI struct { + Methods []*ManagementMethod + Events []*ManagementEvent +} + +// ManagementContract is a contract-specific management.Contract type used by its methods. +type ManagementContract struct { + ID *big.Int + UpdateCounter *big.Int + Hash util.Uint160 + NEF []byte + Manifest *ManagementManifest +} + +// ManagementEvent is a contract-specific management.Event type used by its methods. +type ManagementEvent struct { + Name string + Params []*ManagementParameter +} + +// ManagementGroup is a contract-specific management.Group type used by its methods. +type ManagementGroup struct { + PublicKey *keys.PublicKey + Signature []byte +} + +// ManagementManifest is a contract-specific management.Manifest type used by its methods. +type ManagementManifest struct { + Name string + Groups []*ManagementGroup + Features map[string]string + SupportedStandards []string + ABI *ManagementABI + Permissions []*ManagementPermission + Trusts []util.Uint160 + Extra any +} + +// ManagementMethod is a contract-specific management.Method type used by its methods. +type ManagementMethod struct { + Name string + Params []*ManagementParameter + ReturnType *big.Int + Offset *big.Int + Safe bool +} + +// ManagementParameter is a contract-specific management.Parameter type used by its methods. +type ManagementParameter struct { + Name string + Type *big.Int +} + +// ManagementPermission is a contract-specific management.Permission type used by its methods. +type ManagementPermission struct { + Contract util.Uint160 + Methods []string +} + +// StructsInternal is a contract-specific structs.Internal type used by its methods. +type StructsInternal struct { + Bool bool + Int *big.Int + Bytes []byte + String string + H160 util.Uint160 + H256 util.Uint256 + PK *keys.PublicKey + PubKey *keys.PublicKey + Sign []byte + ArrOfBytes [][]byte + ArrOfH160 []util.Uint160 + Map map[*big.Int]keys.PublicKeys + Struct *StructsInternal +} + +// Invoker is used by ContractReader to call various safe methods. +type Invoker interface { + Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error) +} + +// ContractReader implements safe contract methods. +type ContractReader struct { + invoker Invoker + hash util.Uint160 +} + +// NewReader creates an instance of ContractReader using provided contract hash and the given Invoker. +func NewReader(invoker Invoker, hash util.Uint160) *ContractReader { + return &ContractReader{invoker, hash} +} + +// Block invokes `block` method of contract. +func (c *ContractReader) Block(b *LedgerBlock) (*LedgerBlock, error) { + return itemToLedgerBlock(unwrap.Item(c.invoker.Call(c.hash, "block", b))) +} + +// Contract invokes `contract` method of contract. +func (c *ContractReader) Contract(mc *ManagementContract) (*ManagementContract, error) { + return itemToManagementContract(unwrap.Item(c.invoker.Call(c.hash, "contract", mc))) +} + +// Struct invokes `struct` method of contract. +func (c *ContractReader) Struct(s *StructsInternal) (*StructsInternal, error) { + return itemToStructsInternal(unwrap.Item(c.invoker.Call(c.hash, "struct", s))) +} + +// Transaction invokes `transaction` method of contract. +func (c *ContractReader) Transaction(t *LedgerTransaction) (*LedgerTransaction, error) { + return itemToLedgerTransaction(unwrap.Item(c.invoker.Call(c.hash, "transaction", t))) +} + +// itemToLedgerBlock converts stack item into *LedgerBlock. +func itemToLedgerBlock(item stackitem.Item, err error) (*LedgerBlock, error) { + if err != nil { + return nil, err + } + var res = new(LedgerBlock) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of LedgerBlock from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *LedgerBlock) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 9 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Hash, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Hash: %w", err) + } + + index++ + res.Version, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Version: %w", err) + } + + index++ + res.PrevHash, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field PrevHash: %w", err) + } + + index++ + res.MerkleRoot, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field MerkleRoot: %w", err) + } + + index++ + res.Timestamp, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Timestamp: %w", err) + } + + index++ + res.Nonce, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Nonce: %w", err) + } + + index++ + res.Index, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Index: %w", err) + } + + index++ + res.NextConsensus, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field NextConsensus: %w", err) + } + + index++ + res.TransactionsLength, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field TransactionsLength: %w", err) + } + + return nil +} + +// itemToLedgerBlockSR converts stack item into *LedgerBlockSR. +func itemToLedgerBlockSR(item stackitem.Item, err error) (*LedgerBlockSR, error) { + if err != nil { + return nil, err + } + var res = new(LedgerBlockSR) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of LedgerBlockSR from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *LedgerBlockSR) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 10 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Hash, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Hash: %w", err) + } + + index++ + res.Version, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Version: %w", err) + } + + index++ + res.PrevHash, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field PrevHash: %w", err) + } + + index++ + res.MerkleRoot, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field MerkleRoot: %w", err) + } + + index++ + res.Timestamp, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Timestamp: %w", err) + } + + index++ + res.Nonce, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Nonce: %w", err) + } + + index++ + res.Index, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Index: %w", err) + } + + index++ + res.NextConsensus, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field NextConsensus: %w", err) + } + + index++ + res.TransactionsLength, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field TransactionsLength: %w", err) + } + + index++ + res.PrevStateRoot, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field PrevStateRoot: %w", err) + } + + return nil +} + +// itemToLedgerTransaction converts stack item into *LedgerTransaction. +func itemToLedgerTransaction(item stackitem.Item, err error) (*LedgerTransaction, error) { + if err != nil { + return nil, err + } + var res = new(LedgerTransaction) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of LedgerTransaction from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *LedgerTransaction) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 8 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Hash, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Hash: %w", err) + } + + index++ + res.Version, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Version: %w", err) + } + + index++ + res.Nonce, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Nonce: %w", err) + } + + index++ + res.Sender, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Sender: %w", err) + } + + index++ + res.SysFee, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field SysFee: %w", err) + } + + index++ + res.NetFee, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field NetFee: %w", err) + } + + index++ + res.ValidUntilBlock, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field ValidUntilBlock: %w", err) + } + + index++ + res.Script, err = arr[index].TryBytes() + if err != nil { + return fmt.Errorf("field Script: %w", err) + } + + return nil +} + +// itemToLedgerTransactionSigner converts stack item into *LedgerTransactionSigner. +func itemToLedgerTransactionSigner(item stackitem.Item, err error) (*LedgerTransactionSigner, error) { + if err != nil { + return nil, err + } + var res = new(LedgerTransactionSigner) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of LedgerTransactionSigner from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *LedgerTransactionSigner) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 5 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Account, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Account: %w", err) + } + + index++ + res.Scopes, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Scopes: %w", err) + } + + index++ + res.AllowedContracts, err = func (item stackitem.Item) ([]util.Uint160, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]util.Uint160, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field AllowedContracts: %w", err) + } + + index++ + res.AllowedGroups, err = func (item stackitem.Item) (keys.PublicKeys, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make(keys.PublicKeys, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (*keys.PublicKey, error) { + b, err := item.TryBytes() + if err != nil { + return nil, err + } + k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256()) + if err != nil { + return nil, err + } + return k, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field AllowedGroups: %w", err) + } + + index++ + res.Rules, err = func (item stackitem.Item) ([]*LedgerWitnessRule, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*LedgerWitnessRule, len(arr)) + for i := range res { + res[i], err = itemToLedgerWitnessRule(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Rules: %w", err) + } + + return nil +} + +// itemToLedgerWitnessCondition converts stack item into *LedgerWitnessCondition. +func itemToLedgerWitnessCondition(item stackitem.Item, err error) (*LedgerWitnessCondition, error) { + if err != nil { + return nil, err + } + var res = new(LedgerWitnessCondition) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of LedgerWitnessCondition from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *LedgerWitnessCondition) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Type, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Type: %w", err) + } + + index++ + res.Value, err = arr[index].Value(), error(nil) + if err != nil { + return fmt.Errorf("field Value: %w", err) + } + + return nil +} + +// itemToLedgerWitnessRule converts stack item into *LedgerWitnessRule. +func itemToLedgerWitnessRule(item stackitem.Item, err error) (*LedgerWitnessRule, error) { + if err != nil { + return nil, err + } + var res = new(LedgerWitnessRule) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of LedgerWitnessRule from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *LedgerWitnessRule) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Action, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Action: %w", err) + } + + index++ + res.Condition, err = itemToLedgerWitnessCondition(arr[index], nil) + if err != nil { + return fmt.Errorf("field Condition: %w", err) + } + + return nil +} + +// itemToManagementABI converts stack item into *ManagementABI. +func itemToManagementABI(item stackitem.Item, err error) (*ManagementABI, error) { + if err != nil { + return nil, err + } + var res = new(ManagementABI) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementABI from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementABI) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Methods, err = func (item stackitem.Item) ([]*ManagementMethod, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*ManagementMethod, len(arr)) + for i := range res { + res[i], err = itemToManagementMethod(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Methods: %w", err) + } + + index++ + res.Events, err = func (item stackitem.Item) ([]*ManagementEvent, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*ManagementEvent, len(arr)) + for i := range res { + res[i], err = itemToManagementEvent(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Events: %w", err) + } + + return nil +} + +// itemToManagementContract converts stack item into *ManagementContract. +func itemToManagementContract(item stackitem.Item, err error) (*ManagementContract, error) { + if err != nil { + return nil, err + } + var res = new(ManagementContract) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementContract from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementContract) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 5 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.ID, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field ID: %w", err) + } + + index++ + res.UpdateCounter, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field UpdateCounter: %w", err) + } + + index++ + res.Hash, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Hash: %w", err) + } + + index++ + res.NEF, err = arr[index].TryBytes() + if err != nil { + return fmt.Errorf("field NEF: %w", err) + } + + index++ + res.Manifest, err = itemToManagementManifest(arr[index], nil) + if err != nil { + return fmt.Errorf("field Manifest: %w", err) + } + + return nil +} + +// itemToManagementEvent converts stack item into *ManagementEvent. +func itemToManagementEvent(item stackitem.Item, err error) (*ManagementEvent, error) { + if err != nil { + return nil, err + } + var res = new(ManagementEvent) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementEvent from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementEvent) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Name, err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Name: %w", err) + } + + index++ + res.Params, err = func (item stackitem.Item) ([]*ManagementParameter, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*ManagementParameter, len(arr)) + for i := range res { + res[i], err = itemToManagementParameter(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Params: %w", err) + } + + return nil +} + +// itemToManagementGroup converts stack item into *ManagementGroup. +func itemToManagementGroup(item stackitem.Item, err error) (*ManagementGroup, error) { + if err != nil { + return nil, err + } + var res = new(ManagementGroup) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementGroup from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementGroup) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.PublicKey, err = func (item stackitem.Item) (*keys.PublicKey, error) { + b, err := item.TryBytes() + if err != nil { + return nil, err + } + k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256()) + if err != nil { + return nil, err + } + return k, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field PublicKey: %w", err) + } + + index++ + res.Signature, err = arr[index].TryBytes() + if err != nil { + return fmt.Errorf("field Signature: %w", err) + } + + return nil +} + +// itemToManagementManifest converts stack item into *ManagementManifest. +func itemToManagementManifest(item stackitem.Item, err error) (*ManagementManifest, error) { + if err != nil { + return nil, err + } + var res = new(ManagementManifest) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementManifest from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementManifest) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 8 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Name, err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Name: %w", err) + } + + index++ + res.Groups, err = func (item stackitem.Item) ([]*ManagementGroup, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*ManagementGroup, len(arr)) + for i := range res { + res[i], err = itemToManagementGroup(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Groups: %w", err) + } + + index++ + res.Features, err = func (item stackitem.Item) (map[string]string, error) { + m, ok := item.Value().([]stackitem.MapElement) + if !ok { + return nil, fmt.Errorf("%s is not a map", item.Type().String()) + } + res := make(map[string]string) + for i := range m { + k, err := func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (m[i].Key) + if err != nil { + return nil, fmt.Errorf("key %d: %w", i, err) + } + v, err := func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (m[i].Value) + if err != nil { + return nil, fmt.Errorf("value %d: %w", i, err) + } + res[k] = v + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Features: %w", err) + } + + index++ + res.SupportedStandards, err = func (item stackitem.Item) ([]string, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]string, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field SupportedStandards: %w", err) + } + + index++ + res.ABI, err = itemToManagementABI(arr[index], nil) + if err != nil { + return fmt.Errorf("field ABI: %w", err) + } + + index++ + res.Permissions, err = func (item stackitem.Item) ([]*ManagementPermission, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*ManagementPermission, len(arr)) + for i := range res { + res[i], err = itemToManagementPermission(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Permissions: %w", err) + } + + index++ + res.Trusts, err = func (item stackitem.Item) ([]util.Uint160, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]util.Uint160, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Trusts: %w", err) + } + + index++ + res.Extra, err = arr[index].Value(), error(nil) + if err != nil { + return fmt.Errorf("field Extra: %w", err) + } + + return nil +} + +// itemToManagementMethod converts stack item into *ManagementMethod. +func itemToManagementMethod(item stackitem.Item, err error) (*ManagementMethod, error) { + if err != nil { + return nil, err + } + var res = new(ManagementMethod) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementMethod from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementMethod) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 5 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Name, err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Name: %w", err) + } + + index++ + res.Params, err = func (item stackitem.Item) ([]*ManagementParameter, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]*ManagementParameter, len(arr)) + for i := range res { + res[i], err = itemToManagementParameter(arr[i], nil) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Params: %w", err) + } + + index++ + res.ReturnType, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field ReturnType: %w", err) + } + + index++ + res.Offset, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Offset: %w", err) + } + + index++ + res.Safe, err = arr[index].TryBool() + if err != nil { + return fmt.Errorf("field Safe: %w", err) + } + + return nil +} + +// itemToManagementParameter converts stack item into *ManagementParameter. +func itemToManagementParameter(item stackitem.Item, err error) (*ManagementParameter, error) { + if err != nil { + return nil, err + } + var res = new(ManagementParameter) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementParameter from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementParameter) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Name, err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Name: %w", err) + } + + index++ + res.Type, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Type: %w", err) + } + + return nil +} + +// itemToManagementPermission converts stack item into *ManagementPermission. +func itemToManagementPermission(item stackitem.Item, err error) (*ManagementPermission, error) { + if err != nil { + return nil, err + } + var res = new(ManagementPermission) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of ManagementPermission from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *ManagementPermission) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 2 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Contract, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Contract: %w", err) + } + + index++ + res.Methods, err = func (item stackitem.Item) ([]string, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]string, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Methods: %w", err) + } + + return nil +} + +// itemToStructsInternal converts stack item into *StructsInternal. +func itemToStructsInternal(item stackitem.Item, err error) (*StructsInternal, error) { + if err != nil { + return nil, err + } + var res = new(StructsInternal) + err = res.FromStackItem(item) + return res, err +} + +// FromStackItem retrieves fields of StructsInternal from the given +// [stackitem.Item] or returns an error if it's not possible to do to so. +func (res *StructsInternal) FromStackItem(item stackitem.Item) error { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return errors.New("not an array") + } + if len(arr) != 13 { + return errors.New("wrong number of structure elements") + } + + var ( + index = -1 + err error + ) + index++ + res.Bool, err = arr[index].TryBool() + if err != nil { + return fmt.Errorf("field Bool: %w", err) + } + + index++ + res.Int, err = arr[index].TryInteger() + if err != nil { + return fmt.Errorf("field Int: %w", err) + } + + index++ + res.Bytes, err = arr[index].TryBytes() + if err != nil { + return fmt.Errorf("field Bytes: %w", err) + } + + index++ + res.String, err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field String: %w", err) + } + + index++ + res.H160, err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field H160: %w", err) + } + + index++ + res.H256, err = func (item stackitem.Item) (util.Uint256, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint256{}, err + } + u, err := util.Uint256DecodeBytesBE(b) + if err != nil { + return util.Uint256{}, err + } + return u, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field H256: %w", err) + } + + index++ + res.PK, err = func (item stackitem.Item) (*keys.PublicKey, error) { + b, err := item.TryBytes() + if err != nil { + return nil, err + } + k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256()) + if err != nil { + return nil, err + } + return k, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field PK: %w", err) + } + + index++ + res.PubKey, err = func (item stackitem.Item) (*keys.PublicKey, error) { + b, err := item.TryBytes() + if err != nil { + return nil, err + } + k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256()) + if err != nil { + return nil, err + } + return k, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field PubKey: %w", err) + } + + index++ + res.Sign, err = arr[index].TryBytes() + if err != nil { + return fmt.Errorf("field Sign: %w", err) + } + + index++ + res.ArrOfBytes, err = func (item stackitem.Item) ([][]byte, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([][]byte, len(arr)) + for i := range res { + res[i], err = arr[i].TryBytes() + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field ArrOfBytes: %w", err) + } + + index++ + res.ArrOfH160, err = func (item stackitem.Item) ([]util.Uint160, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]util.Uint160, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field ArrOfH160: %w", err) + } + + index++ + res.Map, err = func (item stackitem.Item) (map[*big.Int]keys.PublicKeys, error) { + m, ok := item.Value().([]stackitem.MapElement) + if !ok { + return nil, fmt.Errorf("%s is not a map", item.Type().String()) + } + res := make(map[*big.Int]keys.PublicKeys) + for i := range m { + k, err := m[i].Key.TryInteger() + if err != nil { + return nil, fmt.Errorf("key %d: %w", i, err) + } + v, err := func (item stackitem.Item) (keys.PublicKeys, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make(keys.PublicKeys, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (*keys.PublicKey, error) { + b, err := item.TryBytes() + if err != nil { + return nil, err + } + k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256()) + if err != nil { + return nil, err + } + return k, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (m[i].Value) + if err != nil { + return nil, fmt.Errorf("value %d: %w", i, err) + } + res[k] = v + } + return res, nil + } (arr[index]) + if err != nil { + return fmt.Errorf("field Map: %w", err) + } + + index++ + res.Struct, err = itemToStructsInternal(arr[index], nil) + if err != nil { + return fmt.Errorf("field Struct: %w", err) + } + + return nil +} diff --git a/cli/smartcontract/testdata/types/rpcbindings.out b/cli/smartcontract/testdata/types/rpcbindings.out index 49f6ac7e5..ee61838d1 100644 --- a/cli/smartcontract/testdata/types/rpcbindings.out +++ b/cli/smartcontract/testdata/types/rpcbindings.out @@ -24,11 +24,13 @@ type Invoker interface { // ContractReader implements safe contract methods. type ContractReader struct { invoker Invoker + hash util.Uint160 } // NewReader creates an instance of ContractReader using Hash and the given Invoker. func NewReader(invoker Invoker) *ContractReader { - return &ContractReader{invoker} + var hash = Hash + return &ContractReader{invoker, hash} } // AAAStrings invokes `aAAStrings` method of contract. @@ -86,7 +88,7 @@ func (c *ContractReader) AAAStrings(s [][][]string) ([][][]string, error) { } return res, nil } (item) - } (unwrap.Item(c.invoker.Call(Hash, "aAAStrings", s))) + } (unwrap.Item(c.invoker.Call(c.hash, "aAAStrings", s))) } // Any invokes `any` method of contract. @@ -96,7 +98,7 @@ func (c *ContractReader) Any(a any) (any, error) { return nil, err } return item.Value(), error(nil) - } (unwrap.Item(c.invoker.Call(Hash, "any", a))) + } (unwrap.Item(c.invoker.Call(c.hash, "any", a))) } // AnyMaps invokes `anyMaps` method of contract. @@ -124,27 +126,27 @@ func (c *ContractReader) AnyMaps(m map[*big.Int]any) (map[*big.Int]any, error) { } return res, nil } (item) - } (unwrap.Item(c.invoker.Call(Hash, "anyMaps", m))) + } (unwrap.Item(c.invoker.Call(c.hash, "anyMaps", m))) } // Bool invokes `bool` method of contract. func (c *ContractReader) Bool(b bool) (bool, error) { - return unwrap.Bool(c.invoker.Call(Hash, "bool", b)) + return unwrap.Bool(c.invoker.Call(c.hash, "bool", b)) } // Bools invokes `bools` method of contract. func (c *ContractReader) Bools(b []bool) ([]bool, error) { - return unwrap.ArrayOfBools(c.invoker.Call(Hash, "bools", b)) + return unwrap.ArrayOfBools(c.invoker.Call(c.hash, "bools", b)) } // Bytes invokes `bytes` method of contract. func (c *ContractReader) Bytes(b []byte) ([]byte, error) { - return unwrap.Bytes(c.invoker.Call(Hash, "bytes", b)) + return unwrap.Bytes(c.invoker.Call(c.hash, "bytes", b)) } // Bytess invokes `bytess` method of contract. func (c *ContractReader) Bytess(b [][]byte) ([][]byte, error) { - return unwrap.ArrayOfBytes(c.invoker.Call(Hash, "bytess", b)) + return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "bytess", b)) } // CrazyMaps invokes `crazyMaps` method of contract. @@ -235,37 +237,37 @@ func (c *ContractReader) CrazyMaps(m map[*big.Int][]map[string][]util.Uint160) ( } return res, nil } (item) - } (unwrap.Item(c.invoker.Call(Hash, "crazyMaps", m))) + } (unwrap.Item(c.invoker.Call(c.hash, "crazyMaps", m))) } // Hash160 invokes `hash160` method of contract. func (c *ContractReader) Hash160(h util.Uint160) (util.Uint160, error) { - return unwrap.Uint160(c.invoker.Call(Hash, "hash160", h)) + return unwrap.Uint160(c.invoker.Call(c.hash, "hash160", h)) } // Hash160s invokes `hash160s` method of contract. func (c *ContractReader) Hash160s(h []util.Uint160) ([]util.Uint160, error) { - return unwrap.ArrayOfUint160(c.invoker.Call(Hash, "hash160s", h)) + return unwrap.ArrayOfUint160(c.invoker.Call(c.hash, "hash160s", h)) } // Hash256 invokes `hash256` method of contract. func (c *ContractReader) Hash256(h util.Uint256) (util.Uint256, error) { - return unwrap.Uint256(c.invoker.Call(Hash, "hash256", h)) + return unwrap.Uint256(c.invoker.Call(c.hash, "hash256", h)) } // Hash256s invokes `hash256s` method of contract. func (c *ContractReader) Hash256s(h []util.Uint256) ([]util.Uint256, error) { - return unwrap.ArrayOfUint256(c.invoker.Call(Hash, "hash256s", h)) + return unwrap.ArrayOfUint256(c.invoker.Call(c.hash, "hash256s", h)) } // Int invokes `int` method of contract. func (c *ContractReader) Int(i *big.Int) (*big.Int, error) { - return unwrap.BigInt(c.invoker.Call(Hash, "int", i)) + return unwrap.BigInt(c.invoker.Call(c.hash, "int", i)) } // Ints invokes `ints` method of contract. func (c *ContractReader) Ints(i []*big.Int) ([]*big.Int, error) { - return unwrap.ArrayOfBigInts(c.invoker.Call(Hash, "ints", i)) + return unwrap.ArrayOfBigInts(c.invoker.Call(c.hash, "ints", i)) } // Maps invokes `maps` method of contract. @@ -311,35 +313,35 @@ func (c *ContractReader) Maps(m map[string]string) (map[string]string, error) { } return res, nil } (item) - } (unwrap.Item(c.invoker.Call(Hash, "maps", m))) + } (unwrap.Item(c.invoker.Call(c.hash, "maps", m))) } // PublicKey invokes `publicKey` method of contract. func (c *ContractReader) PublicKey(k *keys.PublicKey) (*keys.PublicKey, error) { - return unwrap.PublicKey(c.invoker.Call(Hash, "publicKey", k)) + return unwrap.PublicKey(c.invoker.Call(c.hash, "publicKey", k)) } // PublicKeys invokes `publicKeys` method of contract. func (c *ContractReader) PublicKeys(k keys.PublicKeys) (keys.PublicKeys, error) { - return unwrap.ArrayOfPublicKeys(c.invoker.Call(Hash, "publicKeys", k)) + return unwrap.ArrayOfPublicKeys(c.invoker.Call(c.hash, "publicKeys", k)) } // Signature invokes `signature` method of contract. func (c *ContractReader) Signature(s []byte) ([]byte, error) { - return unwrap.Bytes(c.invoker.Call(Hash, "signature", s)) + return unwrap.Bytes(c.invoker.Call(c.hash, "signature", s)) } // Signatures invokes `signatures` method of contract. func (c *ContractReader) Signatures(s [][]byte) ([][]byte, error) { - return unwrap.ArrayOfBytes(c.invoker.Call(Hash, "signatures", s)) + return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "signatures", s)) } // String invokes `string` method of contract. func (c *ContractReader) String(s string) (string, error) { - return unwrap.UTF8String(c.invoker.Call(Hash, "string", s)) + return unwrap.UTF8String(c.invoker.Call(c.hash, "string", s)) } // Strings invokes `strings` method of contract. func (c *ContractReader) Strings(s []string) ([]string, error) { - return unwrap.ArrayOfUTF8Strings(c.invoker.Call(Hash, "strings", s)) + return unwrap.ArrayOfUTF8Strings(c.invoker.Call(c.hash, "strings", s)) } diff --git a/cli/smartcontract/testdata/types/rpcbindings_dynamic_hash.out b/cli/smartcontract/testdata/types/rpcbindings_dynamic_hash.out new file mode 100755 index 000000000..1075e3260 --- /dev/null +++ b/cli/smartcontract/testdata/types/rpcbindings_dynamic_hash.out @@ -0,0 +1,343 @@ +// Package types contains RPC wrappers for Types contract. +package types + +import ( + "errors" + "fmt" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/neorpc/result" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + "math/big" + "unicode/utf8" +) + +// Invoker is used by ContractReader to call various safe methods. +type Invoker interface { + Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error) +} + +// ContractReader implements safe contract methods. +type ContractReader struct { + invoker Invoker + hash util.Uint160 +} + +// NewReader creates an instance of ContractReader using provided contract hash and the given Invoker. +func NewReader(invoker Invoker, hash util.Uint160) *ContractReader { + return &ContractReader{invoker, hash} +} + +// AAAStrings invokes `aAAStrings` method of contract. +func (c *ContractReader) AAAStrings(s [][][]string) ([][][]string, error) { + return func (item stackitem.Item, err error) ([][][]string, error) { + if err != nil { + return nil, err + } + return func (item stackitem.Item) ([][][]string, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([][][]string, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) ([][]string, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([][]string, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) ([]string, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]string, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (item) + } (unwrap.Item(c.invoker.Call(c.hash, "aAAStrings", s))) +} + +// Any invokes `any` method of contract. +func (c *ContractReader) Any(a any) (any, error) { + return func (item stackitem.Item, err error) (any, error) { + if err != nil { + return nil, err + } + return item.Value(), error(nil) + } (unwrap.Item(c.invoker.Call(c.hash, "any", a))) +} + +// AnyMaps invokes `anyMaps` method of contract. +func (c *ContractReader) AnyMaps(m map[*big.Int]any) (map[*big.Int]any, error) { + return func (item stackitem.Item, err error) (map[*big.Int]any, error) { + if err != nil { + return nil, err + } + return func (item stackitem.Item) (map[*big.Int]any, error) { + m, ok := item.Value().([]stackitem.MapElement) + if !ok { + return nil, fmt.Errorf("%s is not a map", item.Type().String()) + } + res := make(map[*big.Int]any) + for i := range m { + k, err := m[i].Key.TryInteger() + if err != nil { + return nil, fmt.Errorf("key %d: %w", i, err) + } + v, err := m[i].Value.Value(), error(nil) + if err != nil { + return nil, fmt.Errorf("value %d: %w", i, err) + } + res[k] = v + } + return res, nil + } (item) + } (unwrap.Item(c.invoker.Call(c.hash, "anyMaps", m))) +} + +// Bool invokes `bool` method of contract. +func (c *ContractReader) Bool(b bool) (bool, error) { + return unwrap.Bool(c.invoker.Call(c.hash, "bool", b)) +} + +// Bools invokes `bools` method of contract. +func (c *ContractReader) Bools(b []bool) ([]bool, error) { + return unwrap.ArrayOfBools(c.invoker.Call(c.hash, "bools", b)) +} + +// Bytes invokes `bytes` method of contract. +func (c *ContractReader) Bytes(b []byte) ([]byte, error) { + return unwrap.Bytes(c.invoker.Call(c.hash, "bytes", b)) +} + +// Bytess invokes `bytess` method of contract. +func (c *ContractReader) Bytess(b [][]byte) ([][]byte, error) { + return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "bytess", b)) +} + +// CrazyMaps invokes `crazyMaps` method of contract. +func (c *ContractReader) CrazyMaps(m map[*big.Int][]map[string][]util.Uint160) (map[*big.Int][]map[string][]util.Uint160, error) { + return func (item stackitem.Item, err error) (map[*big.Int][]map[string][]util.Uint160, error) { + if err != nil { + return nil, err + } + return func (item stackitem.Item) (map[*big.Int][]map[string][]util.Uint160, error) { + m, ok := item.Value().([]stackitem.MapElement) + if !ok { + return nil, fmt.Errorf("%s is not a map", item.Type().String()) + } + res := make(map[*big.Int][]map[string][]util.Uint160) + for i := range m { + k, err := m[i].Key.TryInteger() + if err != nil { + return nil, fmt.Errorf("key %d: %w", i, err) + } + v, err := func (item stackitem.Item) ([]map[string][]util.Uint160, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]map[string][]util.Uint160, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (map[string][]util.Uint160, error) { + m, ok := item.Value().([]stackitem.MapElement) + if !ok { + return nil, fmt.Errorf("%s is not a map", item.Type().String()) + } + res := make(map[string][]util.Uint160) + for i := range m { + k, err := func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (m[i].Key) + if err != nil { + return nil, fmt.Errorf("key %d: %w", i, err) + } + v, err := func (item stackitem.Item) ([]util.Uint160, error) { + arr, ok := item.Value().([]stackitem.Item) + if !ok { + return nil, errors.New("not an array") + } + res := make([]util.Uint160, len(arr)) + for i := range res { + res[i], err = func (item stackitem.Item) (util.Uint160, error) { + b, err := item.TryBytes() + if err != nil { + return util.Uint160{}, err + } + u, err := util.Uint160DecodeBytesBE(b) + if err != nil { + return util.Uint160{}, err + } + return u, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (m[i].Value) + if err != nil { + return nil, fmt.Errorf("value %d: %w", i, err) + } + res[k] = v + } + return res, nil + } (arr[i]) + if err != nil { + return nil, fmt.Errorf("item %d: %w", i, err) + } + } + return res, nil + } (m[i].Value) + if err != nil { + return nil, fmt.Errorf("value %d: %w", i, err) + } + res[k] = v + } + return res, nil + } (item) + } (unwrap.Item(c.invoker.Call(c.hash, "crazyMaps", m))) +} + +// Hash160 invokes `hash160` method of contract. +func (c *ContractReader) Hash160(h util.Uint160) (util.Uint160, error) { + return unwrap.Uint160(c.invoker.Call(c.hash, "hash160", h)) +} + +// Hash160s invokes `hash160s` method of contract. +func (c *ContractReader) Hash160s(h []util.Uint160) ([]util.Uint160, error) { + return unwrap.ArrayOfUint160(c.invoker.Call(c.hash, "hash160s", h)) +} + +// Hash256 invokes `hash256` method of contract. +func (c *ContractReader) Hash256(h util.Uint256) (util.Uint256, error) { + return unwrap.Uint256(c.invoker.Call(c.hash, "hash256", h)) +} + +// Hash256s invokes `hash256s` method of contract. +func (c *ContractReader) Hash256s(h []util.Uint256) ([]util.Uint256, error) { + return unwrap.ArrayOfUint256(c.invoker.Call(c.hash, "hash256s", h)) +} + +// Int invokes `int` method of contract. +func (c *ContractReader) Int(i *big.Int) (*big.Int, error) { + return unwrap.BigInt(c.invoker.Call(c.hash, "int", i)) +} + +// Ints invokes `ints` method of contract. +func (c *ContractReader) Ints(i []*big.Int) ([]*big.Int, error) { + return unwrap.ArrayOfBigInts(c.invoker.Call(c.hash, "ints", i)) +} + +// Maps invokes `maps` method of contract. +func (c *ContractReader) Maps(m map[string]string) (map[string]string, error) { + return func (item stackitem.Item, err error) (map[string]string, error) { + if err != nil { + return nil, err + } + return func (item stackitem.Item) (map[string]string, error) { + m, ok := item.Value().([]stackitem.MapElement) + if !ok { + return nil, fmt.Errorf("%s is not a map", item.Type().String()) + } + res := make(map[string]string) + for i := range m { + k, err := func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (m[i].Key) + if err != nil { + return nil, fmt.Errorf("key %d: %w", i, err) + } + v, err := func (item stackitem.Item) (string, error) { + b, err := item.TryBytes() + if err != nil { + return "", err + } + if !utf8.Valid(b) { + return "", errors.New("not a UTF-8 string") + } + return string(b), nil + } (m[i].Value) + if err != nil { + return nil, fmt.Errorf("value %d: %w", i, err) + } + res[k] = v + } + return res, nil + } (item) + } (unwrap.Item(c.invoker.Call(c.hash, "maps", m))) +} + +// PublicKey invokes `publicKey` method of contract. +func (c *ContractReader) PublicKey(k *keys.PublicKey) (*keys.PublicKey, error) { + return unwrap.PublicKey(c.invoker.Call(c.hash, "publicKey", k)) +} + +// PublicKeys invokes `publicKeys` method of contract. +func (c *ContractReader) PublicKeys(k keys.PublicKeys) (keys.PublicKeys, error) { + return unwrap.ArrayOfPublicKeys(c.invoker.Call(c.hash, "publicKeys", k)) +} + +// Signature invokes `signature` method of contract. +func (c *ContractReader) Signature(s []byte) ([]byte, error) { + return unwrap.Bytes(c.invoker.Call(c.hash, "signature", s)) +} + +// Signatures invokes `signatures` method of contract. +func (c *ContractReader) Signatures(s [][]byte) ([][]byte, error) { + return unwrap.ArrayOfBytes(c.invoker.Call(c.hash, "signatures", s)) +} + +// String invokes `string` method of contract. +func (c *ContractReader) String(s string) (string, error) { + return unwrap.UTF8String(c.invoker.Call(c.hash, "string", s)) +} + +// Strings invokes `strings` method of contract. +func (c *ContractReader) Strings(s []string) ([]string, error) { + return unwrap.ArrayOfUTF8Strings(c.invoker.Call(c.hash, "strings", s)) +} diff --git a/cli/smartcontract/testdata/verifyrpc/verify.go b/cli/smartcontract/testdata/verifyrpc/verify.go index 3a01b990c..7aa5904f0 100644 --- a/cli/smartcontract/testdata/verifyrpc/verify.go +++ b/cli/smartcontract/testdata/verifyrpc/verify.go @@ -32,15 +32,17 @@ type Actor interface { // Contract implements all contract methods. type Contract struct { actor Actor + hash util.Uint160 } // New creates an instance of Contract using Hash and the given Actor. func New(actor Actor) *Contract { - return &Contract{actor} + var hash = Hash + return &Contract{actor, hash} } func scriptForVerify() ([]byte, error) { - return smartcontract.CreateCallWithAssertScript(Hash, "verify") + return smartcontract.CreateCallWithAssertScript(c.hash, "verify") } // Verify creates a transaction invoking `verify` method of the contract. diff --git a/pkg/smartcontract/binding/generate.go b/pkg/smartcontract/binding/generate.go index bd7d42cbc..7e6716908 100644 --- a/pkg/smartcontract/binding/generate.go +++ b/pkg/smartcontract/binding/generate.go @@ -48,8 +48,10 @@ const Hash = "{{ .Hash }}" type ( // Config contains parameter for the generated binding. Config struct { - Package string `yaml:"package,omitempty"` - Manifest *manifest.Manifest `yaml:"-"` + Package string `yaml:"package,omitempty"` + Manifest *manifest.Manifest `yaml:"-"` + // Hash denotes the contract hash and is allowed to be empty for RPC bindings + // generation (if not provided by the user). Hash util.Uint160 `yaml:"hash,omitempty"` Overrides map[string]Override `yaml:"overrides,omitempty"` CallFlags map[string]callflag.CallFlag `yaml:"callflags,omitempty"` @@ -169,9 +171,11 @@ func scTypeToGo(name string, typ smartcontract.ParamType, cfg *Config) (string, // and type conversion function. It assumes manifest to be present in the // configuration and assumes it to be correct (passing IsValid check). func TemplateFromManifest(cfg Config, scTypeConverter func(string, smartcontract.ParamType, *Config) (string, string)) ContractTmpl { - hStr := "" - for _, b := range cfg.Hash.BytesBE() { - hStr += fmt.Sprintf("\\x%02x", b) + var hStr string + if !cfg.Hash.Equals(util.Uint160{}) { + for _, b := range cfg.Hash.BytesBE() { + hStr += fmt.Sprintf("\\x%02x", b) + } } ctr := ContractTmpl{ diff --git a/pkg/smartcontract/rpcbinding/binding.go b/pkg/smartcontract/rpcbinding/binding.go index caf6f4397..d1e835f31 100644 --- a/pkg/smartcontract/rpcbinding/binding.go +++ b/pkg/smartcontract/rpcbinding/binding.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/smartcontract/binding" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest/standard" + "github.com/nspcc-dev/neo-go/pkg/util" ) // The set of constants containing parts of RPC binding template. Each block of code @@ -39,10 +40,10 @@ func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}} } return {{addIndent (etTypeConverter .ExtendedReturn "item") "\t"}} } ( {{- end -}} {{if .ItemTo -}} itemTo{{ .ItemTo }}( {{- end -}} - unwrap.{{.Unwrapper}}(c.invoker.Call(Hash, "{{ .NameABI }}" + unwrap.{{.Unwrapper}}(c.invoker.Call(c.hash, "{{ .NameABI }}" {{- range $arg := .Arguments -}}, {{.Name}}{{end -}} )) {{- if or .ItemTo (eq .Unwrapper "Item") -}} ) {{- end}} {{- else -}} (*result.Invoke, error) { - c.invoker.Call(Hash, "{{ .NameABI }}" + c.invoker.Call(c.hash, "{{ .NameABI }}" {{- range $arg := .Arguments -}}, {{.Name}}{{end}}) {{- end}} } @@ -53,7 +54,7 @@ func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}} // number of result items from the iterator right in the VM and return them to // you. It's only limited by VM stack and GAS available for RPC invocations. func (c *ContractReader) {{.Name}}Expanded({{range $index, $arg := .Arguments}}{{.Name}} {{.Type}}, {{end}}_numOfIteratorItems int) ([]stackitem.Item, error) { - return unwrap.Array(c.invoker.CallAndExpandIterator(Hash, "{{.NameABI}}", _numOfIteratorItems{{range $arg := .Arguments}}, {{.Name}}{{end}})) + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "{{.NameABI}}", _numOfIteratorItems{{range $arg := .Arguments}}, {{.Name}}{{end}})) } {{ end }}{{ end }}` methodDefinition = `{{ define "METHOD" }}{{ if eq .ReturnType "bool"}} @@ -61,7 +62,7 @@ func scriptFor{{.Name}}({{range $index, $arg := .Arguments -}} {{- if ne $index 0}}, {{end}} {{- .Name}} {{.Type}} {{- end}}) ([]byte, error) { - return smartcontract.CreateCallWithAssertScript(Hash, "{{ .NameABI }}"{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}}) + return smartcontract.CreateCallWithAssertScript(c.hash, "{{ .NameABI }}"{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}}) } {{ end }} // {{.Name}} {{.Comment}} @@ -71,7 +72,7 @@ func (c *Contract) {{.Name}}({{range $index, $arg := .Arguments -}} {{- if ne $index 0}}, {{end}} {{- .Name}} {{.Type}} {{- end}}) (util.Uint256, uint32, error) { - {{if ne .ReturnType "bool"}}return c.actor.SendCall(Hash, "{{ .NameABI }}" + {{if ne .ReturnType "bool"}}return c.actor.SendCall(c.hash, "{{ .NameABI }}" {{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}}){{else}}script, err := scriptFor{{.Name}}({{- range $index, $arg := .Arguments -}}{{- if ne $index 0}}, {{end}}{{.Name}}{{end}}) if err != nil { return util.Uint256{}, 0, err @@ -86,7 +87,7 @@ func (c *Contract) {{.Name}}Transaction({{range $index, $arg := .Arguments -}} {{- if ne $index 0}}, {{end}} {{- .Name}} {{.Type}} {{- end}}) (*transaction.Transaction, error) { - {{if ne .ReturnType "bool"}}return c.actor.MakeCall(Hash, "{{ .NameABI }}" + {{if ne .ReturnType "bool"}}return c.actor.MakeCall(c.hash, "{{ .NameABI }}" {{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}}){{else}}script, err := scriptFor{{.Name}}({{- range $index, $arg := .Arguments -}}{{- if ne $index 0}}, {{end}}{{.Name}}{{end}}) if err != nil { return nil, err @@ -102,7 +103,7 @@ func (c *Contract) {{.Name}}Unsigned({{range $index, $arg := .Arguments -}} {{- if ne $index 0}}, {{end}} {{- .Name}} {{.Type}} {{- end}}) (*transaction.Transaction, error) { - {{if ne .ReturnType "bool"}}return c.actor.MakeUnsignedCall(Hash, "{{ .NameABI }}", nil + {{if ne .ReturnType "bool"}}return c.actor.MakeUnsignedCall(c.hash, "{{ .NameABI }}", nil {{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}}){{else}}script, err := scriptFor{{.Name}}({{- range $index, $arg := .Arguments -}}{{- if ne $index 0}}, {{end}}{{.Name}}{{end}}) if err != nil { return nil, err @@ -117,10 +118,11 @@ package {{.PackageName}} import ( {{range $m := .Imports}} "{{ $m }}" {{end}}) - +{{if len .Hash}} // Hash contains contract hash. var Hash = {{ .Hash }} -{{ range $name, $typ := .NamedTypes }} +{{end -}} +{{- range $name, $typ := .NamedTypes }} // {{toTypeName $name}} is a contract-specific {{$name}} type used by its methods. type {{toTypeName $name}} struct { {{- range $m := $typ.Fields}} @@ -175,6 +177,7 @@ type ContractReader struct { {{if .IsNep17}}nep17.TokenReader {{end -}} invoker Invoker + hash util.Uint160 } {{end -}} {{- if .HasWriter}} @@ -189,37 +192,44 @@ type Contract struct { {{if .IsNep17}}nep17.TokenWriter {{end -}} actor Actor + hash util.Uint160 } {{end -}} {{- if .HasReader}} -// NewReader creates an instance of ContractReader using Hash and the given Invoker. -func NewReader(invoker Invoker) *ContractReader { +// NewReader creates an instance of ContractReader using {{if len .Hash -}}Hash{{- else -}}provided contract hash{{- end}} and the given Invoker. +func NewReader(invoker Invoker{{- if not (len .Hash) -}}, hash util.Uint160{{- end -}}) *ContractReader { + {{if len .Hash -}} + var hash = Hash + {{end -}} return &ContractReader{ - {{- if .IsNep11D}}*nep11.NewDivisibleReader(invoker, Hash), {{end}} - {{- if .IsNep11ND}}*nep11.NewNonDivisibleReader(invoker, Hash), {{end}} - {{- if .IsNep17}}*nep17.NewReader(invoker, Hash), {{end -}} - invoker} + {{- if .IsNep11D}}*nep11.NewDivisibleReader(invoker, hash), {{end}} + {{- if .IsNep11ND}}*nep11.NewNonDivisibleReader(invoker, hash), {{end}} + {{- if .IsNep17}}*nep17.NewReader(invoker, hash), {{end -}} + invoker, hash} } {{end -}} {{- if .HasWriter}} -// New creates an instance of Contract using Hash and the given Actor. -func New(actor Actor) *Contract { - {{if .IsNep11D}}var nep11dt = nep11.NewDivisible(actor, Hash) +// New creates an instance of Contract using {{if len .Hash -}}Hash{{- else -}}provided contract hash{{- end}} and the given Actor. +func New(actor Actor{{- if not (len .Hash) -}}, hash util.Uint160{{- end -}}) *Contract { + {{if len .Hash -}} + var hash = Hash {{end -}} - {{if .IsNep11ND}}var nep11ndt = nep11.NewNonDivisible(actor, Hash) + {{if .IsNep11D}}var nep11dt = nep11.NewDivisible(actor, hash) {{end -}} - {{if .IsNep17}}var nep17t = nep17.New(actor, Hash) + {{if .IsNep11ND}}var nep11ndt = nep11.NewNonDivisible(actor, hash) + {{end -}} + {{if .IsNep17}}var nep17t = nep17.New(actor, hash) {{end -}} return &Contract{ {{- if .HasReader}}ContractReader{ {{- if .IsNep11D}}nep11dt.DivisibleReader, {{end -}} {{- if .IsNep11ND}}nep11ndt.NonDivisibleReader, {{end -}} {{- if .IsNep17}}nep17t.TokenReader, {{end -}} - actor}, {{end -}} + actor, hash}, {{end -}} {{- if .IsNep11D}}nep11dt.DivisibleWriter, {{end -}} {{- if .IsNep11ND}}nep11ndt.BaseWriter, {{end -}} {{- if .IsNep17}}nep17t.TokenWriter, {{end -}} - actor} + actor, hash} } {{end -}} {{- range $m := .SafeMethods }}{{template "SAFEMETHOD" $m }}{{ end -}} @@ -660,7 +670,9 @@ func scTemplateToRPC(cfg binding.Config, ctr ContractTmpl, imports map[string]st for i := range ctr.Imports { imports[ctr.Imports[i]] = struct{}{} } - ctr.Hash = fmt.Sprintf("%#v", cfg.Hash) + if !cfg.Hash.Equals(util.Uint160{}) { + ctr.Hash = fmt.Sprintf("%#v", cfg.Hash) + } for i := 0; i < len(ctr.Methods); i++ { abim := cfg.Manifest.ABI.GetMethod(ctr.Methods[i].NameABI, len(ctr.Methods[i].Arguments)) if abim.Safe {