docs: update Go API page (#25112)
* initial commit for go-api page * refine text * Apply suggestions from code review Co-authored-by: Martin Holst Swende <martin@swende.se> * apply suggestions from review update intro para and rm "sales pitch" section * add tutorial * improvements, add filter logs example Co-authored-by: Martin Holst Swende <martin@swende.se> Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This commit is contained in:
parent
f31993644c
commit
1a86e438b3
|
@ -3,64 +3,247 @@ title: Go API
|
|||
sort_key: C
|
||||
---
|
||||
|
||||
The Ethereum blockchain along with its two extension protocols Whisper and Swarm was
|
||||
originally conceptualized to become the supporting pillar of web3, providing the
|
||||
consensus, messaging and storage backbone for a new generation of distributed (actually,
|
||||
decentralized) applications called DApps.
|
||||
Ethereum was originally conceptualized to be the base layer for [Web3][web3-link], providing
|
||||
the backbone for a new generation of decentralized, permissionless and censorship resistant
|
||||
applications called [dapps][dapp-link]. The first step towards this vision was the development
|
||||
of clients providing an RPC interface into the peer-to-peer protocols. This allowed users to
|
||||
transact between accounts and interact with smart contracts using command line tools.
|
||||
Geth was one of the original clients to provide this type of gateway to the Ethereum network.
|
||||
|
||||
The first incarnation towards this dream of web3 was a command line client providing an
|
||||
RPC interface into the peer-to-peer protocols. The client was soon enough extended with a
|
||||
web-browser-like graphical user interface, permitting developers to write DApps based on
|
||||
the tried and proven HTML/CSS/JS technologies.
|
||||
Before long, web-browser-like graphical interfaces (e.g. Mist) were created to extend clients, and
|
||||
client functions were built into websites built using the time-tested HTML/CSS/JS stack.
|
||||
However, to support the most diverse, complex dapps, developers require programmatic access to client
|
||||
functions through an API. This opens up client technologies as re-usable, composable units that
|
||||
can be applied in creative ways by a global community of developers.
|
||||
|
||||
As many DApps have more complex requirements than what a browser environment can handle,
|
||||
it became apparent that providing programmatic access to the web3 pillars would open the
|
||||
door towards a new class of applications. As such, the second incarnation of the web3
|
||||
dream is to open up all our technologies for other projects as reusable components.
|
||||
To support this, Geth ships official Go packages that can be embedded into third party
|
||||
desktop and server applications. There is also a [mobile API](/docs/dapp/mobile) that can be
|
||||
used to embed Geth into mobile applications.
|
||||
|
||||
Starting with the 1.5 release family of `go-ethereum`, we transitioned away from providing
|
||||
only a full blown Ethereum client and started shipping official Go packages that could be
|
||||
embedded into third party desktop and server applications.
|
||||
This page provides a high-level overview of the Go API.
|
||||
|
||||
*Note, this guide will assume you are familiar with Go development. It will make no
|
||||
attempts to cover general topics about Go project layouts, import paths or any other
|
||||
standard methodologies. If you are new to Go, consider reading its [getting started guides][go-guide] first.*
|
||||
*Note, this guide will assume some familiarity with Go development. It does not cover general topics
|
||||
about Go project layouts, import paths or any other standard methodologies. If you are new to Go,
|
||||
consider reading [Getting Started with Go][go-guide] first.*
|
||||
|
||||
## Quick overview
|
||||
## Overview
|
||||
|
||||
Our reusable Go libraries focus on four main usage areas:
|
||||
Geth's reusable Go libraries focus on three main usage areas:
|
||||
|
||||
- Simplified client side account management
|
||||
- Remote node interfacing via different transports
|
||||
- Contract interactions through auto-generated bindings
|
||||
- In-process Ethereum, Whisper and Swarm peer-to-peer node
|
||||
|
||||
You can watch a quick overview about these in Peter's (@karalabe) talk titled "Import
|
||||
Geth: Ethereum from Go and beyond", presented at the Ethereum Devcon2 developer conference
|
||||
in September, 2016 (Shanghai). Slides are [available here][peter-slides].
|
||||
The libraries are updated synchronously with the Geth Github repository.
|
||||
The Go libraries can be viewed in full at [Go Packages][go-pkg-link].
|
||||
|
||||
[![Peter's Devcon2 talk](https://img.youtube.com/vi/R0Ia1U9Gxjg/0.jpg)](https://www.youtube.com/watch?v=R0Ia1U9Gxjg)
|
||||
Péter Szilágyi (@karalabe) gave a high level overview of the Go libraries in
|
||||
a talk at DevCon2 in Shanghai in 2016. The slides are still a useful resource
|
||||
([available here][peter-slides]) and the talk itself can be viewed by clicking
|
||||
the image below (it is also archived on [IPFS][ipfs-link]).
|
||||
|
||||
[![Peter's Devcon2 talk](/static/images/devcon2_labelled.webp)](https://www.youtube.com/watch?v=R0Ia1U9Gxjg)
|
||||
|
||||
## Go packages
|
||||
|
||||
The `go-ethereum` library is distributed as a collection of standard Go packages straight
|
||||
from our GitHub repository. The packages can be used directly via the official Go toolkit,
|
||||
without needing any third party tools. External dependencies are vendored locally into
|
||||
`vendor`, ensuring both self-containment as well as code stability. If you reuse
|
||||
`go-ethereum` in your own project, please follow these best practices and vendor it
|
||||
yourself too to avoid any accidental API breakages!
|
||||
The `go-ethereum` library is distributed as a collection of standard Go packages straight from go-ethereum's
|
||||
GitHub repository. The packages can be used directly via the official Go toolkit, without needing any
|
||||
third party tools.
|
||||
|
||||
The canonical import path for `go-ethereum` is `github.com/ethereum/go-ethereum`, with all
|
||||
packages residing underneath. Although there are [quite a number][go-ethereum-dir] of
|
||||
them, you'll only need to care about a limited subset, each of which will be properly
|
||||
introduced in their relevant section.
|
||||
The canonical import path for Geth is `github.com/ethereum/go-ethereum`, with all packages residing
|
||||
underneath. Although there are [lots of them][go-ethereum-dir] most developers will only care about
|
||||
a limited subset.
|
||||
|
||||
You can download all our packages via:
|
||||
All the Geth packages can be downloaded using:
|
||||
|
||||
```
|
||||
$ go get -d github.com/ethereum/go-ethereum/...
|
||||
```
|
||||
|
||||
More Go API support for dapp developers can be found on the [Go Contract Bindings](/docs/dapp/native-bindings)
|
||||
and [Go Account Management](/docs/dapp/native-accounts) pages.
|
||||
|
||||
|
||||
## Tutorial
|
||||
|
||||
This section includes some basic usage examples for the `ethclient` and `gethclient` packages available as
|
||||
part of the Go API. The `ethclient` package provides a client that implements the full Ethereum JSON-RPC API,
|
||||
whereas `gethclient` offers the Geth-specific API.
|
||||
|
||||
### Instantiating a client
|
||||
|
||||
The client is an instance of the `Client` struct which has associated functions that wrap requests to the Ethereum
|
||||
or Geth RPC API endpoints.
|
||||
|
||||
A client is instantiated by passing a raw url or path to an ipc file to the client's `Dial` function. In the following
|
||||
code snippet the path to the ipc file for a local Geth node is provided to `ethclient.Dial()`.
|
||||
|
||||
```go
|
||||
// create instance of ethclient and assign to cl
|
||||
cl, err := ethclient.Dial("/tmp/geth.ipc")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_ = cl
|
||||
```
|
||||
|
||||
### Interacting with the client
|
||||
|
||||
The client can now be used to handle requests to the Geth node using the full JSON-RPC API. For example, the function
|
||||
`BlockNumer()` wraps a call to the `eth_blockNumber` endpoint. The function `SendTransaction` wraps a call to
|
||||
`eth_sendTransaction`. The full list of client methods can be found [here][ethclient-pkg].
|
||||
|
||||
Frequently, the functions take an instance of the `Context` type as their leading argument. This defines context about requests sent from the application such as deadlines, cancellation signals etc. More information on this can
|
||||
be found in the [Go documentation](https://pkg.go.dev/golang.org/x/net/context). An empty context instance can be
|
||||
created using `Context.Background()`.
|
||||
|
||||
### Querying client for data
|
||||
|
||||
A simple starting point is to fetch the chain ID from the client. This e.g. is needed when signing a transaction as is to be seen in the next section.
|
||||
|
||||
```go
|
||||
chainid, err := cl.ChainID(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
Unlike `ChainID`, many functions require arguments other than context. The Go API takes in and returns high-level types which are used in Geth internals as well to simplify programming and remove the need for knowing how data needs to be formatted exactly as per the JSON-RPC API spec. For example to find out the nonce for an account at a given block the address needs to be provided as a `common.Address` type and the block number as a `*big.Int`:
|
||||
|
||||
```go
|
||||
addr := common.HexToAddress("0xb02A2EdA1b317FBd16760128836B0Ac59B560e9D")
|
||||
nonce, err := cl.NonceAt(context.Background(), addr, big.NewInt(14000000))
|
||||
```
|
||||
|
||||
### Querying past events
|
||||
|
||||
Contracts emit events during execution which can be queried from the client. The parameters for the event one is interested in have to be filled out in the `ethereum.FilterQuery` object. This includes which event topics are of interested, from which contracts and during which range of blocks. The example below queries `Transfer` events of all ERC-20 tokens for the last 10 blocks:
|
||||
|
||||
```go
|
||||
blockNum, err := cl.BlockNumber(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
q := ethereum.FilterQuery{
|
||||
FromBlock: new(big.Int).Sub(blockNum, big.NewInt(10)),
|
||||
ToBlock: blockNum,
|
||||
Topics: [][]common.Hash{common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")},
|
||||
}
|
||||
logs, err := cl.FilterLogs(context.Background(), q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
### Sending a transaction
|
||||
|
||||
Sending a transaction is achieved using the `SendTransaction()` function. `SendTransaction` takes an instance of
|
||||
`context.Context` as its leading argument and a signed transaction as its second argument. The signed transaction
|
||||
must be generated in advance. Building the signed transaction is a multi-stage
|
||||
process that requires first generating a key pair if none exists already, retrieving some chain data and defining sender and recipient
|
||||
addresses. Then these data can be collected into a transaction object and signed. The resulting signed transaction
|
||||
can then be passed to `SendTransaction`.
|
||||
|
||||
The example below assumes the following key pair has already been generated:
|
||||
|
||||
```go
|
||||
// SK and ADDR are the secret key and sender address
|
||||
SK = "0xaf5ead4413ff4b78bc94191a2926ae9ccbec86ce099d65aaf469e9eb1a0fa87f"
|
||||
ADDR = "0x6177843db3138ae69679A54b95cf345ED759450d"
|
||||
```
|
||||
|
||||
The secret key and address can be used to send a transaction. In the example below 1 ETH is sent from the
|
||||
address `ADDR` to an arbitrary recipient.
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// sendTransaction sends a transaction with 1 ETH to a specified address.
|
||||
func sendTransaction(cl *ethclient.Client) error {
|
||||
var (
|
||||
sk = crypto.ToECDSAUnsafe(common.FromHex(SK))
|
||||
to = common.HexToAddress("0xb02A2EdA1b317FBd16760128836B0Ac59B560e9D")
|
||||
value = new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether))
|
||||
sender = common.HexToAddress(ADDR)
|
||||
gasLimit = uint64(21000)
|
||||
)
|
||||
// Retrieve the chainid (needed for signer)
|
||||
chainid, err := cl.ChainID(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Retrieve the pending nonce
|
||||
nonce, err := cl.PendingNonceAt(context.Background(), sender)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Get suggested gas price
|
||||
tipCap, _ := cl.SuggestGasTipCap(context.Background())
|
||||
feeCap, _ := cl.SuggestGasPrice(context.Background())
|
||||
// Create a new transaction
|
||||
tx := types.NewTx(
|
||||
&types.DynamicFeeTx{
|
||||
ChainID: chainid,
|
||||
Nonce: nonce,
|
||||
GasTipCap: tipCap,
|
||||
GasFeeCap: feeCap,
|
||||
Gas: gasLimit,
|
||||
To: &to,
|
||||
Value: value,
|
||||
Data: nil,
|
||||
})
|
||||
// Sign the transaction using our keys
|
||||
signedTx, _ := types.SignTx(tx, types.NewLondonSigner(chainid), sk)
|
||||
// Send the transaction to our node
|
||||
return cl.SendTransaction(context.Background(), signedTx)
|
||||
}
|
||||
```
|
||||
|
||||
### gethclient
|
||||
|
||||
An instance of `gethclient` can be used in exactly the same way as `ethclient`. However, `gethclient`
|
||||
includes Geth-specific API methods. These additional methods are:
|
||||
|
||||
```shell
|
||||
CallContract()
|
||||
CreatAccessList()
|
||||
GCStats()
|
||||
GetNodeInfo()
|
||||
GetProof()
|
||||
MemStats()
|
||||
SetHead()
|
||||
SubscribePendingTransactions()
|
||||
```
|
||||
*Note that both `ethclient` and `gethclient` have a `CallContract()` function - the difference is that
|
||||
the `gethclient` version includes an `overrides` argument.*
|
||||
|
||||
Details relating to these endpoints can be found at [pkg.go.dev][go-api-docs] or the Geth [Github][ethclient-link].
|
||||
The code snippets in this tutorial were adapted from a more more in-depth set of examples available on
|
||||
[Github][web3go-link].
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
There are a wide variety of Go APIs available for dapp developers that abstract away the complexity of interacting with Ethereum
|
||||
using a set of composable, reusable functions provided by Geth.
|
||||
|
||||
[go-guide]: https://github.com/golang/go/wiki#getting-started-with-go
|
||||
[peter-slides]: https://ethereum.karalabe.com/talks/2016-devcon.html
|
||||
[go-ethereum-dir]: https://pkg.go.dev/github.com/ethereum/go-ethereum/#section-directories
|
||||
[ethclient-pkg]:https://pkg.go.dev/github.com/ethereum/go-ethereum/ethclient#Client
|
||||
[go-pkg-link]: https://pkg.go.dev/github.com/ethereum/go-ethereum#section-directories
|
||||
[ipfs-link]: https://ipfs.io/ipfs/QmQRuKPKWWJAamrMqAp9rytX6Q4NvcXUKkhvu3kuREKqXR
|
||||
[dapp-link]: https://ethereum.org/en/glossary/#dapp
|
||||
[web3-link]: https://ethereum.org/en/web3/
|
||||
[ethclient-link]: https://github.com/ethereum/go-ethereum/tree/master/ethclient
|
||||
[go-api-docs]:https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.19/ethclient/gethclient
|
||||
[web3go-link]:https://github.com/MariusVanDerWijden/web3go
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
Loading…
Reference in New Issue