Documentation ¶
Overview ¶
Package nep11 contains RPC wrappers for NEP-11 contracts.
The set of types provided is split between common NEP-11 methods (BaseReader and Base types) and divisible (DivisibleReader and Divisible) and non-divisible (NonDivisibleReader and NonDivisible). If you don't know the type of NEP-11 contract you're going to use you can use Base and BaseReader types for many purposes, otherwise more specific types are recommended.
Index ¶
- func UnwrapKnownProperties(m *stackitem.Map, err error) (map[string]string, error)
- type Actor
- type Base
- type BaseReader
- func (t *BaseReader) Properties(token []byte) (*stackitem.Map, error)
- func (t *BaseReader) Tokens() (*TokenIterator, error)
- func (t *BaseReader) TokensExpanded(num int) ([][]byte, error)
- func (t *BaseReader) TokensOf(account util.Uint160) (*TokenIterator, error)
- func (t *BaseReader) TokensOfExpanded(account util.Uint160, num int) ([][]byte, error)
- type BaseWriter
- func (t *BaseWriter) Transfer(to util.Uint160, id []byte, data interface{}) (util.Uint256, uint32, error)
- func (t *BaseWriter) TransferTransaction(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error)
- func (t *BaseWriter) TransferUnsigned(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error)
- type Divisible
- type DivisibleReader
- type DivisibleWriter
- func (t *DivisibleWriter) TransferD(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, ...) (util.Uint256, uint32, error)
- func (t *DivisibleWriter) TransferDTransaction(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, ...) (*transaction.Transaction, error)
- func (t *DivisibleWriter) TransferDUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, ...) (*transaction.Transaction, error)
- type Invoker
- type NonDivisible
- type NonDivisibleReader
- type OwnerIterator
- type TokenIterator
- type TransferEvent
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func UnwrapKnownProperties ¶
UnwrapKnownProperties can be used as a proxy function to extract well-known NEP-11 properties (name/description/image/tokenURI) defined in the standard. These properties are checked to be valid UTF-8 strings, but can contain control codes or special characters.
Types ¶
type Actor ¶
type Actor interface { Invoker MakeRun(script []byte) (*transaction.Transaction, error) MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error) SendRun(script []byte) (util.Uint256, uint32, error) }
Actor is used by complete NEP-11 types to create and send transactions.
type Base ¶
type Base struct { BaseReader BaseWriter }
Base is a state-changing interface for common divisible and non-divisible NEP-11 methods.
type BaseReader ¶
BaseReader is a reader interface for common divisible and non-divisible NEP-11 methods. It allows to invoke safe methods.
func NewBaseReader ¶
func NewBaseReader(invoker Invoker, hash util.Uint160) *BaseReader
NewBaseReader creates an instance of BaseReader for a contract with the given hash using the given invoker.
func (*BaseReader) Properties ¶
func (t *BaseReader) Properties(token []byte) (*stackitem.Map, error)
Properties returns a set of token's properties such as name or URL. The map is returned as is from this method (stack item) for maximum flexibility, contracts can return a lot of specific data there. Most of the time though they return well-defined properties outlined in NEP-11 and UnwrapKnownProperties can be used to get them in more convenient way. It's an optional method per NEP-11 specification, so it can fail.
func (*BaseReader) Tokens ¶
func (t *BaseReader) Tokens() (*TokenIterator, error)
Tokens returns an iterator that allows to retrieve all tokens minted by the contract. It depends on the server to provide proper session-based iterator, but can also work with expanded one. The method itself is optional per NEP-11 specification, so it can fail.
func (*BaseReader) TokensExpanded ¶
func (t *BaseReader) TokensExpanded(num int) ([][]byte, error)
TokensExpanded uses the same NEP-11 method as Tokens, but can be useful if the server used doesn't support sessions and doesn't expand iterators. It creates a script that will get num of result items from the iterator right in the VM and return them to you. It's only limited by VM stack and GAS available for RPC invocations.
func (*BaseReader) TokensOf ¶
func (t *BaseReader) TokensOf(account util.Uint160) (*TokenIterator, error)
TokensOf returns an iterator that allows to walk through all tokens owned by the given account. It depends on the server to provide proper session-based iterator, but can also work with expanded one.
func (*BaseReader) TokensOfExpanded ¶
TokensOfExpanded uses the same NEP-11 method as TokensOf, but can be useful if the server used doesn't support sessions and doesn't expand iterators. It creates a script that will get num of result items from the iterator right in the VM and return them to you. It's only limited by VM stack and GAS available for RPC invocations.
type BaseWriter ¶
type BaseWriter struct {
// contains filtered or unexported fields
}
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.
func (*BaseWriter) Transfer ¶
func (t *BaseWriter) Transfer(to util.Uint160, id []byte, data interface{}) (util.Uint256, uint32, error)
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. 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 (*BaseWriter) TransferTransaction ¶
func (t *BaseWriter) TransferTransaction(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error)
TransferTransaction creates 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. 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 (*BaseWriter) TransferUnsigned ¶
func (t *BaseWriter) TransferUnsigned(to util.Uint160, id []byte, data interface{}) (*transaction.Transaction, error)
TransferUnsigned creates 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. 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.
type Divisible ¶
type Divisible struct { DivisibleReader DivisibleWriter }
Divisible is a full reader interface for divisible NEP-11 contract.
Example ¶
package main import ( "context" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/wallet" ) func main() { // No error checking done at all, intentionally. w, _ := wallet.NewWalletFromFile("somewhere") defer w.Close() c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{}) // Create a simple CalledByEntry-scoped actor (assuming there is an account // inside the wallet). a, _ := actor.NewSimple(c, w.Accounts[0]) // NEP-11 contract hash. nep11Hash := util.Uint160{9, 8, 7} // Create a complete divisible contract representation. n11 := nep11.NewDivisible(a, nep11Hash) tgtAcc, _ := address.StringToUint160("NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo") // Let's tranfer all of account's tokens to some other account. tokIter, _ := n11.TokensOf(a.Sender()) for toks, err := tokIter.Next(10); err == nil && len(toks) > 0; toks, err = tokIter.Next(10) { for i := range toks { // It's a divisible token, so balance data is required in general case. balance, _ := n11.BalanceOfD(a.Sender(), toks[i]) // This creates a transaction for every token, but you can // create a script that will move multiple tokens in one // transaction with Builder from smartcontract package. txid, vub, _ := n11.TransferD(a.Sender(), tgtAcc, balance, toks[i], nil) _ = txid _ = vub } } }
Output:
type DivisibleReader ¶
type DivisibleReader struct {
BaseReader
}
DivisibleReader is a reader interface for divisible NEP-11 contract.
Example ¶
package main import ( "context" "math/big" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11" "github.com/nspcc-dev/neo-go/pkg/util" ) func main() { // No error checking done at all, intentionally. c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{}) // Safe methods are reachable with just an invoker, no need for an account there. inv := invoker.New(c, nil) // NEP-11 contract hash. nep11Hash := util.Uint160{9, 8, 7} // Divisible contract are more rare, but we can handle them too. n11 := nep11.NewDivisibleReader(inv, nep11Hash) // Get the metadata. Even though these methods are implemented in neptoken package, // they're available for NEP-11 wrappers. symbol, _ := n11.Symbol() supply, _ := n11.TotalSupply() _ = symbol _ = supply // Account hash we're interested in. accHash, _ := address.StringToUint160("NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo") // Get account balance. balance, _ := n11.BalanceOf(accHash) if balance.Sign() > 0 && balance.Cmp(big.NewInt(10)) < 0 { // We know we have a low number of tokens, so we can use a simple API to get them. toks, _ := n11.TokensOfExpanded(accHash, 10) // We can build a list of all owners of account's tokens. var owners = make([]util.Uint160, 0) for i := range toks { ownIter, _ := n11.OwnerOf(toks[i]) for ows, err := ownIter.Next(10); err == nil && len(ows) > 0; ows, err = ownIter.Next(10) { // Notice that it includes accHash too. owners = append(owners, ows...) } } // The list can be sorted/deduplicated if needed. _ = owners } }
Output:
func NewDivisibleReader ¶
func NewDivisibleReader(invoker Invoker, hash util.Uint160) *DivisibleReader
NewDivisibleReader creates an instance of DivisibleReader for a contract with the given hash using the given invoker.
func (*DivisibleReader) BalanceOfD ¶
BalanceOfD is a BalanceOf for divisible NFTs, it returns the amount of token owned by a particular account.
func (*DivisibleReader) OwnerOf ¶
func (t *DivisibleReader) OwnerOf(token []byte) (*OwnerIterator, error)
OwnerOf returns returns an iterator that allows to walk through all owners of the given token. It depends on the server to provide proper session-based iterator, but can also work with expanded one.
func (*DivisibleReader) OwnerOfExpanded ¶
OwnerOfExpanded uses the same NEP-11 method as OwnerOf, but can be useful if the server used doesn't support sessions and doesn't expand iterators. It creates a script that will get num of result items from the iterator right in the VM and return them to you. It's only limited by VM stack and GAS available for RPC invocations.
type DivisibleWriter ¶ added in v0.99.5
type DivisibleWriter struct {
BaseWriter
}
DivisibleWriter is a state-changing interface for divisible NEP-11 contract. It's mostly useful not directly, but as a reusable layer for higher-level structures.
func (*DivisibleWriter) TransferD ¶ added in v0.99.5
func (t *DivisibleWriter) TransferD(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (util.Uint256, uint32, error)
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, failing the transaction if it's not true. The returned values are transaction hash, its ValidUntilBlock value and an error if any.
func (*DivisibleWriter) TransferDTransaction ¶ added in v0.99.5
func (t *DivisibleWriter) TransferDTransaction(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (*transaction.Transaction, error)
TransferDTransaction is a divisible version of (*Base).TransferTransaction, allowing to transfer a part of NFT. It creates 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. This transaction is signed, but not sent to the network, instead it's returned to the caller.
func (*DivisibleWriter) TransferDUnsigned ¶ added in v0.99.5
func (t *DivisibleWriter) TransferDUnsigned(from util.Uint160, to util.Uint160, amount *big.Int, id []byte, data interface{}) (*transaction.Transaction, error)
TransferDUnsigned is a divisible version of (*Base).TransferUnsigned, allowing to transfer a part of NFT. It creates 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. This transaction is not signed and just returned to the caller.
type Invoker ¶
type Invoker interface { neptoken.Invoker CallAndExpandIterator(contract util.Uint160, method string, maxItems int, params ...interface{}) (*result.Invoke, error) TerminateSession(sessionID uuid.UUID) error TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error) }
Invoker is used by reader types to call various methods.
type NonDivisible ¶
type NonDivisible struct { NonDivisibleReader BaseWriter }
NonDivisible is a state-changing interface for non-divisble NEP-11 contract.
Example ¶
package main import ( "context" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/wallet" ) func main() { // No error checking done at all, intentionally. w, _ := wallet.NewWalletFromFile("somewhere") defer w.Close() c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{}) // Create a simple CalledByEntry-scoped actor (assuming there is an account // inside the wallet). a, _ := actor.NewSimple(c, w.Accounts[0]) // NEP-11 contract hash. nep11Hash := util.Uint160{9, 8, 7} // Create a complete non-divisible contract representation. n11 := nep11.NewNonDivisible(a, nep11Hash) tgtAcc, _ := address.StringToUint160("NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo") // Let's tranfer all of account's tokens to some other account. tokIter, _ := n11.TokensOf(a.Sender()) for toks, err := tokIter.Next(10); err == nil && len(toks) > 0; toks, err = tokIter.Next(10) { for i := range toks { // This creates a transaction for every token, but you can // create a script that will move multiple tokens in one // transaction with Builder from smartcontract package. txid, vub, _ := n11.Transfer(tgtAcc, toks[i], nil) _ = txid _ = vub } } }
Output:
func NewNonDivisible ¶
func NewNonDivisible(actor Actor, hash util.Uint160) *NonDivisible
NewNonDivisible creates an instance of NonDivisible for a contract with the given hash using the given actor.
type NonDivisibleReader ¶
type NonDivisibleReader struct {
BaseReader
}
NonDivisibleReader is a reader interface for non-divisble NEP-11 contract.
Example ¶
package main import ( "context" "github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11" "github.com/nspcc-dev/neo-go/pkg/util" ) func main() { // No error checking done at all, intentionally. c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{}) // Safe methods are reachable with just an invoker, no need for an account there. inv := invoker.New(c, nil) // NEP-11 contract hash. nep11Hash := util.Uint160{9, 8, 7} // Most of the time contracts are non-divisible, create a reader for nep11Hash. n11 := nep11.NewNonDivisibleReader(inv, nep11Hash) // Get the metadata. Even though these methods are implemented in neptoken package, // they're available for NEP-11 wrappers. symbol, _ := n11.Symbol() supply, _ := n11.TotalSupply() _ = symbol _ = supply // Account hash we're interested in. accHash, _ := address.StringToUint160("NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo") // Get account balance. balance, _ := n11.BalanceOf(accHash) if balance.Sign() > 0 { // There are some tokens there, let's look at them. tokIter, _ := n11.TokensOf(accHash) for toks, err := tokIter.Next(10); err == nil && len(toks) > 0; toks, err = tokIter.Next(10) { for i := range toks { // We know the owner of the token, but let's check internal contract consistency. owner, _ := n11.OwnerOf(toks[i]) if !owner.Equals(accHash) { panic("NEP-11 contract is broken!") } } } } }
Output:
func NewNonDivisibleReader ¶
func NewNonDivisibleReader(invoker Invoker, hash util.Uint160) *NonDivisibleReader
NewNonDivisibleReader creates an instance of NonDivisibleReader for a contract with the given hash using the given invoker.
type OwnerIterator ¶
type OwnerIterator struct {
// contains filtered or unexported fields
}
OwnerIterator is used for iterating over OwnerOf (for divisible NFTs) results.
func (*OwnerIterator) Next ¶
func (v *OwnerIterator) Next(num int) ([]util.Uint160, error)
Next returns the next set of elements from the iterator (up to num of them). It can return less than num elements in case iterator doesn't have that many or zero elements if the iterator has no more elements or the session is expired.
func (*OwnerIterator) Terminate ¶
func (v *OwnerIterator) Terminate() error
Terminate closes the iterator session used by OwnerIterator (if it's session-based).
type TokenIterator ¶
type TokenIterator struct {
// contains filtered or unexported fields
}
TokenIterator is used for iterating over TokensOf results.
func (*TokenIterator) Next ¶
func (v *TokenIterator) Next(num int) ([][]byte, error)
Next returns the next set of elements from the iterator (up to num of them). It can return less than num elements in case iterator doesn't have that many or zero elements if the iterator has no more elements or the session is expired.
func (*TokenIterator) Terminate ¶
func (v *TokenIterator) Terminate() error
Terminate closes the iterator session used by TokenIterator (if it's session-based).