Skip to content

Commit

Permalink
manifest: support NEP-24
Browse files Browse the repository at this point in the history
Close #3451

Signed-off-by: Ekaterina Pavlova <[email protected]>
  • Loading branch information
AliceInHunterland committed Nov 5, 2024
1 parent 3a55edf commit 61e54e4
Show file tree
Hide file tree
Showing 17 changed files with 1,535 additions and 32 deletions.
38 changes: 25 additions & 13 deletions cli/smartcontract/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,21 +476,28 @@ func TestAssistedRPCBindings(t *testing.T) {
tmpDir := t.TempDir()
e := testcli.NewExecutor(t, false)

var checkBinding = func(source string, hasDefinedHash bool, guessEventTypes bool, suffix ...string) {
var checkBinding = func(source, configFile, expectedFile string, hasDefinedHash, guessEventTypes bool, suffix ...string) {
testName := source
if len(suffix) != 0 {
testName += suffix[0]
}
testName += fmt.Sprintf(", predefined hash: %t", hasDefinedHash)
t.Run(testName, func(t *testing.T) {
outFile := filepath.Join(tmpDir, "out.go")
configFile := filepath.Join(source, "config.yml")
expectedFile := filepath.Join(source, "rpcbindings.out")
if len(suffix) != 0 {
configFile = filepath.Join(source, "config"+suffix[0]+".yml")
expectedFile = filepath.Join(source, "rpcbindings"+suffix[0]+".out")
} else if !hasDefinedHash {
expectedFile = filepath.Join(source, "rpcbindings_dynamic_hash.out")
if configFile == "" {
if len(suffix) != 0 {
configFile = filepath.Join(source, "config"+suffix[0]+".yml")
} else {
configFile = filepath.Join(source, "config.yml")
}
}
if expectedFile == "" {
expectedFile = filepath.Join(source, "rpcbindings.out")
if len(suffix) != 0 {
expectedFile = filepath.Join(source, "rpcbindings"+suffix[0]+".out")
} else if !hasDefinedHash {
expectedFile = filepath.Join(source, "rpcbindings_dynamic_hash.out")
}
}
manifestF := filepath.Join(tmpDir, "manifest.json")
bindingF := filepath.Join(tmpDir, "binding.yml")
Expand Down Expand Up @@ -532,12 +539,17 @@ func TestAssistedRPCBindings(t *testing.T) {
}

for _, hasDefinedHash := range []bool{true, false} {
checkBinding(filepath.Join("testdata", "rpcbindings", "types"), hasDefinedHash, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "structs"), hasDefinedHash, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "types"), "", "", hasDefinedHash, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "structs"), "", "", hasDefinedHash, false)
}
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), true, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), true, false, "_extended")
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), true, true, "_guessed")
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), "", "", true, false)
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), "", "", true, false, "_extended")
checkBinding(filepath.Join("testdata", "rpcbindings", "notifications"), "", "", true, true, "_guessed")

checkBinding(filepath.Join("..", "..", "examples", "nft-d"), filepath.Join("..", "..", "examples", "nft-d", "nft.yml"), filepath.Join("testdata", "rpcbindings", "nft-d", "rpcbindings_dynamic_hash.out"), false, false)
checkBinding(filepath.Join("..", "..", "examples", "nft-d"), filepath.Join("..", "..", "examples", "nft-d", "nft.yml"), filepath.Join("testdata", "rpcbindings", "nft-d", "rpcbindings.out"), true, true)
checkBinding(filepath.Join("..", "..", "examples", "nft-nd"), filepath.Join("..", "..", "examples", "nft-nd", "nft.yml"), filepath.Join("testdata", "rpcbindings", "nft-nd", "rpcbindings_dynamic_hash.out"), false, false)
checkBinding(filepath.Join("..", "..", "examples", "nft-nd"), filepath.Join("..", "..", "examples", "nft-nd", "nft.yml"), filepath.Join("testdata", "rpcbindings", "nft-nd", "rpcbindings.out"), true, true)

require.False(t, rewriteExpectedOutputs)
}
Expand Down
145 changes: 145 additions & 0 deletions cli/smartcontract/testdata/rpcbindings/nft-d/rpcbindings.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.

// Package nft contains RPC wrappers for NeoFS Object NFT contract.
package nft

import (
"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/nep24"
"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}

// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
nep11.Invoker
}

// Actor is used by Contract to call state-changing methods.
type Actor interface {
Invoker

nep11.Actor

MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}

// ContractReader implements safe contract methods.
type ContractReader struct {
nep11.DivisibleReader
nep24.RoyaltyReader
invoker Invoker
hash util.Uint160
}

// Contract implements all contract methods.
type Contract struct {
ContractReader
nep11.DivisibleWriter
actor Actor
hash util.Uint160
}

// NewReader creates an instance of ContractReader using Hash and the given Invoker.
func NewReader(invoker Invoker) *ContractReader {
var hash = Hash
return &ContractReader{*nep11.NewDivisibleReader(invoker, hash), nep24.RoyaltyReader{invoker, hash}, invoker, hash}
}

// New creates an instance of Contract using Hash and the given Actor.
func New(actor Actor) *Contract {
var hash = Hash
var nep11dt = nep11.NewDivisible(actor, hash)
return &Contract{ContractReader{nep11dt.DivisibleReader, nep24.RoyaltyReader{}, actor, hash}, nep11dt.DivisibleWriter, actor, hash}
}

// 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(c.hash, "destroy")
}

// DestroyTransaction creates a transaction invoking `destroy` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) DestroyTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.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(c.hash, "destroy", nil)
}

// 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(c.hash, "update", nef, manifest)
}

// UpdateTransaction creates a transaction invoking `update` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UpdateTransaction(nef []byte, manifest []byte) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.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(c.hash, "update", nil, nef, manifest)
}

func (c *Contract) scriptForVerify() ([]byte, error) {
return smartcontract.CreateCallWithAssertScript(c.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 := c.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 := c.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 := c.scriptForVerify()
if err != nil {
return nil, err
}
return c.actor.MakeUnsignedRun(script, nil)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Code generated by neo-go contract generate-rpcwrapper --manifest <file.json> --out <file.go> [--hash <hash>] [--config <config>]; DO NOT EDIT.

// Package nft contains RPC wrappers for NeoFS Object NFT contract.
package nft

import (
"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/nep24"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
)

// Invoker is used by ContractReader to call various safe methods.
type Invoker interface {
nep11.Invoker
}

// Actor is used by Contract to call state-changing methods.
type Actor interface {
Invoker

nep11.Actor

MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}

// ContractReader implements safe contract methods.
type ContractReader struct {
nep11.DivisibleReader
nep24.RoyaltyReader
invoker Invoker
hash util.Uint160
}

// Contract implements all contract methods.
type Contract struct {
ContractReader
nep11.DivisibleWriter
actor Actor
hash util.Uint160
}

// NewReader creates an instance of ContractReader using provided contract hash and the given Invoker.
func NewReader(invoker Invoker, hash util.Uint160) *ContractReader {
return &ContractReader{*nep11.NewDivisibleReader(invoker, hash), nep24.RoyaltyReader{invoker, hash}, invoker, hash}
}

// New creates an instance of Contract using provided contract hash and the given Actor.
func New(actor Actor, hash util.Uint160) *Contract {
var nep11dt = nep11.NewDivisible(actor, hash)
return &Contract{ContractReader{nep11dt.DivisibleReader, nep24.RoyaltyReader{}, actor, hash}, nep11dt.DivisibleWriter, actor, hash}
}

// 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(c.hash, "destroy")
}

// DestroyTransaction creates a transaction invoking `destroy` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) DestroyTransaction() (*transaction.Transaction, error) {
return c.actor.MakeCall(c.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(c.hash, "destroy", nil)
}

// 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(c.hash, "update", nef, manifest)
}

// UpdateTransaction creates a transaction invoking `update` method of the contract.
// This transaction is signed, but not sent to the network, instead it's
// returned to the caller.
func (c *Contract) UpdateTransaction(nef []byte, manifest []byte) (*transaction.Transaction, error) {
return c.actor.MakeCall(c.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(c.hash, "update", nil, nef, manifest)
}

func (c *Contract) scriptForVerify() ([]byte, error) {
return smartcontract.CreateCallWithAssertScript(c.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 := c.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 := c.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 := c.scriptForVerify()
if err != nil {
return nil, err
}
return c.actor.MakeUnsignedRun(script, nil)
}
Loading

0 comments on commit 61e54e4

Please sign in to comment.