smartcontract: support dynamic contract hash for bindings
Allow dynamic contract hash for contract bindings. Close #3007 Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
This commit is contained in:
parent
8913542f93
commit
c5dbecb754
5 changed files with 523 additions and 39 deletions
|
@ -25,6 +25,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/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"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"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||||||
|
@ -145,18 +146,7 @@ func Blocks() []*alias.Block {
|
||||||
cmd = append(cmd, "--in", ctrPath, "--bindings", bindingsPath)
|
cmd = append(cmd, "--in", ctrPath, "--bindings", bindingsPath)
|
||||||
|
|
||||||
// Replace `pkg/interop` in go.mod to avoid getting an actual module version.
|
// Replace `pkg/interop` in go.mod to avoid getting an actual module version.
|
||||||
goMod := filepath.Join(ctrPath, "go.mod")
|
require.NoError(t, updateGoMod(ctrPath, "myimport.com/testcontract", "../../pkg/interop"))
|
||||||
data, err := os.ReadFile(goMod)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
i := bytes.IndexByte(data, '\n')
|
|
||||||
data = append([]byte("module myimport.com/testcontract"), data[i:]...)
|
|
||||||
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
data = append(data, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "...)
|
|
||||||
data = append(data, filepath.Join(wd, "../../pkg/interop")...)
|
|
||||||
require.NoError(t, os.WriteFile(goMod, data, os.ModePerm))
|
|
||||||
|
|
||||||
cmd = append(cmd, "--config", cfgPath,
|
cmd = append(cmd, "--config", cfgPath,
|
||||||
"--out", filepath.Join(tmpDir, "out.nef"),
|
"--out", filepath.Join(tmpDir, "out.nef"),
|
||||||
|
@ -176,7 +166,7 @@ func Blocks() []*alias.Block {
|
||||||
|
|
||||||
bs, err := os.ReadFile(outPath)
|
bs, err := os.ReadFile(outPath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> --hash <hash> [--config <config>]; DO NOT EDIT.
|
require.Equal(t, `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
|
||||||
|
|
||||||
// Package testcontract contains wrappers for testcontract contract.
|
// Package testcontract contains wrappers for testcontract contract.
|
||||||
package testcontract
|
package testcontract
|
||||||
|
@ -213,6 +203,84 @@ func ToMap(a []testcontract.MyPair) map[int]string {
|
||||||
`, string(bs))
|
`, string(bs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateGoMod updates the go.mod file located in the specified directory.
|
||||||
|
// It sets the module name and replaces the neo-go interop package path with
|
||||||
|
// the provided one to avoid getting an actual module version.
|
||||||
|
func updateGoMod(dir, moduleName, neoGoPath string) error {
|
||||||
|
goModPath := filepath.Join(dir, "go.mod")
|
||||||
|
data, err := os.ReadFile(goModPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read go.mod: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
i := bytes.IndexByte(data, '\n')
|
||||||
|
if i == -1 {
|
||||||
|
return fmt.Errorf("unexpected go.mod format")
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedData := append([]byte("module "+moduleName), data[i:]...)
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get working directory: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
replacementPath := filepath.Join(wd, neoGoPath)
|
||||||
|
updatedData = append(updatedData, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "+replacementPath+" \n"...)
|
||||||
|
|
||||||
|
if err := os.WriteFile(goModPath, updatedData, os.ModePerm); err != nil {
|
||||||
|
return fmt.Errorf("failed to write updated go.mod: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDynamicWrapper(t *testing.T) {
|
||||||
|
// For proper contract init. The actual version as it will be replaced.
|
||||||
|
smartcontract.ModVersion = "v0.0.0"
|
||||||
|
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
e := testcli.NewExecutor(t, true)
|
||||||
|
|
||||||
|
ctrPath := "../smartcontract/testdata"
|
||||||
|
|
||||||
|
verifyHash := testcli.DeployContract(t, e, filepath.Join(ctrPath, "verify.go"), filepath.Join(ctrPath, "verify.yml"), testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
|
||||||
|
|
||||||
|
helperContract := `package testcontract
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||||
|
verify "myimport.com/testcontract/bindings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CallVerifyContract(h interop.Hash160) bool{
|
||||||
|
contractInstance := verify.NewContract(h)
|
||||||
|
return contractInstance.Verify()
|
||||||
|
}`
|
||||||
|
|
||||||
|
helperDir := filepath.Join(tmpDir, "helper")
|
||||||
|
e.Run(t, "neo-go", "contract", "init", "--name", helperDir)
|
||||||
|
|
||||||
|
require.NoError(t, updateGoMod(helperDir, "myimport.com/testcontract", "../../pkg/interop"))
|
||||||
|
require.NoError(t, os.WriteFile(filepath.Join(helperDir, "main.go"), []byte(helperContract), os.ModePerm))
|
||||||
|
require.NoError(t, os.Mkdir(filepath.Join(helperDir, "bindings"), os.ModePerm))
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "contract", "generate-wrapper",
|
||||||
|
"--config", filepath.Join(ctrPath, "verify.bindings.yml"), "--manifest", filepath.Join(ctrPath, "verify.manifest.json"),
|
||||||
|
"--out", filepath.Join(helperDir, "bindings", "testdata.go"))
|
||||||
|
e.Run(t, "neo-go", "contract", "compile", "--in", filepath.Join(helperDir, "main.go"), "--config", filepath.Join(helperDir, "neo-go.yml"))
|
||||||
|
helperHash := testcli.DeployContract(t, e, filepath.Join(helperDir, "main.go"), filepath.Join(helperDir, "neo-go.yml"), testcli.ValidatorWallet, testcli.ValidatorAddr, testcli.ValidatorPass)
|
||||||
|
|
||||||
|
e.In.WriteString("one\r")
|
||||||
|
e.Run(t, "neo-go", "contract", "invokefunction",
|
||||||
|
"--rpc-endpoint", "http://"+e.RPC.Addresses()[0],
|
||||||
|
"--wallet", testcli.ValidatorWallet, "--address", testcli.ValidatorAddr, "--force", "--await", helperHash.StringLE(), "callVerifyContract", verifyHash.StringLE())
|
||||||
|
|
||||||
|
tx, _ := e.CheckTxPersisted(t, "Sent invocation transaction ")
|
||||||
|
aer, err := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, aer[0].Stack[0].Value().(bool), true)
|
||||||
|
}
|
||||||
|
|
||||||
func TestContractInitAndCompile(t *testing.T) {
|
func TestContractInitAndCompile(t *testing.T) {
|
||||||
// For proper contract init. The actual version as it will be replaced.
|
// For proper contract init. The actual version as it will be replaced.
|
||||||
smartcontract.ModVersion = "v0.0.0"
|
smartcontract.ModVersion = "v0.0.0"
|
||||||
|
@ -265,15 +333,7 @@ func TestContractInitAndCompile(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Replace `pkg/interop` in go.mod to avoid getting an actual module version.
|
// Replace `pkg/interop` in go.mod to avoid getting an actual module version.
|
||||||
goMod := filepath.Join(ctrPath, "go.mod")
|
require.NoError(t, updateGoMod(ctrPath, "myimport.com/testcontract", "../../pkg/interop"))
|
||||||
data, err := os.ReadFile(goMod)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
wd, err := os.Getwd()
|
|
||||||
require.NoError(t, err)
|
|
||||||
data = append(data, "\nreplace github.com/nspcc-dev/neo-go/pkg/interop => "...)
|
|
||||||
data = append(data, filepath.Join(wd, "../../pkg/interop")...)
|
|
||||||
require.NoError(t, os.WriteFile(goMod, data, os.ModePerm))
|
|
||||||
|
|
||||||
cmd = append(cmd, "--config", cfgPath)
|
cmd = append(cmd, "--config", cfgPath)
|
||||||
|
|
||||||
|
|
|
@ -30,17 +30,22 @@ var generatorFlags = []cli.Flag{
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "hash",
|
Name: "hash",
|
||||||
Usage: "Smart-contract hash",
|
Usage: "Smart-contract hash. If not passed, the wrapper will be designed for dynamic hash usage",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var generateWrapperCmd = cli.Command{
|
var generateWrapperCmd = cli.Command{
|
||||||
Name: "generate-wrapper",
|
Name: "generate-wrapper",
|
||||||
Usage: "generate wrapper to use in other contracts",
|
Usage: "generate wrapper to use in other contracts",
|
||||||
UsageText: "neo-go contract generate-wrapper --manifest <file.json> --out <file.go> --hash <hash> [--config <config>]",
|
UsageText: "neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]",
|
||||||
Description: ``,
|
Description: `Generates a Go wrapper to use it in other smart contracts. If the
|
||||||
Action: contractGenerateWrapper,
|
--hash flag is provided, CALLT instruction is used for the target contract
|
||||||
Flags: generatorFlags,
|
invocation as an optimization of the wrapper contract code. If omitted, the
|
||||||
|
generated wrapper will be designed for dynamic hash usage, allowing
|
||||||
|
the hash to be specified at runtime.
|
||||||
|
`,
|
||||||
|
Action: contractGenerateWrapper,
|
||||||
|
Flags: generatorFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
var generateRPCWrapperCmd = cli.Command{
|
var generateRPCWrapperCmd = cli.Command{
|
||||||
|
@ -52,15 +57,15 @@ var generateRPCWrapperCmd = cli.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
func contractGenerateWrapper(ctx *cli.Context) error {
|
func contractGenerateWrapper(ctx *cli.Context) error {
|
||||||
return contractGenerateSomething(ctx, binding.Generate, false)
|
return contractGenerateSomething(ctx, binding.Generate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func contractGenerateRPCWrapper(ctx *cli.Context) error {
|
func contractGenerateRPCWrapper(ctx *cli.Context) error {
|
||||||
return contractGenerateSomething(ctx, rpcbinding.Generate, true)
|
return contractGenerateSomething(ctx, rpcbinding.Generate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// contractGenerateSomething reads generator parameters and calls the given callback.
|
// contractGenerateSomething reads generator parameters and calls the given callback.
|
||||||
func contractGenerateSomething(ctx *cli.Context, cb func(binding.Config) error, allowEmptyHash bool) error {
|
func contractGenerateSomething(ctx *cli.Context, cb func(binding.Config) error) error {
|
||||||
if err := cmdargs.EnsureNone(ctx); err != nil {
|
if err := cmdargs.EnsureNone(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -73,8 +78,6 @@ func contractGenerateSomething(ctx *cli.Context, cb func(binding.Config) error,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid contract hash: %w", err), 1)
|
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)
|
m, _, err := readManifest(ctx.String("manifest"), h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -151,7 +151,7 @@ callflags:
|
||||||
"--hash", h.StringLE(),
|
"--hash", h.StringLE(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const expected = `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> --hash <hash> [--config <config>]; DO NOT EDIT.
|
const expected = `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
|
||||||
|
|
||||||
// Package wrapper contains wrappers for MyContract contract.
|
// Package wrapper contains wrappers for MyContract contract.
|
||||||
package wrapper
|
package wrapper
|
||||||
|
@ -233,6 +233,99 @@ func MyFunc(in map[int]mycontract.Input) []mycontract.Output {
|
||||||
data, err := os.ReadFile(outFile)
|
data, err := os.ReadFile(outFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, expected, string(data))
|
require.Equal(t, expected, string(data))
|
||||||
|
|
||||||
|
require.NoError(t, app.Run([]string{"", "generate-wrapper",
|
||||||
|
"--manifest", manifestFile,
|
||||||
|
"--config", cfgPath,
|
||||||
|
"--out", outFile,
|
||||||
|
}))
|
||||||
|
expectedWithDynamicHash := `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package wrapper contains wrappers for MyContract contract.
|
||||||
|
package wrapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/heyitsme/mycontract"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/iterator"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/native/ledger"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/interop/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Contract represents the MyContract smart contract.
|
||||||
|
type Contract struct {
|
||||||
|
Hash interop.Hash160
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContract returns a new Contract instance with the specified hash.
|
||||||
|
func NewContract(hash interop.Hash160) Contract {
|
||||||
|
return Contract{Hash: hash}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum invokes ` + "`sum`" + ` method of contract.
|
||||||
|
func (c Contract) Sum(first int, second int) int {
|
||||||
|
return contract.Call(c.Hash, "sum", contract.All, first, second).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum2 invokes ` + "`sum`" + ` method of contract.
|
||||||
|
func (c Contract) Sum2(first int, second int, third int) int {
|
||||||
|
return contract.Call(c.Hash, "sum", contract.All, first, second, third).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum3 invokes ` + "`sum3`" + ` method of contract.
|
||||||
|
func (c Contract) Sum3() int {
|
||||||
|
return contract.Call(c.Hash, "sum3", contract.ReadOnly).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zum invokes ` + "`zum`" + ` method of contract.
|
||||||
|
func (c Contract) Zum(typev int, typev_ int, funcv int) int {
|
||||||
|
return contract.Call(c.Hash, "zum", contract.All, typev, typev_, funcv).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// JustExecute invokes ` + "`justExecute`" + ` method of contract.
|
||||||
|
func (c Contract) JustExecute(arr []any) {
|
||||||
|
contract.Call(c.Hash, "justExecute", contract.All, arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPublicKey invokes ` + "`getPublicKey`" + ` method of contract.
|
||||||
|
func (c Contract) GetPublicKey() interop.PublicKey {
|
||||||
|
return contract.Call(c.Hash, "getPublicKey", contract.All).(interop.PublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OtherTypes invokes ` + "`otherTypes`" + ` method of contract.
|
||||||
|
func (c Contract) OtherTypes(ctr interop.Hash160, tx interop.Hash256, sig interop.Signature, data any) bool {
|
||||||
|
return contract.Call(c.Hash, "otherTypes", contract.All, ctr, tx, sig, data).(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchStorage invokes ` + "`searchStorage`" + ` method of contract.
|
||||||
|
func (c Contract) SearchStorage(ctx storage.Context) iterator.Iterator {
|
||||||
|
return contract.Call(c.Hash, "searchStorage", contract.All, ctx).(iterator.Iterator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFromMap invokes ` + "`getFromMap`" + ` method of contract.
|
||||||
|
func (c Contract) GetFromMap(intMap map[string]int, indices []string) []int {
|
||||||
|
return contract.Call(c.Hash, "getFromMap", contract.All, intMap, indices).([]int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoSomething invokes ` + "`doSomething`" + ` method of contract.
|
||||||
|
func (c Contract) DoSomething(bytes []byte, str string) any {
|
||||||
|
return contract.Call(c.Hash, "doSomething", contract.ReadStates, bytes, str).(any)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockWrapper invokes ` + "`getBlockWrapper`" + ` method of contract.
|
||||||
|
func (c Contract) GetBlockWrapper() ledger.Block {
|
||||||
|
return contract.Call(c.Hash, "getBlockWrapper", contract.All).(ledger.Block)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MyFunc invokes ` + "`myFunc`" + ` method of contract.
|
||||||
|
func (c Contract) MyFunc(in map[int]mycontract.Input) []mycontract.Output {
|
||||||
|
return contract.Call(c.Hash, "myFunc", contract.All, in).([]mycontract.Output)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
data, err = os.ReadFile(outFile)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expectedWithDynamicHash, string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateValidPackageName(t *testing.T) {
|
func TestGenerateValidPackageName(t *testing.T) {
|
||||||
|
@ -267,7 +360,7 @@ func TestGenerateValidPackageName(t *testing.T) {
|
||||||
|
|
||||||
data, err := os.ReadFile(outFile)
|
data, err := os.ReadFile(outFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> --hash <hash> [--config <config>]; DO NOT EDIT.
|
require.Equal(t, `// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
|
||||||
|
|
||||||
// Package myspacecontract contains wrappers for My space contract contract.
|
// Package myspacecontract contains wrappers for My space contract contract.
|
||||||
package myspacecontract
|
package myspacecontract
|
||||||
|
|
297
cli/smartcontract/testdata/verify.bindings.yml
vendored
Executable file
297
cli/smartcontract/testdata/verify.bindings.yml
vendored
Executable file
|
@ -0,0 +1,297 @@
|
||||||
|
package: testdata
|
||||||
|
hash: "0x0000000000000000000000000000000000000000"
|
||||||
|
overrides:
|
||||||
|
burnGas.gas: int
|
||||||
|
call: any
|
||||||
|
call.args: '[]any'
|
||||||
|
call.f: any
|
||||||
|
call.method: string
|
||||||
|
call.scriptHash: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
callWithToken: any
|
||||||
|
callWithToken.args: '[]any'
|
||||||
|
callWithToken.flags: int
|
||||||
|
callWithToken.method: string
|
||||||
|
callWithToken.scriptHash: string
|
||||||
|
callWithTokenNoRet.args: '[]any'
|
||||||
|
callWithTokenNoRet.flags: int
|
||||||
|
callWithTokenNoRet.method: string
|
||||||
|
callWithTokenNoRet.scriptHash: string
|
||||||
|
checkWitness: bool
|
||||||
|
checkWitness.hashOrKey: '[]byte'
|
||||||
|
createMultisigAccount: '[]byte'
|
||||||
|
createMultisigAccount.m: int
|
||||||
|
createMultisigAccount.pubs: '[]github.com/nspcc-dev/neo-go/pkg/interop.PublicKey'
|
||||||
|
createStandardAccount: '[]byte'
|
||||||
|
createStandardAccount.pub: github.com/nspcc-dev/neo-go/pkg/interop.PublicKey
|
||||||
|
currentHash: github.com/nspcc-dev/neo-go/pkg/interop.Hash256
|
||||||
|
currentIndex: int
|
||||||
|
currentSigners: '[]github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.TransactionSigner'
|
||||||
|
equals: bool
|
||||||
|
equals.b: any
|
||||||
|
gasLeft: int
|
||||||
|
getAddressVersion: int
|
||||||
|
getBlock: '*github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.Block'
|
||||||
|
getBlock.indexOrHash: any
|
||||||
|
getCallFlags: any
|
||||||
|
getCallingScriptHash: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
getEntryScriptHash: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
getExecutingScriptHash: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
getInvocationCounter: int
|
||||||
|
getNetwork: int
|
||||||
|
getNotifications: '[][]any'
|
||||||
|
getNotifications.h: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
getRandom: int
|
||||||
|
getScriptContainer: '*github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.Transaction'
|
||||||
|
getTime: int
|
||||||
|
getTransaction: '*github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.Transaction'
|
||||||
|
getTransaction.hash: github.com/nspcc-dev/neo-go/pkg/interop.Hash256
|
||||||
|
getTransactionFromBlock: '*github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.Transaction'
|
||||||
|
getTransactionFromBlock.indexOrHash: any
|
||||||
|
getTransactionFromBlock.txIndex: int
|
||||||
|
getTransactionHeight: int
|
||||||
|
getTransactionHeight.hash: github.com/nspcc-dev/neo-go/pkg/interop.Hash256
|
||||||
|
getTransactionSigners: '[]github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.TransactionSigner'
|
||||||
|
getTransactionSigners.hash: github.com/nspcc-dev/neo-go/pkg/interop.Hash256
|
||||||
|
getTransactionVMState: int
|
||||||
|
getTransactionVMState.hash: github.com/nspcc-dev/neo-go/pkg/interop.Hash256
|
||||||
|
getTrigger: int
|
||||||
|
loadScript: any
|
||||||
|
loadScript.args: '[]any'
|
||||||
|
loadScript.f: any
|
||||||
|
loadScript.script: '[]byte'
|
||||||
|
log.message: string
|
||||||
|
notify.args: '[]any'
|
||||||
|
notify.name: string
|
||||||
|
onNEP11Payment.amount: int
|
||||||
|
onNEP11Payment.data: any
|
||||||
|
onNEP11Payment.from: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
onNEP11Payment.token: '[]byte'
|
||||||
|
onNEP17Payment.amount: int
|
||||||
|
onNEP17Payment.data: any
|
||||||
|
onNEP17Payment.from: github.com/nspcc-dev/neo-go/pkg/interop.Hash160
|
||||||
|
opcode0NoReturn.op: string
|
||||||
|
opcode1: any
|
||||||
|
opcode1NoReturn.arg: any
|
||||||
|
opcode1NoReturn.op: string
|
||||||
|
opcode1.arg: any
|
||||||
|
opcode1.op: string
|
||||||
|
opcode2: any
|
||||||
|
opcode2NoReturn.arg1: any
|
||||||
|
opcode2NoReturn.arg2: any
|
||||||
|
opcode2NoReturn.op: string
|
||||||
|
opcode2.arg1: any
|
||||||
|
opcode2.arg2: any
|
||||||
|
opcode2.op: string
|
||||||
|
opcode3: any
|
||||||
|
opcode3.arg1: any
|
||||||
|
opcode3.arg2: any
|
||||||
|
opcode3.arg3: any
|
||||||
|
opcode3.op: string
|
||||||
|
platform: '[]byte'
|
||||||
|
syscall0: any
|
||||||
|
syscall0NoReturn.name: string
|
||||||
|
syscall0.name: string
|
||||||
|
syscall1: any
|
||||||
|
syscall1NoReturn.arg: any
|
||||||
|
syscall1NoReturn.name: string
|
||||||
|
syscall1.arg: any
|
||||||
|
syscall1.name: string
|
||||||
|
syscall2: any
|
||||||
|
syscall2NoReturn.arg1: any
|
||||||
|
syscall2NoReturn.arg2: any
|
||||||
|
syscall2NoReturn.name: string
|
||||||
|
syscall2.arg1: any
|
||||||
|
syscall2.arg2: any
|
||||||
|
syscall2.name: string
|
||||||
|
syscall3: any
|
||||||
|
syscall3NoReturn.arg1: any
|
||||||
|
syscall3NoReturn.arg2: any
|
||||||
|
syscall3NoReturn.arg3: any
|
||||||
|
syscall3NoReturn.name: string
|
||||||
|
syscall3.arg1: any
|
||||||
|
syscall3.arg2: any
|
||||||
|
syscall3.arg3: any
|
||||||
|
syscall3.name: string
|
||||||
|
syscall4: any
|
||||||
|
syscall4NoReturn.arg1: any
|
||||||
|
syscall4NoReturn.arg2: any
|
||||||
|
syscall4NoReturn.arg3: any
|
||||||
|
syscall4NoReturn.arg4: any
|
||||||
|
syscall4NoReturn.name: string
|
||||||
|
syscall4.arg1: any
|
||||||
|
syscall4.arg2: any
|
||||||
|
syscall4.arg3: any
|
||||||
|
syscall4.arg4: any
|
||||||
|
syscall4.name: string
|
||||||
|
toBlockSR: '*github.com/nspcc-dev/neo-go/pkg/interop/native/ledger.BlockSR'
|
||||||
|
verify: bool
|
||||||
|
namedtypes:
|
||||||
|
ledger.Block:
|
||||||
|
base: Array
|
||||||
|
name: ledger.Block
|
||||||
|
fields:
|
||||||
|
- field: Hash
|
||||||
|
base: Hash256
|
||||||
|
- field: Version
|
||||||
|
base: Integer
|
||||||
|
- field: PrevHash
|
||||||
|
base: Hash256
|
||||||
|
- field: MerkleRoot
|
||||||
|
base: Hash256
|
||||||
|
- field: Timestamp
|
||||||
|
base: Integer
|
||||||
|
- field: Nonce
|
||||||
|
base: Integer
|
||||||
|
- field: Index
|
||||||
|
base: Integer
|
||||||
|
- field: NextConsensus
|
||||||
|
base: Hash160
|
||||||
|
- field: TransactionsLength
|
||||||
|
base: Integer
|
||||||
|
ledger.BlockSR:
|
||||||
|
base: Array
|
||||||
|
name: ledger.BlockSR
|
||||||
|
fields:
|
||||||
|
- field: Hash
|
||||||
|
base: Hash256
|
||||||
|
- field: Version
|
||||||
|
base: Integer
|
||||||
|
- field: PrevHash
|
||||||
|
base: Hash256
|
||||||
|
- field: MerkleRoot
|
||||||
|
base: Hash256
|
||||||
|
- field: Timestamp
|
||||||
|
base: Integer
|
||||||
|
- field: Nonce
|
||||||
|
base: Integer
|
||||||
|
- field: Index
|
||||||
|
base: Integer
|
||||||
|
- field: NextConsensus
|
||||||
|
base: Hash160
|
||||||
|
- field: TransactionsLength
|
||||||
|
base: Integer
|
||||||
|
- field: PrevStateRoot
|
||||||
|
base: Hash256
|
||||||
|
ledger.Transaction:
|
||||||
|
base: Array
|
||||||
|
name: ledger.Transaction
|
||||||
|
fields:
|
||||||
|
- field: Hash
|
||||||
|
base: Hash256
|
||||||
|
- field: Version
|
||||||
|
base: Integer
|
||||||
|
- field: Nonce
|
||||||
|
base: Integer
|
||||||
|
- field: Sender
|
||||||
|
base: Hash160
|
||||||
|
- field: SysFee
|
||||||
|
base: Integer
|
||||||
|
- field: NetFee
|
||||||
|
base: Integer
|
||||||
|
- field: ValidUntilBlock
|
||||||
|
base: Integer
|
||||||
|
- field: Script
|
||||||
|
base: ByteArray
|
||||||
|
ledger.TransactionSigner:
|
||||||
|
base: Array
|
||||||
|
name: ledger.TransactionSigner
|
||||||
|
fields:
|
||||||
|
- field: Account
|
||||||
|
base: Hash160
|
||||||
|
- field: Scopes
|
||||||
|
base: Integer
|
||||||
|
- field: AllowedContracts
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Hash160
|
||||||
|
- field: AllowedGroups
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: PublicKey
|
||||||
|
- field: Rules
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Array
|
||||||
|
name: ledger.WitnessRule
|
||||||
|
ledger.WitnessCondition:
|
||||||
|
base: Array
|
||||||
|
name: ledger.WitnessCondition
|
||||||
|
fields:
|
||||||
|
- field: Type
|
||||||
|
base: Integer
|
||||||
|
- field: Value
|
||||||
|
base: Any
|
||||||
|
ledger.WitnessRule:
|
||||||
|
base: Array
|
||||||
|
name: ledger.WitnessRule
|
||||||
|
fields:
|
||||||
|
- field: Action
|
||||||
|
base: Integer
|
||||||
|
- field: Condition
|
||||||
|
base: Array
|
||||||
|
name: ledger.WitnessCondition
|
||||||
|
types:
|
||||||
|
call.args:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Any
|
||||||
|
call.f:
|
||||||
|
base: InteropInterface
|
||||||
|
interface: iterator
|
||||||
|
callWithToken.args:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Any
|
||||||
|
callWithTokenNoRet.args:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Any
|
||||||
|
createMultisigAccount.pubs:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: PublicKey
|
||||||
|
currentSigners:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Array
|
||||||
|
name: ledger.TransactionSigner
|
||||||
|
getBlock:
|
||||||
|
base: Array
|
||||||
|
name: ledger.Block
|
||||||
|
getCallFlags:
|
||||||
|
base: InteropInterface
|
||||||
|
interface: iterator
|
||||||
|
getNotifications:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Any
|
||||||
|
getScriptContainer:
|
||||||
|
base: Array
|
||||||
|
name: ledger.Transaction
|
||||||
|
getTransaction:
|
||||||
|
base: Array
|
||||||
|
name: ledger.Transaction
|
||||||
|
getTransactionFromBlock:
|
||||||
|
base: Array
|
||||||
|
name: ledger.Transaction
|
||||||
|
getTransactionSigners:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Array
|
||||||
|
name: ledger.TransactionSigner
|
||||||
|
loadScript.args:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Any
|
||||||
|
loadScript.f:
|
||||||
|
base: InteropInterface
|
||||||
|
interface: iterator
|
||||||
|
notify.args:
|
||||||
|
base: Array
|
||||||
|
value:
|
||||||
|
base: Any
|
||||||
|
toBlockSR:
|
||||||
|
base: Array
|
||||||
|
name: ledger.BlockSR
|
|
@ -19,7 +19,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const srcTmpl = `
|
const srcTmpl = `
|
||||||
{{- define "METHOD" -}}
|
{{- define "FUNCTION" -}}
|
||||||
// {{.Name}} {{.Comment}}
|
// {{.Name}} {{.Comment}}
|
||||||
func {{.Name}}({{range $index, $arg := .Arguments -}}
|
func {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
{{- if ne $index 0}}, {{end}}
|
{{- if ne $index 0}}, {{end}}
|
||||||
|
@ -33,7 +33,21 @@ func {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
}
|
}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> --hash <hash> [--config <config>]; DO NOT EDIT.
|
{{- define "METHOD" -}}
|
||||||
|
// {{.Name}} {{.Comment}}
|
||||||
|
func (c Contract) {{.Name}}({{range $index, $arg := .Arguments -}}
|
||||||
|
{{- if ne $index 0}}, {{end}}
|
||||||
|
{{- .Name}} {{.Type}}
|
||||||
|
{{- end}}) {{if .ReturnType }}{{ .ReturnType}} {
|
||||||
|
return contract.Call(c.Hash, "{{ .NameABI }}", contract.{{ .CallFlag }}
|
||||||
|
{{- range $arg := .Arguments -}}, {{.Name}}{{end}}).({{ .ReturnType }})
|
||||||
|
{{- else -}} {
|
||||||
|
contract.Call(c.Hash, "{{ .NameABI }}", contract.{{ .CallFlag }}
|
||||||
|
{{- range $arg := .Arguments -}}, {{.Name}}{{end}})
|
||||||
|
{{- end}}
|
||||||
|
}
|
||||||
|
{{- end -}}
|
||||||
|
// Code generated by neo-go contract generate-wrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.
|
||||||
|
|
||||||
// Package {{.PackageName}} contains wrappers for {{.ContractName}} contract.
|
// Package {{.PackageName}} contains wrappers for {{.ContractName}} contract.
|
||||||
package {{.PackageName}}
|
package {{.PackageName}}
|
||||||
|
@ -42,10 +56,25 @@ import (
|
||||||
{{range $m := .Imports}} "{{ $m }}"
|
{{range $m := .Imports}} "{{ $m }}"
|
||||||
{{end}})
|
{{end}})
|
||||||
|
|
||||||
|
{{if .Hash}}
|
||||||
// Hash contains contract hash in big-endian form.
|
// Hash contains contract hash in big-endian form.
|
||||||
const Hash = "{{ .Hash }}"
|
const Hash = "{{ .Hash }}"
|
||||||
{{range $m := .Methods}}
|
{{range $m := .Methods}}
|
||||||
|
{{template "FUNCTION" $m }}
|
||||||
|
{{end}}
|
||||||
|
{{else}}
|
||||||
|
// Contract represents the {{.ContractName}} smart contract.
|
||||||
|
type Contract struct {
|
||||||
|
Hash interop.Hash160
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContract returns a new Contract instance with the specified hash.
|
||||||
|
func NewContract(hash interop.Hash160) Contract {
|
||||||
|
return Contract{Hash: hash}
|
||||||
|
}
|
||||||
|
{{range $m := .Methods}}
|
||||||
{{template "METHOD" $m }}
|
{{template "METHOD" $m }}
|
||||||
|
{{end}}
|
||||||
{{end}}`
|
{{end}}`
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -127,7 +156,9 @@ func NewConfig() Config {
|
||||||
func Generate(cfg Config) error {
|
func Generate(cfg Config) error {
|
||||||
ctr := TemplateFromManifest(cfg, scTypeToGo)
|
ctr := TemplateFromManifest(cfg, scTypeToGo)
|
||||||
ctr.Imports = append(ctr.Imports, "github.com/nspcc-dev/neo-go/pkg/interop/contract")
|
ctr.Imports = append(ctr.Imports, "github.com/nspcc-dev/neo-go/pkg/interop/contract")
|
||||||
ctr.Imports = append(ctr.Imports, "github.com/nspcc-dev/neo-go/pkg/interop/neogointernal")
|
if ctr.Hash != "" {
|
||||||
|
ctr.Imports = append(ctr.Imports, "github.com/nspcc-dev/neo-go/pkg/interop/neogointernal")
|
||||||
|
}
|
||||||
sort.Strings(ctr.Imports)
|
sort.Strings(ctr.Imports)
|
||||||
|
|
||||||
return FExecute(srcTemplate, cfg.Output, ctr)
|
return FExecute(srcTemplate, cfg.Output, ctr)
|
||||||
|
|
Loading…
Reference in a new issue