mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 13:41:37 +00:00
rpcclient: use separate reader/writer structs in nep11 and nep17
Which greatly simplifies reuse of these packages (and they're expected to be reused since real tokens implement standards and also add something of their own) and allows to avoid effects like doc_test.go:68:28: ambiguous selector neoContract.BalanceOf when neo.Contract is used. Avoids duplication in NEP-11 implementation as well.
This commit is contained in:
parent
00a9376311
commit
e1fe76137e
5 changed files with 41 additions and 48 deletions
|
@ -63,7 +63,7 @@ type ContractReader struct {
|
||||||
// Contract provides full NEO interface, both safe and state-changing methods.
|
// Contract provides full NEO interface, both safe and state-changing methods.
|
||||||
type Contract struct {
|
type Contract struct {
|
||||||
ContractReader
|
ContractReader
|
||||||
nep17.Token
|
nep17.TokenWriter
|
||||||
|
|
||||||
actor Actor
|
actor Actor
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,8 @@ func NewReader(invoker Invoker) *ContractReader {
|
||||||
// New creates an instance of Contract to perform state-changing actions in the
|
// New creates an instance of Contract to perform state-changing actions in the
|
||||||
// NEO contract.
|
// NEO contract.
|
||||||
func New(actor Actor) *Contract {
|
func New(actor Actor) *Contract {
|
||||||
return &Contract{*NewReader(actor), *nep17.New(actor, Hash), actor}
|
nep := nep17.New(actor, Hash)
|
||||||
|
return &Contract{ContractReader{nep.TokenReader, actor}, nep.TokenWriter, actor}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountState returns current NEO balance state for the account which
|
// GetAccountState returns current NEO balance state for the account which
|
||||||
|
|
|
@ -51,12 +51,19 @@ type BaseReader struct {
|
||||||
hash util.Uint160
|
hash util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BaseWriter is a transaction-creating interface for common divisible and
|
||||||
|
// non-divisible NEP-11 methods. It simplifies reusing this set of methods,
|
||||||
|
// but a complete Base is expected to be used in other packages.
|
||||||
|
type BaseWriter struct {
|
||||||
|
hash util.Uint160
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
// Base is a state-changing interface for common divisible and non-divisible NEP-11
|
// Base is a state-changing interface for common divisible and non-divisible NEP-11
|
||||||
// methods.
|
// methods.
|
||||||
type Base struct {
|
type Base struct {
|
||||||
BaseReader
|
BaseReader
|
||||||
|
BaseWriter
|
||||||
actor Actor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransferEvent represents a Transfer event as defined in the NEP-11 standard.
|
// TransferEvent represents a Transfer event as defined in the NEP-11 standard.
|
||||||
|
@ -83,7 +90,7 @@ func NewBaseReader(invoker Invoker, hash util.Uint160) *BaseReader {
|
||||||
// NewBase creates an instance of Base for contract with the given
|
// NewBase creates an instance of Base for contract with the given
|
||||||
// hash using the given actor.
|
// hash using the given actor.
|
||||||
func NewBase(actor Actor, hash util.Uint160) *Base {
|
func NewBase(actor Actor, hash util.Uint160) *Base {
|
||||||
return &Base{*NewBaseReader(actor, hash), actor}
|
return &Base{*NewBaseReader(actor, hash), BaseWriter{hash, actor}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties returns a set of token's properties such as name or URL. The map
|
// Properties returns a set of token's properties such as name or URL. The map
|
||||||
|
@ -142,7 +149,7 @@ func (t *BaseReader) TokensOfExpanded(account util.Uint160, num int) ([][]byte,
|
||||||
// transaction if it's not true. It works for divisible NFTs only when there is
|
// transaction if it's not true. It works for divisible NFTs only when there is
|
||||||
// one owner for the particular token. The returned values are transaction hash,
|
// one owner for the particular token. The returned values are transaction hash,
|
||||||
// its ValidUntilBlock value and an error if any.
|
// its ValidUntilBlock value and an error if any.
|
||||||
func (t *Base) Transfer(to util.Uint160, id []byte, data interface{}) (util.Uint256, uint32, error) {
|
func (t *BaseWriter) Transfer(to util.Uint160, id []byte, data interface{}) (util.Uint256, uint32, error) {
|
||||||
script, err := t.transferScript(to, id, data)
|
script, err := t.transferScript(to, id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint256{}, 0, err
|
return util.Uint256{}, 0, err
|
||||||
|
@ -155,7 +162,7 @@ func (t *Base) Transfer(to util.Uint160, id []byte, data interface{}) (util.Uint
|
||||||
// transaction if it's not true. It works for divisible NFTs only when there is
|
// transaction if it's not true. It works for divisible NFTs only when there is
|
||||||
// one owner for the particular token. This transaction is signed, but not sent
|
// one owner for the particular token. This transaction is signed, but not sent
|
||||||
// to the network, instead it's returned to the caller.
|
// to the network, instead it's returned to the caller.
|
||||||
func (t *Base) TransferTransaction(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error) {
|
func (t *BaseWriter) TransferTransaction(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error) {
|
||||||
script, err := t.transferScript(to, id, data)
|
script, err := t.transferScript(to, id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -168,7 +175,7 @@ func (t *Base) TransferTransaction(to util.Uint160, id []byte, data interface{})
|
||||||
// transaction if it's not true. It works for divisible NFTs only when there is
|
// transaction if it's not true. It works for divisible NFTs only when there is
|
||||||
// one owner for the particular token. This transaction is not signed and just
|
// one owner for the particular token. This transaction is not signed and just
|
||||||
// returned to the caller.
|
// returned to the caller.
|
||||||
func (t *Base) TransferUnsigned(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error) {
|
func (t *BaseWriter) TransferUnsigned(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error) {
|
||||||
script, err := t.transferScript(to, id, data)
|
script, err := t.transferScript(to, id, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -176,7 +183,7 @@ func (t *Base) TransferUnsigned(to util.Uint160, id []byte, data interface{}) (*
|
||||||
return t.actor.MakeUnsignedRun(script, nil)
|
return t.actor.MakeUnsignedRun(script, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Base) transferScript(params ...interface{}) ([]byte, error) {
|
func (t *BaseWriter) transferScript(params ...interface{}) ([]byte, error) {
|
||||||
return smartcontract.CreateCallWithAssertScript(t.hash, "transfer", params...)
|
return smartcontract.CreateCallWithAssertScript(t.hash, "transfer", params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ type DivisibleReader struct {
|
||||||
|
|
||||||
// Divisible is a state-changing interface for divisible NEP-11 contract.
|
// Divisible is a state-changing interface for divisible NEP-11 contract.
|
||||||
type Divisible struct {
|
type Divisible struct {
|
||||||
Base
|
DivisibleReader
|
||||||
|
BaseWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnerIterator is used for iterating over OwnerOf (for divisible NFTs) results.
|
// OwnerIterator is used for iterating over OwnerOf (for divisible NFTs) results.
|
||||||
|
@ -37,7 +38,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{*NewBase(actor, hash)}
|
return &Divisible{*NewDivisibleReader(actor, hash), 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
|
||||||
|
@ -66,24 +67,6 @@ func (t *DivisibleReader) BalanceOfD(owner util.Uint160, token []byte) (*big.Int
|
||||||
return unwrap.BigInt(t.invoker.Call(t.hash, "balanceOf", owner, token))
|
return unwrap.BigInt(t.invoker.Call(t.hash, "balanceOf", owner, token))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnerOf is the same as (*DivisibleReader).OwnerOf.
|
|
||||||
func (t *Divisible) OwnerOf(token []byte) (*OwnerIterator, error) {
|
|
||||||
r := DivisibleReader{t.BaseReader}
|
|
||||||
return r.OwnerOf(token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OwnerOfExpanded is the same as (*DivisibleReader).OwnerOfExpanded.
|
|
||||||
func (t *Divisible) OwnerOfExpanded(token []byte, num int) ([]util.Uint160, error) {
|
|
||||||
r := DivisibleReader{t.BaseReader}
|
|
||||||
return r.OwnerOfExpanded(token, num)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BalanceOfD is the same as (*DivisibleReader).BalanceOfD.
|
|
||||||
func (t *Divisible) BalanceOfD(owner util.Uint160, token []byte) (*big.Int, error) {
|
|
||||||
r := DivisibleReader{t.BaseReader}
|
|
||||||
return r.BalanceOfD(owner, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransferD is a divisible version of (*Base).Transfer, allowing to transfer a
|
// TransferD is a divisible version of (*Base).Transfer, allowing to transfer a
|
||||||
// part of NFT. It creates and sends a transaction that performs a `transfer`
|
// part of NFT. It creates and sends a transaction that performs a `transfer`
|
||||||
// method call using the given parameters and checks for this call result,
|
// method call using the given parameters and checks for this call result,
|
||||||
|
|
|
@ -12,7 +12,8 @@ type NonDivisibleReader struct {
|
||||||
|
|
||||||
// NonDivisible is a state-changing interface for non-divisble NEP-11 contract.
|
// NonDivisible is a state-changing interface for non-divisble NEP-11 contract.
|
||||||
type NonDivisible struct {
|
type NonDivisible struct {
|
||||||
Base
|
NonDivisibleReader
|
||||||
|
BaseWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNonDivisibleReader creates an instance of NonDivisibleReader for a contract
|
// NewNonDivisibleReader creates an instance of NonDivisibleReader for a contract
|
||||||
|
@ -24,16 +25,10 @@ func NewNonDivisibleReader(invoker Invoker, hash util.Uint160) *NonDivisibleRead
|
||||||
// NewNonDivisible creates an instance of NonDivisible for a contract
|
// NewNonDivisible creates an instance of NonDivisible for a contract
|
||||||
// with the given hash using the given actor.
|
// with the given hash using the given actor.
|
||||||
func NewNonDivisible(actor Actor, hash util.Uint160) *NonDivisible {
|
func NewNonDivisible(actor Actor, hash util.Uint160) *NonDivisible {
|
||||||
return &NonDivisible{*NewBase(actor, hash)}
|
return &NonDivisible{*NewNonDivisibleReader(actor, hash), BaseWriter{hash, actor}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnerOf returns the owner of the given NFT.
|
// OwnerOf returns the owner of the given NFT.
|
||||||
func (t *NonDivisibleReader) OwnerOf(token []byte) (util.Uint160, error) {
|
func (t *NonDivisibleReader) OwnerOf(token []byte) (util.Uint160, error) {
|
||||||
return unwrap.Uint160(t.invoker.Call(t.hash, "ownerOf", token))
|
return unwrap.Uint160(t.invoker.Call(t.hash, "ownerOf", token))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnerOf is the same as (*NonDivisibleReader).OwnerOf.
|
|
||||||
func (t *NonDivisible) OwnerOf(token []byte) (util.Uint160, error) {
|
|
||||||
r := NonDivisibleReader{t.BaseReader}
|
|
||||||
return r.OwnerOf(token)
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,12 +36,19 @@ type TokenReader struct {
|
||||||
neptoken.Base
|
neptoken.Base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TokenWriter contains NEP-17 token methods that change state. It's not meant
|
||||||
|
// to be used directly (Token that includes it is more convenient) and just
|
||||||
|
// separates one set of methods from another to simplify reusing this package
|
||||||
|
// for other contracts that extend NEP-17 interface.
|
||||||
|
type TokenWriter struct {
|
||||||
|
hash util.Uint160
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
// Token provides full NEP-17 interface, both safe and state-changing methods.
|
// Token provides full NEP-17 interface, both safe and state-changing methods.
|
||||||
type Token struct {
|
type Token struct {
|
||||||
TokenReader
|
TokenReader
|
||||||
|
TokenWriter
|
||||||
hash util.Uint160
|
|
||||||
actor Actor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransferEvent represents a Transfer event as defined in the NEP-17 standard.
|
// TransferEvent represents a Transfer event as defined in the NEP-17 standard.
|
||||||
|
@ -68,14 +75,14 @@ func NewReader(invoker Invoker, hash util.Uint160) *TokenReader {
|
||||||
// New creates an instance of Token for contract with the given hash
|
// New creates an instance of Token for contract with the given hash
|
||||||
// using the given Actor.
|
// using the given Actor.
|
||||||
func New(actor Actor, hash util.Uint160) *Token {
|
func New(actor Actor, hash util.Uint160) *Token {
|
||||||
return &Token{*NewReader(actor, hash), hash, actor}
|
return &Token{*NewReader(actor, hash), TokenWriter{hash, actor}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer creates and sends a transaction that performs a `transfer` method
|
// Transfer creates and sends a transaction that performs a `transfer` method
|
||||||
// call using the given parameters and checks for this call result, failing the
|
// call using the given parameters and checks for this call result, failing the
|
||||||
// transaction if it's not true. The returned values are transaction hash, its
|
// transaction if it's not true. The returned values are transaction hash, its
|
||||||
// ValidUntilBlock value and an error if any.
|
// ValidUntilBlock value and an error if any.
|
||||||
func (t *Token) Transfer(from util.Uint160, to util.Uint160, amount *big.Int, data interface{}) (util.Uint256, uint32, error) {
|
func (t *TokenWriter) Transfer(from util.Uint160, to util.Uint160, amount *big.Int, data interface{}) (util.Uint256, uint32, error) {
|
||||||
return t.MultiTransfer([]TransferParameters{{from, to, amount, data}})
|
return t.MultiTransfer([]TransferParameters{{from, to, amount, data}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +90,7 @@ func (t *Token) Transfer(from util.Uint160, to util.Uint160, amount *big.Int, da
|
||||||
// call using the given parameters and checks for this call result, failing the
|
// call using the given parameters and checks for this call result, failing the
|
||||||
// transaction if it's not true. This transaction is signed, but not sent to the
|
// transaction if it's not true. This transaction is signed, but not sent to the
|
||||||
// network, instead it's returned to the caller.
|
// network, instead it's returned to the caller.
|
||||||
func (t *Token) TransferTransaction(from util.Uint160, to util.Uint160, amount *big.Int, data interface{}) (*transaction.Transaction, error) {
|
func (t *TokenWriter) TransferTransaction(from util.Uint160, to util.Uint160, amount *big.Int, data interface{}) (*transaction.Transaction, error) {
|
||||||
return t.MultiTransferTransaction([]TransferParameters{{from, to, amount, data}})
|
return t.MultiTransferTransaction([]TransferParameters{{from, to, amount, data}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,11 +98,11 @@ func (t *Token) TransferTransaction(from util.Uint160, to util.Uint160, amount *
|
||||||
// call using the given parameters and checks for this call result, failing the
|
// call using the given parameters and checks for this call result, failing the
|
||||||
// transaction if it's not true. This transaction is not signed and just returned
|
// transaction if it's not true. This transaction is not signed and just returned
|
||||||
// to the caller.
|
// to the caller.
|
||||||
func (t *Token) TransferUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, data interface{}) (*transaction.Transaction, error) {
|
func (t *TokenWriter) TransferUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, data interface{}) (*transaction.Transaction, error) {
|
||||||
return t.MultiTransferUnsigned([]TransferParameters{{from, to, amount, data}})
|
return t.MultiTransferUnsigned([]TransferParameters{{from, to, amount, data}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Token) multiTransferScript(params []TransferParameters) ([]byte, error) {
|
func (t *TokenWriter) multiTransferScript(params []TransferParameters) ([]byte, error) {
|
||||||
if len(params) == 0 {
|
if len(params) == 0 {
|
||||||
return nil, errors.New("at least one transfer parameter required")
|
return nil, errors.New("at least one transfer parameter required")
|
||||||
}
|
}
|
||||||
|
@ -113,7 +120,7 @@ func (t *Token) multiTransferScript(params []TransferParameters) ([]byte, error)
|
||||||
// many times as needed (with ASSERTs added, so if any of these transfers fail
|
// many times as needed (with ASSERTs added, so if any of these transfers fail
|
||||||
// whole transaction (with all transfers) fails). The values returned are the
|
// whole transaction (with all transfers) fails). The values returned are the
|
||||||
// same as in Transfer.
|
// same as in Transfer.
|
||||||
func (t *Token) MultiTransfer(params []TransferParameters) (util.Uint256, uint32, error) {
|
func (t *TokenWriter) MultiTransfer(params []TransferParameters) (util.Uint256, uint32, error) {
|
||||||
script, err := t.multiTransferScript(params)
|
script, err := t.multiTransferScript(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint256{}, 0, err
|
return util.Uint256{}, 0, err
|
||||||
|
@ -123,7 +130,7 @@ func (t *Token) MultiTransfer(params []TransferParameters) (util.Uint256, uint32
|
||||||
|
|
||||||
// MultiTransferTransaction is similar to MultiTransfer, but returns the same values
|
// MultiTransferTransaction is similar to MultiTransfer, but returns the same values
|
||||||
// as TransferTransaction (signed transaction that is not yet sent).
|
// as TransferTransaction (signed transaction that is not yet sent).
|
||||||
func (t *Token) MultiTransferTransaction(params []TransferParameters) (*transaction.Transaction, error) {
|
func (t *TokenWriter) MultiTransferTransaction(params []TransferParameters) (*transaction.Transaction, error) {
|
||||||
script, err := t.multiTransferScript(params)
|
script, err := t.multiTransferScript(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -133,7 +140,7 @@ func (t *Token) MultiTransferTransaction(params []TransferParameters) (*transact
|
||||||
|
|
||||||
// MultiTransferUnsigned is similar to MultiTransfer, but returns the same values
|
// MultiTransferUnsigned is similar to MultiTransfer, but returns the same values
|
||||||
// as TransferUnsigned (not yet signed transaction).
|
// as TransferUnsigned (not yet signed transaction).
|
||||||
func (t *Token) MultiTransferUnsigned(params []TransferParameters) (*transaction.Transaction, error) {
|
func (t *TokenWriter) MultiTransferUnsigned(params []TransferParameters) (*transaction.Transaction, error) {
|
||||||
script, err := t.multiTransferScript(params)
|
script, err := t.multiTransferScript(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in a new issue