neo

package
v0.105.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 12, 2024 License: MIT Imports: 14 Imported by: 3

Documentation

Overview

Package neo provides an RPC-based wrapper for the NEOToken contract.

Safe methods are encapsulated into ContractReader structure while Contract provides various methods to perform state-changing calls.

Index

Examples

Constants

This section is empty.

Variables

Hash stores the hash of the native NEOToken contract.

Functions

This section is empty.

Types

type Actor

type Actor interface {
	nep17.Actor
	Invoker

	Run(script []byte) (*result.Invoke, error)
	MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
	MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
	MakeUnsignedUncheckedRun(script []byte, sysFee int64, attrs []transaction.Attribute) (*transaction.Transaction, error)
	SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
	Sign(tx *transaction.Transaction) error
	SignAndSend(tx *transaction.Transaction) (util.Uint256, uint32, error)
}

Actor is used by Contract to create and send transactions.

type CandidateStateEvent

type CandidateStateEvent struct {
	Key        *keys.PublicKey
	Registered bool
	Votes      *big.Int
}

CandidateStateEvent represents a CandidateStateChanged NEO event.

type Contract

type Contract struct {
	ContractReader
	nep17.TokenWriter
	// contains filtered or unexported fields
}

Contract provides full NEO interface, both safe and state-changing methods.

Example
package main

import (
	"context"
	"math/big"
	"sort"

	"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/neo"
	"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])

	// Create a complete contract representation.
	neoToken := neo.New(a)

	tgtAcc, _ := address.StringToUint160("NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo")

	// Send a transaction that transfers one token to another account.
	txid, vub, _ := neoToken.Transfer(a.Sender(), tgtAcc, big.NewInt(1), nil)
	_ = txid
	_ = vub

	// Get a list of candidates (it's limited, but should be sufficient in most cases).
	cands, _ := neoToken.GetCandidates()

	// Sort by votes.
	sort.Slice(cands, func(i, j int) bool { return cands[i].Votes < cands[j].Votes })

	// Get the extended NEO-specific balance data.
	bNeo, _ := neoToken.GetAccountState(a.Sender())

	// If not yet voted, or voted for suboptimal candidate (we want the one with the least votes),
	// send a new voting transaction
	if bNeo.VoteTo == nil || !bNeo.VoteTo.Equal(&cands[0].PublicKey) {
		txid, vub, _ = neoToken.Vote(a.Sender(), &cands[0].PublicKey)
		_ = txid
		_ = vub
	}
}
Output:

func New

func New(actor Actor) *Contract

New creates an instance of Contract to perform state-changing actions in the NEO contract.

func (*Contract) RegisterCandidate

func (c *Contract) RegisterCandidate(k *keys.PublicKey) (util.Uint256, uint32, error)

RegisterCandidate creates and sends a transaction that adds the given key to the list of candidates that can be voted for. The return result from the "registerCandidate" method is checked to be true, so transaction fails (with FAULT state) if not successful. Notice that for this call to work it must be witnessed by the simple account derived from the given key, so use an appropriate Actor. The returned values are transaction hash, its ValidUntilBlock value and an error if any.

Notice that unlike for all other methods the script for this one is not test-executed in its final form because most networks have registration price set to be much higher than typical RPC server allows to spend during test-execution. This adds some risk that it might fail on-chain, but in practice it's not likely to happen if signers are set up correctly.

func (*Contract) RegisterCandidateTransaction

func (c *Contract) RegisterCandidateTransaction(k *keys.PublicKey) (*transaction.Transaction, error)

RegisterCandidateTransaction creates a transaction that adds the given key to the list of candidates that can be voted for. The return result from the "registerCandidate" method is checked to be true, so transaction fails (with FAULT state) if not successful. Notice that for this call to work it must be witnessed by the simple account derived from the given key, so use an appropriate Actor. The transaction is signed, but not sent to the network, instead it's returned to the caller.

Notice that unlike for all other methods the script for this one is not test-executed in its final form because most networks have registration price set to be much higher than typical RPC server allows to spend during test-execution. This adds some risk that it might fail on-chain, but in practice it's not likely to happen if signers are set up correctly.

func (*Contract) RegisterCandidateUnsigned

func (c *Contract) RegisterCandidateUnsigned(k *keys.PublicKey) (*transaction.Transaction, error)

RegisterCandidateUnsigned creates a transaction that adds the given key to the list of candidates that can be voted for. The return result from the "registerCandidate" method is checked to be true, so transaction fails (with FAULT state) if not successful. Notice that for this call to work it must be witnessed by the simple account derived from the given key, so use an appropriate Actor. The transaction is not signed and just returned to the caller.

Notice that unlike for all other methods the script for this one is not test-executed in its final form because most networks have registration price set to be much higher than typical RPC server allows to spend during test-execution. This adds some risk that it might fail on-chain, but in practice it's not likely to happen if signers are set up correctly.

func (*Contract) SetGasPerBlock

func (c *Contract) SetGasPerBlock(gas int64) (util.Uint256, uint32, error)

SetGasPerBlock creates and sends a transaction that sets the new amount of GAS to be generated in each block. The action is successful when transaction ends in HALT state. Notice that this setting can be changed only by the network's committee, so use an appropriate Actor. The returned values are transaction hash, its ValidUntilBlock value and an error if any.

func (*Contract) SetGasPerBlockTransaction

func (c *Contract) SetGasPerBlockTransaction(gas int64) (*transaction.Transaction, error)

SetGasPerBlockTransaction creates a transaction that sets the new amount of GAS to be generated in each block. The action is successful when transaction ends in HALT state. Notice that this setting can be changed only by the network's committee, so use an appropriate Actor. The transaction is signed, but not sent to the network, instead it's returned to the caller.

func (*Contract) SetGasPerBlockUnsigned

func (c *Contract) SetGasPerBlockUnsigned(gas int64) (*transaction.Transaction, error)

SetGasPerBlockUnsigned creates a transaction that sets the new amount of GAS to be generated in each block. The action is successful when transaction ends in HALT state. Notice that this setting can be changed only by the network's committee, so use an appropriate Actor. The transaction is not signed and just returned to the caller.

func (*Contract) SetRegisterPrice

func (c *Contract) SetRegisterPrice(price int64) (util.Uint256, uint32, error)

SetRegisterPrice creates and sends a transaction that sets the new candidate registration price (in GAS). The action is successful when transaction ends in HALT state. Notice that this setting can be changed only by the network's committee, so use an appropriate Actor. The returned values are transaction hash, its ValidUntilBlock value and an error if any.

func (*Contract) SetRegisterPriceTransaction

func (c *Contract) SetRegisterPriceTransaction(price int64) (*transaction.Transaction, error)

SetRegisterPriceTransaction creates a transaction that sets the new candidate registration price (in GAS). The action is successful when transaction ends in HALT state. Notice that this setting can be changed only by the network's committee, so use an appropriate Actor. The transaction is signed, but not sent to the network, instead it's returned to the caller.

func (*Contract) SetRegisterPriceUnsigned

func (c *Contract) SetRegisterPriceUnsigned(price int64) (*transaction.Transaction, error)

SetRegisterPriceUnsigned creates a transaction that sets the new candidate registration price (in GAS). The action is successful when transaction ends in HALT state. Notice that this setting can be changed only by the network's committee, so use an appropriate Actor. The transaction is not signed and just returned to the caller.

func (*Contract) UnregisterCandidate

func (c *Contract) UnregisterCandidate(k *keys.PublicKey) (util.Uint256, uint32, error)

UnregisterCandidate creates and sends a transaction that removes the key from the list of candidates that can be voted for. The return result from the "unregisterCandidate" method is checked to be true, so transaction fails (with FAULT state) if not successful. Notice that for this call to work it must be witnessed by the simple account derived from the given key, so use an appropriate Actor. The returned values are transaction hash, its ValidUntilBlock value and an error if any.

func (*Contract) UnregisterCandidateTransaction

func (c *Contract) UnregisterCandidateTransaction(k *keys.PublicKey) (*transaction.Transaction, error)

UnregisterCandidateTransaction creates a transaction that removes the key from the list of candidates that can be voted for. The return result from the "unregisterCandidate" method is checked to be true, so transaction fails (with FAULT state) if not successful. Notice that for this call to work it must be witnessed by the simple account derived from the given key, so use an appropriate Actor. The transaction is signed, but not sent to the network, instead it's returned to the caller.

func (*Contract) UnregisterCandidateUnsigned

func (c *Contract) UnregisterCandidateUnsigned(k *keys.PublicKey) (*transaction.Transaction, error)

UnregisterCandidateUnsigned creates a transaction that removes the key from the list of candidates that can be voted for. The return result from the "unregisterCandidate" method is checked to be true, so transaction fails (with FAULT state) if not successful. Notice that for this call to work it must be witnessed by the simple account derived from the given key, so use an appropriate Actor. The transaction is not signed and just returned to the caller.

func (*Contract) Vote

func (c *Contract) Vote(account util.Uint160, voteTo *keys.PublicKey) (util.Uint256, uint32, error)

Vote creates and sends a transaction that casts a vote from the given account to the given key which can be nil (in which case any previous vote is removed). The return result from the "vote" method is checked to be true, so transaction fails (with FAULT state) if voting is not successful. The returned values are transaction hash, its ValidUntilBlock value and an error if any.

func (*Contract) VoteTransaction

func (c *Contract) VoteTransaction(account util.Uint160, voteTo *keys.PublicKey) (*transaction.Transaction, error)

VoteTransaction creates a transaction that casts a vote from the given account to the given key which can be nil (in which case any previous vote is removed). The return result from the "vote" method is checked to be true, so transaction fails (with FAULT state) if voting is not successful. The transaction is signed, but not sent to the network, instead it's returned to the caller.

func (*Contract) VoteUnsigned

func (c *Contract) VoteUnsigned(account util.Uint160, voteTo *keys.PublicKey) (*transaction.Transaction, error)

VoteUnsigned creates a transaction that casts a vote from the given account to the given key which can be nil (in which case any previous vote is removed). The return result from the "vote" method is checked to be true, so transaction fails (with FAULT state) if voting is not successful. The transaction is not signed and just returned to the caller.

type ContractReader

type ContractReader struct {
	nep17.TokenReader
	// contains filtered or unexported fields
}

ContractReader represents safe (read-only) methods of NEO. It can be used to query various data.

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/neo"
)

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)

	// Create a reader interface.
	neoToken := neo.NewReader(inv)

	// Account hash we're interested in.
	accHash, _ := address.StringToUint160("NdypBhqkz2CMMnwxBgvoC9X2XjKF5axgKo")

	// Get the account balance.
	balance, _ := neoToken.BalanceOf(accHash)
	_ = balance

	// Get the extended NEO-specific balance data.
	bNeo, _ := neoToken.GetAccountState(accHash)

	// Account can have no associated vote.
	if bNeo.VoteTo == nil {
		return
	}
	// Committee keys.
	comm, _ := neoToken.GetCommittee()

	// Check if the vote is made for a committee member.
	var votedForCommitteeMember bool
	for i := range comm {
		if bNeo.VoteTo.Equal(comm[i]) {
			votedForCommitteeMember = true
			break
		}
	}
	_ = votedForCommitteeMember
}
Output:

func NewReader

func NewReader(invoker Invoker) *ContractReader

NewReader creates an instance of ContractReader to get data from the NEO contract.

func (*ContractReader) GetAccountState

func (c *ContractReader) GetAccountState(account util.Uint160) (*state.NEOBalance, error)

GetAccountState returns current NEO balance state for the account which includes balance and voting data. It can return nil balance with no error if the account given has no NEO.

func (*ContractReader) GetAllCandidates

func (c *ContractReader) GetAllCandidates() (*ValidatorIterator, error)

GetAllCandidates returns an iterator that allows to retrieve all registered validators from it. It depends on the server to provide proper session-based iterator, but can also work with expanded one.

func (*ContractReader) GetAllCandidatesExpanded

func (c *ContractReader) GetAllCandidatesExpanded(num int) ([]result.Validator, error)

GetAllCandidatesExpanded is similar to GetAllCandidates (uses the same NEO method), 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 (*ContractReader) GetCandidates

func (c *ContractReader) GetCandidates() ([]result.Validator, error)

GetCandidates returns the list of validators with their vote count. This method is mostly useful for historic invocations because the RPC protocol provides direct getcandidates call that returns more data and works faster. The contract only returns up to 256 candidates in response to this method, so if there are more of them on the network you will get a truncated result, use GetAllCandidates to solve this problem.

func (*ContractReader) GetCommittee

func (c *ContractReader) GetCommittee() (keys.PublicKeys, error)

GetCommittee returns the list of committee member public keys. This method is mostly useful for historic invocations because the RPC protocol provides direct getcommittee call that works faster.

func (*ContractReader) GetGasPerBlock

func (c *ContractReader) GetGasPerBlock() (int64, error)

GetGasPerBlock returns the amount of GAS generated in each block.

func (*ContractReader) GetNextBlockValidators

func (c *ContractReader) GetNextBlockValidators() (keys.PublicKeys, error)

GetNextBlockValidators returns the list of validator keys that will sign the next block. This method is mostly useful for historic invocations because the RPC protocol provides direct getnextblockvalidators call that provides more data and works faster.

func (*ContractReader) GetRegisterPrice

func (c *ContractReader) GetRegisterPrice() (int64, error)

GetRegisterPrice returns the price of candidate key registration.

func (*ContractReader) UnclaimedGas

func (c *ContractReader) UnclaimedGas(account util.Uint160, end uint32) (*big.Int, error)

UnclaimedGas allows to calculate the amount of GAS that will be generated if any NEO state change ("claim") is to happen for the given account at the given block number. This method is mostly useful for historic invocations because the RPC protocol provides direct getunclaimedgas method that works faster.

type Invoker

type Invoker interface {
	nep17.Invoker

	CallAndExpandIterator(contract util.Uint160, method string, maxItems int, params ...any) (*result.Invoke, error)
	TerminateSession(sessionID uuid.UUID) error
	TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error)
}

Invoker is used by ContractReader to perform read-only calls.

type ValidatorIterator

type ValidatorIterator struct {
	// contains filtered or unexported fields
}

ValidatorIterator is used for iterating over GetAllCandidates results.

func (*ValidatorIterator) Next

func (v *ValidatorIterator) Next(num int) ([]result.Validator, 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 (*ValidatorIterator) Terminate

func (v *ValidatorIterator) Terminate() error

Terminate closes the iterator session used by ValidatorIterator (if it's session-based).

type VoteEvent

type VoteEvent struct {
	Account util.Uint160
	From    *keys.PublicKey
	To      *keys.PublicKey
	Amount  *big.Int
}

VoteEvent represents a Vote NEO event.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL