rpcbinding: generate ASSERT for bool-returning methods
It's a common pattern.
This commit is contained in:
parent
2a4a5ab479
commit
aeb61fb61d
3 changed files with 63 additions and 15 deletions
23
cli/smartcontract/testdata/nameservice/nns.go
vendored
23
cli/smartcontract/testdata/nameservice/nns.go
vendored
|
@ -6,6 +6,7 @@ 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/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"
|
||||||
|
@ -153,18 +154,30 @@ func (c *Contract) SetPriceUnsigned(priceList []interface{}) (*transaction.Trans
|
||||||
return c.actor.MakeUnsignedCall(Hash, "setPrice", nil, priceList)
|
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.
|
// Register creates a transaction invoking `register` method of the contract.
|
||||||
// This transaction is signed and immediately sent to the network.
|
// This transaction is signed and immediately sent to the network.
|
||||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
// 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) {
|
func (c *Contract) Register(name string, owner util.Uint160) (util.Uint256, uint32, error) {
|
||||||
return c.actor.SendCall(Hash, "register", name, owner)
|
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.
|
// RegisterTransaction creates a transaction invoking `register` method of the contract.
|
||||||
// This transaction is signed, but not sent to the network, instead it's
|
// This transaction is signed, but not sent to the network, instead it's
|
||||||
// returned to the caller.
|
// returned to the caller.
|
||||||
func (c *Contract) RegisterTransaction(name string, owner util.Uint160) (*transaction.Transaction, error) {
|
func (c *Contract) RegisterTransaction(name string, owner util.Uint160) (*transaction.Transaction, error) {
|
||||||
return c.actor.MakeCall(Hash, "register", name, owner)
|
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.
|
// RegisterUnsigned creates a transaction invoking `register` method of the contract.
|
||||||
|
@ -172,7 +185,11 @@ func (c *Contract) RegisterTransaction(name string, owner util.Uint160) (*transa
|
||||||
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
||||||
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
||||||
func (c *Contract) RegisterUnsigned(name string, owner util.Uint160) (*transaction.Transaction, error) {
|
func (c *Contract) RegisterUnsigned(name string, owner util.Uint160) (*transaction.Transaction, error) {
|
||||||
return c.actor.MakeUnsignedCall(Hash, "register", nil, name, owner)
|
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.
|
// Renew creates a transaction invoking `renew` method of the contract.
|
||||||
|
|
|
@ -436,11 +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. If your
|
contract-specific RPC bindings with the "generate-rpcwrapper" command. It
|
||||||
contract is NEP-11 or NEP-17 that's autodetected and an appropriate package is
|
generates ContractReader structure for safe methods that accept appropriate
|
||||||
included as well. Notice that the type data available in the manifest is
|
data for input and return things returned by the contract. State-changing
|
||||||
limited, so in some cases the interface generated may use generic stackitem
|
methods are contained in Contract structure with each contract method
|
||||||
types. Iterators are not supported yet.
|
represented by three wrapper methods that create/send transaction with a
|
||||||
|
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
|
||||||
|
|
|
@ -27,15 +27,26 @@ func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
}
|
}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- define "METHOD" -}}
|
{{- define "METHOD" -}}
|
||||||
// {{.Name}} {{.Comment}}
|
{{- 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.
|
// This transaction is signed and immediately sent to the network.
|
||||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||||
func (c *Contract) {{.Name}}({{range $index, $arg := .Arguments -}}
|
func (c *Contract) {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
{{- if ne $index 0}}, {{end}}
|
{{- if ne $index 0}}, {{end}}
|
||||||
{{- .Name}} {{.Type}}
|
{{- .Name}} {{.Type}}
|
||||||
{{- end}}) (util.Uint256, uint32, error) {
|
{{- end}}) (util.Uint256, uint32, error) {
|
||||||
return c.actor.SendCall(Hash, "{{ .NameABI }}"
|
{{if ne .ReturnType "bool"}}return c.actor.SendCall(Hash, "{{ .NameABI }}"
|
||||||
{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}})
|
{{- 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}}
|
// {{.Name}}Transaction {{.Comment}}
|
||||||
|
@ -45,8 +56,12 @@ func (c *Contract) {{.Name}}Transaction({{range $index, $arg := .Arguments -}}
|
||||||
{{- if ne $index 0}}, {{end}}
|
{{- if ne $index 0}}, {{end}}
|
||||||
{{- .Name}} {{.Type}}
|
{{- .Name}} {{.Type}}
|
||||||
{{- end}}) (*transaction.Transaction, error) {
|
{{- end}}) (*transaction.Transaction, error) {
|
||||||
return c.actor.MakeCall(Hash, "{{ .NameABI }}"
|
{{if ne .ReturnType "bool"}}return c.actor.MakeCall(Hash, "{{ .NameABI }}"
|
||||||
{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}})
|
{{- 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}}
|
// {{.Name}}Unsigned {{.Comment}}
|
||||||
|
@ -57,8 +72,12 @@ func (c *Contract) {{.Name}}Unsigned({{range $index, $arg := .Arguments -}}
|
||||||
{{- if ne $index 0}}, {{end}}
|
{{- if ne $index 0}}, {{end}}
|
||||||
{{- .Name}} {{.Type}}
|
{{- .Name}} {{.Type}}
|
||||||
{{- end}}) (*transaction.Transaction, error) {
|
{{- end}}) (*transaction.Transaction, error) {
|
||||||
return c.actor.MakeUnsignedCall(Hash, "{{ .NameABI }}", nil
|
{{if ne .ReturnType "bool"}}return c.actor.MakeUnsignedCall(Hash, "{{ .NameABI }}", nil
|
||||||
{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}})
|
{{- 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 -}}
|
{{- end -}}
|
||||||
// Package {{.PackageName}} contains RPC wrappers for {{.ContractName}} contract.
|
// Package {{.PackageName}} contains RPC wrappers for {{.ContractName}} contract.
|
||||||
|
@ -278,6 +297,9 @@ func scTemplateToRPC(cfg binding.Config, bctr binding.ContractTmpl) ContractTmpl
|
||||||
i--
|
i--
|
||||||
} else {
|
} else {
|
||||||
ctr.Methods[i].Comment = fmt.Sprintf("creates a transaction invoking `%s` method of the contract.", ctr.Methods[i].NameABI)
|
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.
|
||||||
|
|
Loading…
Reference in a new issue