RPC
Go Client for the Tezos RPC
The RPC package defines a common client object that wraps a HTTP/TLS connection and offers an extensive list of RPC calls to
- query the state of a Tezos node (
GetStatus()
andGetVersionInfo()
) - fetch blocks and operations (
GetBlock()
,GetBlockHeader()
,GetBlockOperation()
, etc) - fetch mempool contents (
GetMempool()
) - monitor for events (
MonitorBlockHeader()
,MonitorMempool()
, etc) - query accounts, delegates and contract state (e.g.
GetContract()
,GetDelegate()
,GetContractStorage()
,GetBigmapValue()
, etc) - query delegate baking rights, rolls, snapshots
- query voting data such as lists of voters, ballots, proposals and voting stats
- run/simulate code, views, operations and broadcast operations
Note that the Tezos RPC uses the term contract for both accounts and smart contracts in its path arguments. To avoid confusion we use the same terminology here.
TzGo does not ship a list of public RPC endpoints or a default setting. To create an RPC client you need to provide a URL to either your own node or a public Tezos RPC provider.
// init RPC client with a custom testnet URL
c, _ := rpc.NewClient("https://rpc.hangzhou.tzstats.com", nil)
// optionally fetch the chain configuration; this populates c.Params
// and c.ChainId which is required for some high-level features;
// it also tells you whether the RPC endpoint work or not
err := c.Iinit(ctx)
if err != nil {
log.Fatalln(err)
}
TzGo's
rpc.NewClient()
function takes an optional Go http.Client
as parameter which you can configure before or after passing it to the library. The example below shows how to set custom timeouts and disable TLS certificate checks (not recommended in production, but useful if you use self-signed certificates during testing).import (
"crypto/tls"
"log"
"net"
"net/http"
"blockwatch.cc/tzgo/rpc"
)
func main() {
hc := &http.Client{
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 2 * time.Second,
KeepAlive: 180 * time.Second,
}).Dial,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
}
}
}
c, err := rpc.NewClient("https://my-private-node.local:8732", hc)
if err != nil {
log.Fatalln(err)
}
}
TzGo lets you easily check node status and version
// status info
GetChainId() // network id
GetStatus() // node sync status
GetVersionInfo() // node version
Many queries in TzGo's RPC package allow you to select a block to run the query against. That way you can access historic state of accounts, contracts or bigmaps if you execute the query against a full archive node. TzGo provides several ways to express block identity using
rpc.BlockLevel
for block heights (this may be ambiguous during reorgs)rpc.Head
orrpc.Genesis
as alias names- a
tezos.BlockHash
(is best choice) rpc.BlockOffset
to define a positive or negative offset from a given identity
// a hash as block id
hash := tezos.MustParseHash("BM3Y475mu61aTrTgpPdzU7EQVP8T9cReGBuqSU5wEht2gmSN5Ro")
// a block level
lvl := rpc.BlockLevel(2019913)
// positive block offset, e.g. 10 blocks after block BM3Y475...
after := rpc.NewBlockOffset(hash, 10)
// negative block offset, e.g. 10 blocks behind Head
before := rpc.NewBlockOffset(rpc.Head, -10)
Tezos blocks contain receipts for confirmed operations plus some consensus-related metadata. A block's identity is uniquely defined by its block hash. The position inside the chain is defined by the block's level and relations between blocks are expressed by a predecessor hash in each block's metadata. Following predecessor hashes backwards walks the entire chain back in history. Block queries can use different identifiers to select a block (see above).
Operations inside a block are assigned to 4 lists according to their type (0) consensus, (1) voting, (2) special and (3) user transactions. An operation in Tezos contains a common header that defines provenance information plus some non-empty content which may be a single transaction or a list of multiple transactions. Transactions are typed and each type contains data that has been sent and signed by a user's wallet plus metadata that has been added as an execution receipt by the Tezos blockchain. Receipts contain balance updates for transfers and fee payments as well as a result which lists all state changes in response to the execution of a transaction. Some smart contract calls can initiate calls to other contracts. If that's the case, an additional internal result list is present.
TzGo's RPC client offers several functions to query blocks, operations and follow the chain of blocks (a non-exhaustive list):
// query block contents (/chains/main/blocks/:id)
GetBlock() // single block including all operations
GetBlockHeader() // single block header only
GetBlockHash() // single block hash
// query block hashes (/chains/main/...)
GetTips() // list most recent block hashes, first is head
GetBlockPredHashes() // list predecessor hashes starting at a given block
GetInvalidBlocks() // list recent invalid blocks (side-chains)
GetInvalidBlock() // single invalid block
// query operation hashes (/chains/main/blocks/:id/operation_hashes/*/*)
GetBlockOperationHashes() // all hashes from all lists
GetBlockOperationListHashes() // all hashes from a given list
GetBlockOperationHash() // single hash
// query operations contents (/chains/main/blocks/:id/operations/*/*)
GetBlockOperations() // all operations from all lists
GetBlockOperationList() // all operations from a given list
GetBlockOperation() // single operation
In addition, TzGo's RPC client supports calls to stream new blocks and mempool data.
// streaming events
MonitorBootstrapped() // wait for node to finish initial sync
MonitorBlockHeader() // stream new block headers (also during reorgs)
MonitorMempool() // stream new operations entering the mempool
Blocks represent the history of updates, but many applications require the current state of an account or some historic state in the past. Both is possible by using a BlockID, for the current block use the
rpc.Head
constant, for a historic block use its hash or level. Note Tezos RPC paths do not distinguish between end user accounts (tz1/tz2/tz3) and smart contracts (KT1), and account calls are named 'contract'. The TzGo client exports the following functions to query account data.
# query accounts (/chains/main/blocks/:id/context/contracts/:address)
GetContract() // account info (balance, counter, delegate)
GetContractScript() // smart contract code
GetContractStorage() // smart contract storage
GetContractEntrypoints() // smart contract entrypoints
# query bakers (/chains/main/blocks/:id/context/delegates/:address)
GetDelegate() // baker info (balances, delegators)
ListActiveDelegates() // addresses of active bakers
# query bigmap data (/chains/main/blocks/:id/context/big_maps/:ptr)
GetBigmapInfo() // key/value types and size
GetBigmapValue() // single value (Micheline primitives)
ListBigmapKeys() // SLOW (!) list all key expr hashes
ListBigmapValues() // SLOW (!) list all values (Micheline primitives)
TzGo supports a few more calls specific to baker accounts which allow you to list baking rights and governance voting
// baker rights (chains/main/blocks/:id/helpers/baking_rights and ./endorsing_rights)
ListBakingRights() // single block
ListBakingRightsCycle() // full cycle
ListEndorsingRights() // single block
ListEndorsingRightsCycle() // full cycle
GetSnapshotIndexCycle() // snapshot block info, works pre/post Ithaca
GetRollSnapshotInfoCycle() // pre-Ithaca only
GetStakingSnapshotInfoCycle() // post-Ithaca only
ListSnapshotRollOwners() // baker key list per roll, pre-Ithaca only
// voting (chains/main/blocks/:id/votes/...)
GetVoteQuorum() // required quorum at voting period
GetVoteProposal() // winning proposal
ListBallots() // all ballots at voting period
ListProposals() // all proposals at voting period
GetVoteResult() // current status or final result
TzGo supports sending of all operation kinds including batch operations (operation groups). The typical Tezos flow of sending an operation constructed by the
codec
or contract
packages is- 1.Fill an operation or group with the desired content
- 2.Define a block as anchor (branch) to control the maximum lifetime should the operation remain unconfirmed
- 3.Complete the operation by dynamically adding a
reveal
operation to publish the signere's public key if necessary - 4.Simulate the operation to identify errors early and to estimate costs (gas and storage)
- 5.Fill in costs and fees
- 6.Serialize and sign the operation
- 7.Inject (broadcast) the signed operation
- 8.Wait for confirmation (inclusion in a block plus at least N blocks on top to be reorg safe)
Each step of the process can be executed individually step by step using available methods. Most of the time its, however, more convenient to just call
Send()
// hight-level operation for sending operations defined by RPC client
Complete() // adds reveal, sets counters, adds branch if missing
Simulate() // dry-run the operation to identify costs and catch errors
Validate() // check local serialization against Tezos node (optional)
Broadcast() // inject operation into the network
Send() // all-in-one wrapper complete/simulate/broadcast/wait
// additional low-level RPC helpers
BroadcastOperation() // inject signed binary data (low-level)
ForgeOperation() // serialized operation data remotely
RunOperation() // simulate an operation (low-level)
RunCode() // execute off-chain view or other code
RunView() // execute on-chain view
TraceCode() // debug tracing contract code
The
Send()
and Simulate()
functions on the RPC client take an optional argument CallOptions
as the last parameter which can be used for customizing the behavior per call.type CallOptions struct {
// number of confirmations to wait after broadcast
Confirmations int64
// max acceptable fee, optional (default = 0)
MaxFee int64
// max lifetime for operations in blocks
TTL int64
// ignore simulated limits and use user-defined limits from op.WithLimits()
IgnoreLimits bool
// custom signer to use for signing the transaction
Signer signer.Signer
// custom address to sign for (use when signer manages multiple addresses)
Sender tezos.Address
// custom block observer for waiting on confirmations
Observer *Observer
}
The execution result of a finalized operation is wrapped into a
Receipt
structtype Receipt struct {
Block tezos.BlockHash // block the operation was included in
List int // operation list (alwasy 3 for regular transactions)
Pos int // list position
Op *Operation // RPC operation receipt
}
// convenience wrappers on receipt
TotalCosts() // summarized gas/storage/burn/fees
Costs() // array of individual gas/storage/burn/fees
IsSuccess() // true when all contained operations are applied
Error() // returns the first (non-backtracked) error
MinLimits() // array of gas/storage limits (returned by simulation)
Last modified 1yr ago