mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 03:41:34 +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.
|
||||
type Contract struct {
|
||||
ContractReader
|
||||
nep17.Token
|
||||
nep17.TokenWriter
|
||||
|
||||
actor Actor
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ func NewReader(invoker Invoker) *ContractReader {
|
|||
// New creates an instance of Contract to perform state-changing actions in the
|
||||
// NEO 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
|
||||
|
|
|
@ -51,12 +51,19 @@ type BaseReader struct {
|
|||
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
|
||||
// methods.
|
||||
type Base struct {
|
||||
BaseReader
|
||||
|
||||
actor Actor
|
||||
BaseWriter
|
||||
}
|
||||
|
||||
// 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
|
||||
// hash using the given actor.
|
||||
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
|
||||
|
@ -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
|
||||
// one owner for the particular token. The returned values are transaction hash,
|
||||
// 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)
|
||||
if err != nil {
|
||||
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
|
||||
// one owner for the particular token. This transaction is signed, but not sent
|
||||
// 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)
|
||||
if err != nil {
|
||||
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
|
||||
// one owner for the particular token. This transaction is not signed and just
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -176,7 +183,7 @@ func (t *Base) TransferUnsigned(to util.Uint160, id []byte, data interface{}) (*
|
|||
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...)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ type DivisibleReader struct {
|
|||
|
||||
// Divisible is a state-changing interface for divisible NEP-11 contract.
|
||||
type Divisible struct {
|
||||
Base
|
||||
DivisibleReader
|
||||
BaseWriter
|
||||
}
|
||||
|
||||
// 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
|
||||
// with the given hash using the given actor.
|
||||
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
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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,
|
||||
|
|
|
@ -12,7 +12,8 @@ type NonDivisibleReader struct {
|
|||
|
||||
// NonDivisible is a state-changing interface for non-divisble NEP-11 contract.
|
||||
type NonDivisible struct {
|
||||
Base
|
||||
NonDivisibleReader
|
||||
BaseWriter
|
||||
}
|
||||
|
||||
// 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
|
||||
// with the given hash using the given actor.
|
||||
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.
|
||||
func (t *NonDivisibleReader) OwnerOf(token []byte) (util.Uint160, error) {
|
||||
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
|
||||
}
|
||||
|
||||
// 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.
|
||||
type Token struct {
|
||||
TokenReader
|
||||
|
||||
hash util.Uint160
|
||||
actor Actor
|
||||
TokenWriter
|
||||
}
|
||||
|
||||
// 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
|
||||
// using the given Actor.
|
||||
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
|
||||
// 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
|
||||
// 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}})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
// transaction if it's not true. This transaction is signed, but not sent to the
|
||||
// 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}})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
// transaction if it's not true. This transaction is not signed and just returned
|
||||
// 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}})
|
||||
}
|
||||
|
||||
func (t *Token) multiTransferScript(params []TransferParameters) ([]byte, error) {
|
||||
func (t *TokenWriter) multiTransferScript(params []TransferParameters) ([]byte, error) {
|
||||
if len(params) == 0 {
|
||||
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
|
||||
// whole transaction (with all transfers) fails). The values returned are the
|
||||
// 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)
|
||||
if err != nil {
|
||||
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
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -133,7 +140,7 @@ func (t *Token) MultiTransferTransaction(params []TransferParameters) (*transact
|
|||
|
||||
// MultiTransferUnsigned is similar to MultiTransfer, but returns the same values
|
||||
// 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
Loading…
Reference in a new issue