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/rpcclient/nep11"
|
||||
"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/vm/stackitem"
|
||||
"math/big"
|
||||
|
@ -153,18 +154,30 @@ func (c *Contract) SetPriceUnsigned(priceList []interface{}) (*transaction.Trans
|
|||
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) {
|
||||
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.
|
||||
// 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) {
|
||||
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.
|
||||
|
@ -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,
|
||||
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
||||
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.
|
||||
|
|
|
@ -436,11 +436,20 @@ $ ./bin/neo-go contract generate-wrapper --manifest manifest.json --config contr
|
|||
|
||||
### Generating RPC contract bindings
|
||||
To simplify interacting with the contract via RPC you can generate
|
||||
contract-specific RPC bindings with the "generate-rpcwrapper" command. 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.
|
||||
contract-specific RPC bindings with the "generate-rpcwrapper" command. It
|
||||
generates ContractReader structure for safe methods that accept appropriate
|
||||
data for input and return things returned by the contract. State-changing
|
||||
methods are contained in Contract structure with each contract method
|
||||
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
|
||||
|
|
|
@ -27,15 +27,26 @@ func (c *ContractReader) {{.Name}}({{range $index, $arg := .Arguments -}}
|
|||
}
|
||||
{{- end -}}
|
||||
{{- 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.
|
||||
// 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) {
|
||||
return c.actor.SendCall(Hash, "{{ .NameABI }}"
|
||||
{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}})
|
||||
{{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}}
|
||||
|
@ -45,8 +56,12 @@ func (c *Contract) {{.Name}}Transaction({{range $index, $arg := .Arguments -}}
|
|||
{{- if ne $index 0}}, {{end}}
|
||||
{{- .Name}} {{.Type}}
|
||||
{{- end}}) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeCall(Hash, "{{ .NameABI }}"
|
||||
{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}})
|
||||
{{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}}
|
||||
|
@ -57,8 +72,12 @@ func (c *Contract) {{.Name}}Unsigned({{range $index, $arg := .Arguments -}}
|
|||
{{- if ne $index 0}}, {{end}}
|
||||
{{- .Name}} {{.Type}}
|
||||
{{- end}}) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeUnsignedCall(Hash, "{{ .NameABI }}", nil
|
||||
{{- range $index, $arg := .Arguments -}}, {{.Name}}{{end}})
|
||||
{{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.
|
||||
|
@ -278,6 +297,9 @@ func scTemplateToRPC(cfg binding.Config, bctr binding.ContractTmpl) ContractTmpl
|
|||
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.
|
||||
|
|
Loading…
Reference in a new issue