Merge pull request #2778 from nspcc-dev/rpc-wrapper-writer
State-changing methods in RPC wrappers
This commit is contained in:
commit
695f00cfeb
10 changed files with 891 additions and 95 deletions
|
@ -294,6 +294,7 @@ package myspacecontract
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"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/rpcclient/unwrap"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -328,34 +329,37 @@ func TestGenerateRPCBindings(t *testing.T) {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Commands = []cli.Command{generateWrapperCmd, generateRPCWrapperCmd}
|
app.Commands = []cli.Command{generateWrapperCmd, generateRPCWrapperCmd}
|
||||||
|
|
||||||
outFile := filepath.Join(tmpDir, "out.go")
|
var checkBinding = func(manifest string, hash string, good string) {
|
||||||
require.NoError(t, app.Run([]string{"", "generate-rpcwrapper",
|
t.Run(manifest, func(t *testing.T) {
|
||||||
"--manifest", filepath.Join("testdata", "nex", "nex.manifest.json"),
|
outFile := filepath.Join(tmpDir, "out.go")
|
||||||
"--out", outFile,
|
require.NoError(t, app.Run([]string{"", "generate-rpcwrapper",
|
||||||
"--hash", "0xa2a67f09e8cf22c6bfd5cea24adc0f4bf0a11aa8",
|
"--manifest", manifest,
|
||||||
}))
|
"--out", outFile,
|
||||||
|
"--hash", hash,
|
||||||
|
}))
|
||||||
|
|
||||||
data, err := os.ReadFile(outFile)
|
data, err := os.ReadFile(outFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
data = bytes.ReplaceAll(data, []byte("\r"), []byte{}) // Windows.
|
data = bytes.ReplaceAll(data, []byte("\r"), []byte{}) // Windows.
|
||||||
expected, err := os.ReadFile(filepath.Join("testdata", "nex", "nex.go"))
|
expected, err := os.ReadFile(good)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
expected = bytes.ReplaceAll(expected, []byte("\r"), []byte{}) // Windows.
|
expected = bytes.ReplaceAll(expected, []byte("\r"), []byte{}) // Windows.
|
||||||
require.Equal(t, string(expected), string(data))
|
require.Equal(t, string(expected), string(data))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
require.NoError(t, app.Run([]string{"", "generate-rpcwrapper",
|
checkBinding(filepath.Join("testdata", "nex", "nex.manifest.json"),
|
||||||
"--manifest", filepath.Join("testdata", "nameservice", "nns.manifest.json"),
|
"0xa2a67f09e8cf22c6bfd5cea24adc0f4bf0a11aa8",
|
||||||
"--out", outFile,
|
filepath.Join("testdata", "nex", "nex.go"))
|
||||||
"--hash", "0x50ac1c37690cc2cfc594472833cf57505d5f46de",
|
checkBinding(filepath.Join("testdata", "nameservice", "nns.manifest.json"),
|
||||||
}))
|
"0x50ac1c37690cc2cfc594472833cf57505d5f46de",
|
||||||
|
filepath.Join("testdata", "nameservice", "nns.go"))
|
||||||
data, err = os.ReadFile(outFile)
|
checkBinding(filepath.Join("testdata", "gas", "gas.manifest.json"),
|
||||||
require.NoError(t, err)
|
"0xd2a4cff31913016155e38e474a2c06d08be276cf",
|
||||||
data = bytes.ReplaceAll(data, []byte("\r"), []byte{}) // Windows.
|
filepath.Join("testdata", "gas", "gas.go"))
|
||||||
expected, err = os.ReadFile(filepath.Join("testdata", "nameservice", "nns.go"))
|
checkBinding(filepath.Join("testdata", "verifyrpc", "verify.manifest.json"),
|
||||||
require.NoError(t, err)
|
"0x00112233445566778899aabbccddeeff00112233",
|
||||||
expected = bytes.ReplaceAll(expected, []byte("\r"), []byte{}) // Windows.
|
filepath.Join("testdata", "verifyrpc", "verify.go"))
|
||||||
require.Equal(t, string(expected), string(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerate_Errors(t *testing.T) {
|
func TestGenerate_Errors(t *testing.T) {
|
||||||
|
|
47
cli/smartcontract/testdata/gas/gas.go
vendored
Normal file
47
cli/smartcontract/testdata/gas/gas.go
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Package gastoken contains RPC wrappers for GasToken contract.
|
||||||
|
package gastoken
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hash contains contract hash.
|
||||||
|
var Hash = util.Uint160{0xcf, 0x76, 0xe2, 0x8b, 0xd0, 0x6, 0x2c, 0x4a, 0x47, 0x8e, 0xe3, 0x55, 0x61, 0x1, 0x13, 0x19, 0xf3, 0xcf, 0xa4, 0xd2}
|
||||||
|
|
||||||
|
// Invoker is used by ContractReader to call various safe methods.
|
||||||
|
type Invoker interface {
|
||||||
|
nep17.Invoker
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actor is used by Contract to call state-changing methods.
|
||||||
|
type Actor interface {
|
||||||
|
Invoker
|
||||||
|
|
||||||
|
nep17.Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContractReader implements safe contract methods.
|
||||||
|
type ContractReader struct {
|
||||||
|
nep17.TokenReader
|
||||||
|
invoker Invoker
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contract implements all contract methods.
|
||||||
|
type Contract struct {
|
||||||
|
ContractReader
|
||||||
|
nep17.TokenWriter
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
||||||
|
func NewReader(invoker Invoker) *ContractReader {
|
||||||
|
return &ContractReader{*nep17.NewReader(invoker, Hash), invoker}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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}
|
||||||
|
}
|
||||||
|
|
1
cli/smartcontract/testdata/gas/gas.manifest.json
vendored
Normal file
1
cli/smartcontract/testdata/gas/gas.manifest.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"name":"GasToken","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"balanceOf","parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","offset":0,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":7,"safe":true},{"name":"symbol","parameters":[],"returntype":"String","offset":14,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":21,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":28,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":null}
|
245
cli/smartcontract/testdata/nameservice/nns.go
vendored
245
cli/smartcontract/testdata/nameservice/nns.go
vendored
|
@ -2,9 +2,10 @@
|
||||||
package nameservice
|
package nameservice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -16,7 +17,20 @@ var Hash = util.Uint160{0xde, 0x46, 0x5f, 0x5d, 0x50, 0x57, 0xcf, 0x33, 0x28, 0x
|
||||||
// Invoker is used by ContractReader to call various safe methods.
|
// Invoker is used by ContractReader to call various safe methods.
|
||||||
type Invoker interface {
|
type Invoker interface {
|
||||||
nep11.Invoker
|
nep11.Invoker
|
||||||
Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error)
|
}
|
||||||
|
|
||||||
|
// Actor is used by Contract to call state-changing methods.
|
||||||
|
type Actor interface {
|
||||||
|
Invoker
|
||||||
|
|
||||||
|
nep11.Actor
|
||||||
|
|
||||||
|
MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeRun(script []byte) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
|
||||||
|
SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error)
|
||||||
|
SendRun(script []byte) (util.Uint256, uint32, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContractReader implements safe contract methods.
|
// ContractReader implements safe contract methods.
|
||||||
|
@ -25,11 +39,24 @@ type ContractReader struct {
|
||||||
invoker Invoker
|
invoker Invoker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contract implements all contract methods.
|
||||||
|
type Contract struct {
|
||||||
|
ContractReader
|
||||||
|
nep11.BaseWriter
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
||||||
func NewReader(invoker Invoker) *ContractReader {
|
func NewReader(invoker Invoker) *ContractReader {
|
||||||
return &ContractReader{*nep11.NewNonDivisibleReader(invoker, Hash), invoker}
|
return &ContractReader{*nep11.NewNonDivisibleReader(invoker, Hash), invoker}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Roots invokes `roots` method of contract.
|
// Roots invokes `roots` method of contract.
|
||||||
func (c *ContractReader) Roots() (stackitem.Item, error) {
|
func (c *ContractReader) Roots() (stackitem.Item, error) {
|
||||||
|
@ -60,3 +87,217 @@ func (c *ContractReader) GetAllRecords(name string) (stackitem.Item, error) {
|
||||||
func (c *ContractReader) Resolve(name string, typev *big.Int) (string, error) {
|
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(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUnsigned creates a transaction invoking `update` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRootUnsigned creates a transaction invoking `addRoot` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 []interface{}) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendCall(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 []interface{}) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeCall(Hash, "setPrice", priceList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPriceUnsigned creates a transaction invoking `setPrice` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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 []interface{}) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedCall(Hash, "setPrice", nil, priceList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func scriptForRegister(name string, owner util.Uint160) ([]byte, error) {
|
||||||
|
return smartcontract.CreateCallWithAssertScript(Hash, "register", name, owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register creates a transaction invoking `register` 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) Register(name string, owner util.Uint160) (util.Uint256, uint32, error) {
|
||||||
|
script, err := scriptForRegister(name, owner)
|
||||||
|
if err != nil {
|
||||||
|
return util.Uint256{}, 0, err
|
||||||
|
}
|
||||||
|
return c.actor.SendRun(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterTransaction creates a transaction invoking `register` method of the contract.
|
||||||
|
// This transaction is signed, but not sent to the network, instead it's
|
||||||
|
// returned to the caller.
|
||||||
|
func (c *Contract) RegisterTransaction(name string, owner util.Uint160) (*transaction.Transaction, error) {
|
||||||
|
script, err := scriptForRegister(name, owner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.actor.MakeRun(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUnsigned creates a transaction invoking `register` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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) RegisterUnsigned(name string, owner util.Uint160) (*transaction.Transaction, error) {
|
||||||
|
script, err := scriptForRegister(name, owner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.actor.MakeUnsignedRun(script, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renew 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(name string) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendCall(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenewUnsigned creates a transaction invoking `renew` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renew_2Unsigned creates a transaction invoking `renew` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAdminUnsigned creates a transaction invoking `setAdmin` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRecordUnsigned creates a transaction invoking `setRecord` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecordUnsigned creates a transaction invoking `deleteRecord` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
184
cli/smartcontract/testdata/nex/nex.go
vendored
184
cli/smartcontract/testdata/nex/nex.go
vendored
|
@ -2,8 +2,8 @@
|
||||||
package nextoken
|
package nextoken
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -16,7 +16,20 @@ var Hash = util.Uint160{0xa8, 0x1a, 0xa1, 0xf0, 0x4b, 0xf, 0xdc, 0x4a, 0xa2, 0xc
|
||||||
// Invoker is used by ContractReader to call various safe methods.
|
// Invoker is used by ContractReader to call various safe methods.
|
||||||
type Invoker interface {
|
type Invoker interface {
|
||||||
nep17.Invoker
|
nep17.Invoker
|
||||||
Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error)
|
}
|
||||||
|
|
||||||
|
// Actor is used by Contract to call state-changing methods.
|
||||||
|
type Actor interface {
|
||||||
|
Invoker
|
||||||
|
|
||||||
|
nep17.Actor
|
||||||
|
|
||||||
|
MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeRun(script []byte) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
|
||||||
|
SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error)
|
||||||
|
SendRun(script []byte) (util.Uint256, uint32, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContractReader implements safe contract methods.
|
// ContractReader implements safe contract methods.
|
||||||
|
@ -25,11 +38,24 @@ type ContractReader struct {
|
||||||
invoker Invoker
|
invoker Invoker
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contract implements all contract methods.
|
||||||
|
type Contract struct {
|
||||||
|
ContractReader
|
||||||
|
nep17.TokenWriter
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
||||||
func NewReader(invoker Invoker) *ContractReader {
|
func NewReader(invoker Invoker) *ContractReader {
|
||||||
return &ContractReader{*nep17.NewReader(invoker, Hash), invoker}
|
return &ContractReader{*nep17.NewReader(invoker, Hash), invoker}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Cap invokes `cap` method of contract.
|
// Cap invokes `cap` method of contract.
|
||||||
func (c *ContractReader) Cap() (*big.Int, error) {
|
func (c *ContractReader) Cap() (*big.Int, error) {
|
||||||
|
@ -50,3 +76,157 @@ func (c *ContractReader) GetOwner() (util.Uint160, error) {
|
||||||
func (c *ContractReader) TotalMinted() (*big.Int, error) {
|
func (c *ContractReader) TotalMinted() (*big.Int, error) {
|
||||||
return unwrap.BigInt(c.invoker.Call(Hash, "totalMinted"))
|
return unwrap.BigInt(c.invoker.Call(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeMinterUnsigned creates a transaction invoking `changeMinter` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeOwnerUnsigned creates a transaction invoking `changeOwner` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DestroyUnsigned creates a transaction invoking `destroy` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxSupplyUnsigned creates a transaction invoking `maxSupply` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 interface{}) (util.Uint256, uint32, error) {
|
||||||
|
return c.actor.SendCall(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 interface{}) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeCall(Hash, "mint", from, to, amount, swapId, signature, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MintUnsigned creates a transaction invoking `mint` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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 interface{}) (*transaction.Transaction, error) {
|
||||||
|
return c.actor.MakeUnsignedCall(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUnsigned creates a transaction invoking `update` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateCapUnsigned creates a transaction invoking `updateCap` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
70
cli/smartcontract/testdata/verifyrpc/verify.go
vendored
Normal file
70
cli/smartcontract/testdata/verifyrpc/verify.go
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Package verify contains RPC wrappers for verify contract.
|
||||||
|
package verify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hash contains contract hash.
|
||||||
|
var Hash = util.Uint160{0x33, 0x22, 0x11, 0x0, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x0}
|
||||||
|
|
||||||
|
// Actor is used by Contract to call state-changing methods.
|
||||||
|
type Actor interface {
|
||||||
|
MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeRun(script []byte) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
|
||||||
|
SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error)
|
||||||
|
SendRun(script []byte) (util.Uint256, uint32, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contract implements all contract methods.
|
||||||
|
type Contract struct {
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates an instance of Contract using Hash and the given Actor.
|
||||||
|
func New(actor Actor) *Contract {
|
||||||
|
return &Contract{actor}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func scriptForVerify() ([]byte, error) {
|
||||||
|
return smartcontract.CreateCallWithAssertScript(Hash, "verify")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify creates a transaction invoking `verify` 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) Verify() (util.Uint256, uint32, error) {
|
||||||
|
script, err := scriptForVerify()
|
||||||
|
if err != nil {
|
||||||
|
return util.Uint256{}, 0, err
|
||||||
|
}
|
||||||
|
return c.actor.SendRun(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyTransaction creates a transaction invoking `verify` method of the contract.
|
||||||
|
// This transaction is signed, but not sent to the network, instead it's
|
||||||
|
// returned to the caller.
|
||||||
|
func (c *Contract) VerifyTransaction() (*transaction.Transaction, error) {
|
||||||
|
script, err := scriptForVerify()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.actor.MakeRun(script)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyUnsigned creates a transaction invoking `verify` method of the contract.
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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) VerifyUnsigned() (*transaction.Transaction, error) {
|
||||||
|
script, err := scriptForVerify()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.actor.MakeUnsignedRun(script, nil)
|
||||||
|
}
|
79
cli/smartcontract/testdata/verifyrpc/verify.manifest.json
vendored
Executable file
79
cli/smartcontract/testdata/verifyrpc/verify.manifest.json
vendored
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
"groups" : [],
|
||||||
|
"extra" : null,
|
||||||
|
"supportedstandards" : [],
|
||||||
|
"name" : "verify",
|
||||||
|
"trusts" : [],
|
||||||
|
"permissions" : [
|
||||||
|
{
|
||||||
|
"methods" : "*",
|
||||||
|
"contract" : "*"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"abi" : {
|
||||||
|
"methods" : [
|
||||||
|
{
|
||||||
|
"safe" : false,
|
||||||
|
"offset" : 0,
|
||||||
|
"parameters" : [],
|
||||||
|
"name" : "verify",
|
||||||
|
"returntype" : "Boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"returntype" : "Void",
|
||||||
|
"safe" : false,
|
||||||
|
"offset" : 5,
|
||||||
|
"parameters" : [
|
||||||
|
{
|
||||||
|
"type" : "Hash160",
|
||||||
|
"name" : "from"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "Integer",
|
||||||
|
"name" : "amount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "Any",
|
||||||
|
"name" : "data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name" : "onNEP17Payment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"returntype" : "Void",
|
||||||
|
"safe" : false,
|
||||||
|
"offset" : 5,
|
||||||
|
"parameters" : [
|
||||||
|
{
|
||||||
|
"type" : "Hash160",
|
||||||
|
"name" : "from"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "Integer",
|
||||||
|
"name" : "amount"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "ByteArray",
|
||||||
|
"name" : "tokenid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "Any",
|
||||||
|
"name" : "data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name" : "onNEP11Payment"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"events" : [
|
||||||
|
{
|
||||||
|
"parameters" : [
|
||||||
|
{
|
||||||
|
"type" : "Array",
|
||||||
|
"name" : "args"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name" : "Hello world!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -436,12 +436,20 @@ $ ./bin/neo-go contract generate-wrapper --manifest manifest.json --config contr
|
||||||
|
|
||||||
### Generating RPC contract bindings
|
### Generating RPC contract bindings
|
||||||
To simplify interacting with the contract via RPC you can generate
|
To simplify interacting with the contract via RPC you can generate
|
||||||
contract-specific RPC bindings with the "generate-rpcwrapper" command. At the
|
contract-specific RPC bindings with the "generate-rpcwrapper" command. It
|
||||||
moment it only works for safe (read-only) methods. If your contract is NEP-11
|
generates ContractReader structure for safe methods that accept appropriate
|
||||||
or NEP-17 that's autodetected and an appropriate package is included as
|
data for input and return things returned by the contract. State-changing
|
||||||
well. Notice that the type data available in the manifest is limited, so in
|
methods are contained in Contract structure with each contract method
|
||||||
some cases the interface generated may use generic stackitem types. Iterators
|
represented by three wrapper methods that create/send transaction with a
|
||||||
are not supported yet.
|
script performing appropriate action. This script invokes contract method and
|
||||||
|
does not do anything else unless the method's returned value is of a boolean
|
||||||
|
type, in this case an ASSERT is added to script making it fail when the method
|
||||||
|
returns false.
|
||||||
|
|
||||||
|
If your contract is NEP-11 or NEP-17 that's autodetected and an appropriate
|
||||||
|
package is included as well. Notice that the type data available in the
|
||||||
|
manifest is limited, so in some cases the interface generated may use generic
|
||||||
|
stackitem types. Iterators are not supported yet.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
|
$ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176
|
||||||
|
|
|
@ -16,10 +16,17 @@ type DivisibleReader struct {
|
||||||
BaseReader
|
BaseReader
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divisible is a state-changing interface for divisible NEP-11 contract.
|
// DivisibleWriter is a state-changing interface for divisible NEP-11 contract.
|
||||||
|
// It's mostly useful not directly, but as a reusable layer for higher-level
|
||||||
|
// structures.
|
||||||
|
type DivisibleWriter struct {
|
||||||
|
BaseWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Divisible is a full reader interface for divisible NEP-11 contract.
|
||||||
type Divisible struct {
|
type Divisible struct {
|
||||||
DivisibleReader
|
DivisibleReader
|
||||||
BaseWriter
|
DivisibleWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnerIterator is used for iterating over OwnerOf (for divisible NFTs) results.
|
// OwnerIterator is used for iterating over OwnerOf (for divisible NFTs) results.
|
||||||
|
@ -38,7 +45,7 @@ func NewDivisibleReader(invoker Invoker, hash util.Uint160) *DivisibleReader {
|
||||||
// NewDivisible creates an instance of Divisible for a contract
|
// NewDivisible creates an instance of Divisible for a contract
|
||||||
// with the given hash using the given actor.
|
// with the given hash using the given actor.
|
||||||
func NewDivisible(actor Actor, hash util.Uint160) *Divisible {
|
func NewDivisible(actor Actor, hash util.Uint160) *Divisible {
|
||||||
return &Divisible{*NewDivisibleReader(actor, hash), BaseWriter{hash, actor}}
|
return &Divisible{*NewDivisibleReader(actor, hash), DivisibleWriter{BaseWriter{hash, actor}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnerOf returns returns an iterator that allows to walk through all owners of
|
// OwnerOf returns returns an iterator that allows to walk through all owners of
|
||||||
|
@ -72,7 +79,7 @@ func (t *DivisibleReader) BalanceOfD(owner util.Uint160, token []byte) (*big.Int
|
||||||
// method call using the given parameters and checks for this call result,
|
// method call using the given parameters and checks for this call result,
|
||||||
// failing the transaction if it's not true. The returned values are transaction
|
// failing the transaction if it's not true. The returned values are transaction
|
||||||
// hash, its ValidUntilBlock value and an error if any.
|
// hash, its ValidUntilBlock value and an error if any.
|
||||||
func (t *Divisible) TransferD(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (util.Uint256, uint32, error) {
|
func (t *DivisibleWriter) TransferD(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (util.Uint256, uint32, error) {
|
||||||
script, err := t.transferScript(from, to, amount, id, data)
|
script, err := t.transferScript(from, to, amount, id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint256{}, 0, err
|
return util.Uint256{}, 0, err
|
||||||
|
@ -85,7 +92,7 @@ func (t *Divisible) TransferD(from util.Uint160, to util.Uint160, amount *big.In
|
||||||
// `transfer` method call using the given parameters and checks for this call
|
// `transfer` method call using the given parameters and checks for this call
|
||||||
// result, failing the transaction if it's not true. This transaction is signed,
|
// result, failing the transaction if it's not true. This transaction is signed,
|
||||||
// but not sent to the network, instead it's returned to the caller.
|
// but not sent to the network, instead it's returned to the caller.
|
||||||
func (t *Divisible) TransferDTransaction(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (*transaction.Transaction, error) {
|
func (t *DivisibleWriter) TransferDTransaction(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (*transaction.Transaction, error) {
|
||||||
script, err := t.transferScript(from, to, amount, id, data)
|
script, err := t.transferScript(from, to, amount, id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -98,7 +105,7 @@ func (t *Divisible) TransferDTransaction(from util.Uint160, to util.Uint160, amo
|
||||||
// `transfer` method call using the given parameters and checks for this call
|
// `transfer` method call using the given parameters and checks for this call
|
||||||
// result, failing the transaction if it's not true. This transaction is not
|
// result, failing the transaction if it's not true. This transaction is not
|
||||||
// signed and just returned to the caller.
|
// signed and just returned to the caller.
|
||||||
func (t *Divisible) TransferDUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (*transaction.Transaction, error) {
|
func (t *DivisibleWriter) TransferDUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (*transaction.Transaction, error) {
|
||||||
script, err := t.transferScript(from, to, amount, id, data)
|
script, err := t.transferScript(from, to, amount, id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const srcTmpl = `
|
const srcTmpl = `
|
||||||
{{- define "METHOD" -}}
|
{{- define "SAFEMETHOD" -}}
|
||||||
// {{.Name}} {{.Comment}}
|
// {{.Name}} {{.Comment}}
|
||||||
func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}}
|
func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
{{- if ne $index 0}}, {{end}}
|
{{- if ne $index 0}}, {{end}}
|
||||||
|
@ -26,6 +26,60 @@ func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
}
|
}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
{{- define "METHOD" -}}
|
||||||
|
{{- if eq .ReturnType "bool"}}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}})
|
||||||
|
}
|
||||||
|
|
||||||
|
{{end}}// {{.Name}} {{.Comment}}
|
||||||
|
// 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) {{.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 }}"
|
||||||
|
{{- 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
|
||||||
|
}
|
||||||
|
return c.actor.SendRun(script){{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Name}}Transaction {{.Comment}}
|
||||||
|
// This transaction is signed, but not sent to the network, instead it's
|
||||||
|
// returned to the caller.
|
||||||
|
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 }}"
|
||||||
|
{{- 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
|
||||||
|
}
|
||||||
|
return c.actor.MakeRun(script){{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Name}}Unsigned {{.Comment}}
|
||||||
|
// This transaction is not signed, it's simply returned to the caller.
|
||||||
|
// 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) {{.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
|
||||||
|
{{- 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
|
||||||
|
}
|
||||||
|
return c.actor.MakeUnsignedRun(script, nil){{end}}
|
||||||
|
}
|
||||||
|
{{- end -}}
|
||||||
// Package {{.PackageName}} contains RPC wrappers for {{.ContractName}} contract.
|
// Package {{.PackageName}} contains RPC wrappers for {{.ContractName}} contract.
|
||||||
package {{.PackageName}}
|
package {{.PackageName}}
|
||||||
|
|
||||||
|
@ -36,16 +90,37 @@ import (
|
||||||
// Hash contains contract hash.
|
// Hash contains contract hash.
|
||||||
var Hash = {{ .Hash }}
|
var Hash = {{ .Hash }}
|
||||||
|
|
||||||
// Invoker is used by ContractReader to call various safe methods.
|
{{if .HasReader}}// Invoker is used by ContractReader to call various safe methods.
|
||||||
type Invoker interface {
|
type Invoker interface {
|
||||||
{{if or .IsNep11D .IsNep11ND}}nep11.Invoker
|
{{if or .IsNep11D .IsNep11ND}} nep11.Invoker
|
||||||
{{end -}}
|
{{else if .IsNep17}} nep17.Invoker
|
||||||
{{if .IsNep17}}nep17.Invoker
|
{{else if len .SafeMethods}} Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error)
|
||||||
{{end -}}
|
{{end -}}
|
||||||
Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContractReader implements safe contract methods.
|
{{end -}}
|
||||||
|
{{if .HasWriter}}// Actor is used by Contract to call state-changing methods.
|
||||||
|
type Actor interface {
|
||||||
|
{{- if .HasReader}}
|
||||||
|
Invoker
|
||||||
|
{{end}}
|
||||||
|
{{- if or .IsNep11D .IsNep11ND}}
|
||||||
|
nep11.Actor
|
||||||
|
{{else if .IsNep17}}
|
||||||
|
nep17.Actor
|
||||||
|
{{end}}
|
||||||
|
{{- if len .Methods}}
|
||||||
|
MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeRun(script []byte) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error)
|
||||||
|
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
|
||||||
|
SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error)
|
||||||
|
SendRun(script []byte) (util.Uint256, uint32, error)
|
||||||
|
{{end -}}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{end -}}
|
||||||
|
{{if .HasReader}}// ContractReader implements safe contract methods.
|
||||||
type ContractReader struct {
|
type ContractReader struct {
|
||||||
{{if .IsNep11D}}nep11.DivisibleReader
|
{{if .IsNep11D}}nep11.DivisibleReader
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
@ -56,7 +131,22 @@ type ContractReader struct {
|
||||||
invoker Invoker
|
invoker Invoker
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
{{end -}}
|
||||||
|
{{if .HasWriter}}// Contract implements all contract methods.
|
||||||
|
type Contract struct {
|
||||||
|
{{if .HasReader}}ContractReader
|
||||||
|
{{end -}}
|
||||||
|
{{if .IsNep11D}}nep11.DivisibleWriter
|
||||||
|
{{end -}}
|
||||||
|
{{if .IsNep11ND}}nep11.BaseWriter
|
||||||
|
{{end -}}
|
||||||
|
{{if .IsNep17}}nep17.TokenWriter
|
||||||
|
{{end -}}
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
{{end -}}
|
||||||
|
{{if .HasReader}}// NewReader creates an instance of ContractReader using Hash and the given Invoker.
|
||||||
func NewReader(invoker Invoker) *ContractReader {
|
func NewReader(invoker Invoker) *ContractReader {
|
||||||
return &ContractReader{
|
return &ContractReader{
|
||||||
{{- if .IsNep11D}}*nep11.NewDivisibleReader(invoker, Hash), {{end}}
|
{{- if .IsNep11D}}*nep11.NewDivisibleReader(invoker, Hash), {{end}}
|
||||||
|
@ -65,7 +155,32 @@ func NewReader(invoker Invoker) *ContractReader {
|
||||||
invoker}
|
invoker}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{range $m := .Methods}}
|
{{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)
|
||||||
|
{{end -}}
|
||||||
|
{{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 -}}
|
||||||
|
{{- if .IsNep11D}}nep11dt.DivisibleWriter, {{end -}}
|
||||||
|
{{- if .IsNep11ND}}nep11ndt.BaseWriter, {{end -}}
|
||||||
|
{{- if .IsNep17}}nep17t.TokenWriter, {{end -}}
|
||||||
|
actor}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{end -}}
|
||||||
|
{{range $m := .SafeMethods}}
|
||||||
|
{{template "SAFEMETHOD" $m }}
|
||||||
|
{{end}}
|
||||||
|
{{- range $m := .Methods}}
|
||||||
{{template "METHOD" $m }}
|
{{template "METHOD" $m }}
|
||||||
{{end}}`
|
{{end}}`
|
||||||
|
|
||||||
|
@ -74,9 +189,15 @@ var srcTemplate = template.Must(template.New("generate").Parse(srcTmpl))
|
||||||
type (
|
type (
|
||||||
ContractTmpl struct {
|
ContractTmpl struct {
|
||||||
binding.ContractTmpl
|
binding.ContractTmpl
|
||||||
|
|
||||||
|
SafeMethods []binding.MethodTmpl
|
||||||
|
|
||||||
IsNep11D bool
|
IsNep11D bool
|
||||||
IsNep11ND bool
|
IsNep11ND bool
|
||||||
IsNep17 bool
|
IsNep17 bool
|
||||||
|
|
||||||
|
HasReader bool
|
||||||
|
HasWriter bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,19 +208,58 @@ func NewConfig() binding.Config {
|
||||||
|
|
||||||
// Generate writes Go file containing smartcontract bindings to the `cfg.Output`.
|
// Generate writes Go file containing smartcontract bindings to the `cfg.Output`.
|
||||||
func Generate(cfg binding.Config) error {
|
func Generate(cfg binding.Config) error {
|
||||||
|
// Avoid changing *cfg.Manifest.
|
||||||
|
mfst := *cfg.Manifest
|
||||||
|
mfst.ABI.Methods = make([]manifest.Method, len(mfst.ABI.Methods))
|
||||||
|
copy(mfst.ABI.Methods, cfg.Manifest.ABI.Methods)
|
||||||
|
cfg.Manifest = &mfst
|
||||||
|
|
||||||
|
var imports = make(map[string]struct{})
|
||||||
|
var ctr ContractTmpl
|
||||||
|
|
||||||
|
// Strip standard methods from NEP-XX packages.
|
||||||
|
for _, std := range cfg.Manifest.SupportedStandards {
|
||||||
|
if std == manifest.NEP11StandardName {
|
||||||
|
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"] = struct{}{}
|
||||||
|
if standard.ComplyABI(cfg.Manifest, standard.Nep11Divisible) == nil {
|
||||||
|
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep11Divisible)
|
||||||
|
ctr.IsNep11D = true
|
||||||
|
} else if standard.ComplyABI(cfg.Manifest, standard.Nep11NonDivisible) == nil {
|
||||||
|
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep11NonDivisible)
|
||||||
|
ctr.IsNep11ND = true
|
||||||
|
}
|
||||||
|
break // Can't be NEP-17 at the same time.
|
||||||
|
}
|
||||||
|
if std == manifest.NEP17StandardName && standard.ComplyABI(cfg.Manifest, standard.Nep17) == nil {
|
||||||
|
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep17)
|
||||||
|
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"] = struct{}{}
|
||||||
|
ctr.IsNep17 = true
|
||||||
|
break // Can't be NEP-11 at the same time.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnNepXXPayment handlers normally can't be called directly.
|
||||||
|
if standard.ComplyABI(cfg.Manifest, standard.Nep11Payable) == nil {
|
||||||
|
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep11Payable)
|
||||||
|
}
|
||||||
|
if standard.ComplyABI(cfg.Manifest, standard.Nep17Payable) == nil {
|
||||||
|
mfst.ABI.Methods = dropStdMethods(mfst.ABI.Methods, standard.Nep17Payable)
|
||||||
|
}
|
||||||
|
|
||||||
bctr, err := binding.TemplateFromManifest(cfg, scTypeToGo)
|
bctr, err := binding.TemplateFromManifest(cfg, scTypeToGo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctr := scTemplateToRPC(cfg, bctr)
|
ctr.ContractTmpl = bctr
|
||||||
|
ctr = scTemplateToRPC(cfg, ctr, imports)
|
||||||
|
|
||||||
return srcTemplate.Execute(cfg.Output, ctr)
|
return srcTemplate.Execute(cfg.Output, ctr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dropManifestMethods(meths []binding.MethodTmpl, manifested []manifest.Method) []binding.MethodTmpl {
|
func dropManifestMethods(meths []manifest.Method, manifested []manifest.Method) []manifest.Method {
|
||||||
for _, m := range manifested {
|
for _, m := range manifested {
|
||||||
for i := 0; i < len(meths); i++ {
|
for i := 0; i < len(meths); i++ {
|
||||||
if meths[i].NameABI == m.Name && len(meths[i].Arguments) == len(m.Parameters) {
|
if meths[i].Name == m.Name && len(meths[i].Parameters) == len(m.Parameters) {
|
||||||
meths = append(meths[:i], meths[i+1:]...)
|
meths = append(meths[:i], meths[i+1:]...)
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
|
@ -108,7 +268,7 @@ func dropManifestMethods(meths []binding.MethodTmpl, manifested []manifest.Metho
|
||||||
return meths
|
return meths
|
||||||
}
|
}
|
||||||
|
|
||||||
func dropStdMethods(meths []binding.MethodTmpl, std *standard.Standard) []binding.MethodTmpl {
|
func dropStdMethods(meths []manifest.Method, std *standard.Standard) []manifest.Method {
|
||||||
meths = dropManifestMethods(meths, std.Manifest.ABI.Methods)
|
meths = dropManifestMethods(meths, std.Manifest.ABI.Methods)
|
||||||
if std.Optional != nil {
|
if std.Optional != nil {
|
||||||
meths = dropManifestMethods(meths, std.Optional)
|
meths = dropManifestMethods(meths, std.Optional)
|
||||||
|
@ -152,71 +312,70 @@ func scTypeToGo(name string, typ smartcontract.ParamType, overrides map[string]b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func scTemplateToRPC(cfg binding.Config, bctr binding.ContractTmpl) ContractTmpl {
|
func scTemplateToRPC(cfg binding.Config, ctr ContractTmpl, imports map[string]struct{}) ContractTmpl {
|
||||||
var imports = make(map[string]struct{})
|
|
||||||
var ctr = ContractTmpl{ContractTmpl: bctr}
|
|
||||||
for i := range ctr.Imports {
|
for i := range ctr.Imports {
|
||||||
imports[ctr.Imports[i]] = struct{}{}
|
imports[ctr.Imports[i]] = struct{}{}
|
||||||
}
|
}
|
||||||
ctr.Hash = fmt.Sprintf("%#v", cfg.Hash)
|
ctr.Hash = fmt.Sprintf("%#v", cfg.Hash)
|
||||||
for _, std := range cfg.Manifest.SupportedStandards {
|
|
||||||
if std == manifest.NEP11StandardName {
|
|
||||||
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"] = struct{}{}
|
|
||||||
if standard.ComplyABI(cfg.Manifest, standard.Nep11Divisible) == nil {
|
|
||||||
ctr.Methods = dropStdMethods(ctr.Methods, standard.Nep11Divisible)
|
|
||||||
ctr.IsNep11D = true
|
|
||||||
} else if standard.ComplyABI(cfg.Manifest, standard.Nep11NonDivisible) == nil {
|
|
||||||
ctr.Methods = dropStdMethods(ctr.Methods, standard.Nep11NonDivisible)
|
|
||||||
ctr.IsNep11ND = true
|
|
||||||
}
|
|
||||||
break // Can't be NEP-17 at the same time.
|
|
||||||
}
|
|
||||||
if std == manifest.NEP17StandardName && standard.ComplyABI(cfg.Manifest, standard.Nep17) == nil {
|
|
||||||
ctr.Methods = dropStdMethods(ctr.Methods, standard.Nep17)
|
|
||||||
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"] = struct{}{}
|
|
||||||
ctr.IsNep17 = true
|
|
||||||
break // Can't be NEP-11 at the same time.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < len(ctr.Methods); i++ {
|
for i := 0; i < len(ctr.Methods); i++ {
|
||||||
abim := cfg.Manifest.ABI.GetMethod(ctr.Methods[i].NameABI, len(ctr.Methods[i].Arguments))
|
abim := cfg.Manifest.ABI.GetMethod(ctr.Methods[i].NameABI, len(ctr.Methods[i].Arguments))
|
||||||
if !abim.Safe {
|
if abim.Safe {
|
||||||
|
ctr.SafeMethods = append(ctr.SafeMethods, ctr.Methods[i])
|
||||||
ctr.Methods = append(ctr.Methods[:i], ctr.Methods[i+1:]...)
|
ctr.Methods = append(ctr.Methods[:i], ctr.Methods[i+1:]...)
|
||||||
i--
|
i--
|
||||||
|
} else {
|
||||||
|
ctr.Methods[i].Comment = fmt.Sprintf("creates a transaction invoking `%s` method of the contract.", ctr.Methods[i].NameABI)
|
||||||
|
if ctr.Methods[i].ReturnType == "bool" {
|
||||||
|
imports["github.com/nspcc-dev/neo-go/pkg/smartcontract"] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We're misusing CallFlag field for function name here.
|
// We're misusing CallFlag field for function name here.
|
||||||
for i := range ctr.Methods {
|
for i := range ctr.SafeMethods {
|
||||||
switch ctr.Methods[i].ReturnType {
|
switch ctr.SafeMethods[i].ReturnType {
|
||||||
case "interface{}":
|
case "interface{}":
|
||||||
imports["github.com/nspcc-dev/neo-go/pkg/vm/stackitem"] = struct{}{}
|
imports["github.com/nspcc-dev/neo-go/pkg/vm/stackitem"] = struct{}{}
|
||||||
ctr.Methods[i].ReturnType = "stackitem.Item"
|
ctr.SafeMethods[i].ReturnType = "stackitem.Item"
|
||||||
ctr.Methods[i].CallFlag = "Item"
|
ctr.SafeMethods[i].CallFlag = "Item"
|
||||||
case "bool":
|
case "bool":
|
||||||
ctr.Methods[i].CallFlag = "Bool"
|
ctr.SafeMethods[i].CallFlag = "Bool"
|
||||||
case "*big.Int":
|
case "*big.Int":
|
||||||
ctr.Methods[i].CallFlag = "BigInt"
|
ctr.SafeMethods[i].CallFlag = "BigInt"
|
||||||
case "string":
|
case "string":
|
||||||
ctr.Methods[i].CallFlag = "UTF8String"
|
ctr.SafeMethods[i].CallFlag = "UTF8String"
|
||||||
case "util.Uint160":
|
case "util.Uint160":
|
||||||
ctr.Methods[i].CallFlag = "Uint160"
|
ctr.SafeMethods[i].CallFlag = "Uint160"
|
||||||
case "util.Uint256":
|
case "util.Uint256":
|
||||||
ctr.Methods[i].CallFlag = "Uint256"
|
ctr.SafeMethods[i].CallFlag = "Uint256"
|
||||||
case "*keys.PublicKey":
|
case "*keys.PublicKey":
|
||||||
ctr.Methods[i].CallFlag = "PublicKey"
|
ctr.SafeMethods[i].CallFlag = "PublicKey"
|
||||||
case "[]byte":
|
case "[]byte":
|
||||||
ctr.Methods[i].CallFlag = "Bytes"
|
ctr.SafeMethods[i].CallFlag = "Bytes"
|
||||||
case "[]interface{}":
|
case "[]interface{}":
|
||||||
imports["github.com/nspcc-dev/neo-go/pkg/vm/stackitem"] = struct{}{}
|
imports["github.com/nspcc-dev/neo-go/pkg/vm/stackitem"] = struct{}{}
|
||||||
ctr.Methods[i].ReturnType = "[]stackitem.Item"
|
ctr.SafeMethods[i].ReturnType = "[]stackitem.Item"
|
||||||
ctr.Methods[i].CallFlag = "Array"
|
ctr.SafeMethods[i].CallFlag = "Array"
|
||||||
case "*stackitem.Map":
|
case "*stackitem.Map":
|
||||||
ctr.Methods[i].CallFlag = "Map"
|
ctr.SafeMethods[i].CallFlag = "Map"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"] = struct{}{}
|
imports["github.com/nspcc-dev/neo-go/pkg/util"] = struct{}{}
|
||||||
imports["github.com/nspcc-dev/neo-go/pkg/neorpc/result"] = struct{}{}
|
if len(ctr.SafeMethods) > 0 {
|
||||||
|
imports["github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"] = struct{}{}
|
||||||
|
if !(ctr.IsNep17 || ctr.IsNep11D || ctr.IsNep11ND) {
|
||||||
|
imports["github.com/nspcc-dev/neo-go/pkg/neorpc/result"] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(ctr.Methods) > 0 {
|
||||||
|
imports["github.com/nspcc-dev/neo-go/pkg/core/transaction"] = struct{}{}
|
||||||
|
}
|
||||||
|
if len(ctr.Methods) > 0 || ctr.IsNep17 || ctr.IsNep11D || ctr.IsNep11ND {
|
||||||
|
ctr.HasWriter = true
|
||||||
|
}
|
||||||
|
if len(ctr.SafeMethods) > 0 || ctr.IsNep17 || ctr.IsNep11D || ctr.IsNep11ND {
|
||||||
|
ctr.HasReader = true
|
||||||
|
}
|
||||||
ctr.Imports = ctr.Imports[:0]
|
ctr.Imports = ctr.Imports[:0]
|
||||||
for imp := range imports {
|
for imp := range imports {
|
||||||
ctr.Imports = append(ctr.Imports, imp)
|
ctr.Imports = append(ctr.Imports, imp)
|
||||||
|
|
Loading…
Reference in a new issue