mirror of https://github.com/ethereum/go-ethereum
docs: add page on abigen (#26057)
* add page on abigen * Apply suggestions from code review Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de> * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>pull/26121/head
parent
2e7bc0f4ae
commit
e7558aa2d8
@ -0,0 +1,169 @@ |
||||
--- |
||||
title: Abigen |
||||
sort-key: p |
||||
--- |
||||
|
||||
Abigen is a binding-generator for easily interacting with Ethereum using Go. |
||||
Abigen creates easy-to-use, type-safe Go packages from Ethereum smart contract |
||||
definitions known as ABIs. This abstracts away a lot of the complexity of handling |
||||
smart contract deployment and interaction in Go native applications such as |
||||
encoding and decoding events. Abigen comes bundled with |
||||
Geth. Abigen can also be built |
||||
independently by navigating to `go-ethereum/cmd/abigen` and running `go build`, or |
||||
equivalently: |
||||
|
||||
```sh |
||||
$ cd $GOPATH/src/github.com/ethereum/go-ethereum |
||||
$ go build ./cmd/abigen |
||||
``` |
||||
|
||||
## What is an ABI? |
||||
|
||||
Ethereum smart contracts have a schema that defines its functions and return types |
||||
in the form of a JSON file. This JSON file is known as an _Application Binary Interface_, |
||||
or ABI. The ABI acts as a specification for precisely how to encode data sent to a |
||||
contract and how to decode the data the contract sends back. The ABI is the only |
||||
essential piece of information required to generate Go bindings, unless a deployment function is expected in which case the contract bytecode is also needed. Go developers can then |
||||
use the bindings to interact with the contract from their Go application without having |
||||
to deal directly with data encoding and decoding. An ABI is generated when a contract |
||||
is compiled. |
||||
|
||||
### Generating the bindings |
||||
|
||||
To demonstrate the binding generator a contract is required. The contract `Storage.sol` |
||||
implements two very simple functions: `store` updates a user-provided `uint256` to the |
||||
contract's storage, and `retrieve` displays the value stored in the contract to the user. |
||||
The Solidity code is as follows: |
||||
|
||||
```solidity |
||||
// SPDX-License-Identifier: GPL-3.0 |
||||
|
||||
pragma solidity >0.7.0 < 0.9.0; |
||||
/** |
||||
* @title Storage |
||||
* @dev store or retrieve variable value |
||||
*/ |
||||
|
||||
contract Storage { |
||||
|
||||
uint256 value; |
||||
|
||||
function store(uint256 number) public{ |
||||
value = number; |
||||
} |
||||
|
||||
function retrieve() public view returns (uint256){ |
||||
return value; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
This contract can be pasted into a text file and saved as `Storage.sol`. T |
||||
he following code snippet shows how an ABI can be generated for `Storage.sol` |
||||
using the Solidity compiler `solc`. |
||||
|
||||
```shell |
||||
solc --abi Storage.sol -o build |
||||
``` |
||||
|
||||
The ABI can also be generated in other ways such as using the `compile` commands |
||||
in development frameworks such as [Truffle](https://trufflesuite.com/), |
||||
[Hardhat](https://hardhat.org/) and [Brownie](https://eth-brownie.readthedocs.io/en/stable/) |
||||
or in the online IDE [Remix](https://remix.ethereum.org/). ABIs for existing verified |
||||
contracts can be downloaded from [Etherscan](etherscan.io). |
||||
|
||||
The ABI for `Storage.sol` (`Storage.abi`) looks as follows: |
||||
|
||||
```json |
||||
[ |
||||
{ |
||||
"inputs": [], |
||||
"name": "retrieve", |
||||
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], |
||||
"stateMutability": "view", |
||||
"type": "function" |
||||
}, |
||||
{ |
||||
"inputs": [{ "internalType": "uint256", "name": "number", "type": "uint256" }], |
||||
"name": "store", |
||||
"outputs": [], |
||||
"stateMutability": "nonpayable", |
||||
"type": "function" |
||||
} |
||||
] |
||||
``` |
||||
|
||||
The contract binding can then be generated by passing the ABI |
||||
to `abigen` as follows: |
||||
|
||||
```sh |
||||
$ abigen --abi Storage.abi --pkg main --type Storage --out Storage.go |
||||
``` |
||||
|
||||
Where the flags are: |
||||
|
||||
- `--abi`: Mandatory path to the contract ABI to bind to |
||||
- `--pkg`: Mandatory Go package name to place the Go code into |
||||
- `--type`: Optional Go type name to assign to the binding struct |
||||
- `--out`: Optional output path for the generated Go source file (not set = stdout) |
||||
|
||||
This will generate a type-safe Go binding for the Storage contract. The generated |
||||
code will look something like the snippet below, the full version of which can be |
||||
viewed [here](https://gist.github.com/jmcook1186/a78e59d203bb54b06e1b81f2cda79d93). |
||||
|
||||
```go |
||||
// Code generated - DO NOT EDIT. |
||||
// This file is a generated binding and any manual changes will be lost. |
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"errors" |
||||
"math/big" |
||||
"strings" |
||||
|
||||
ethereum "github.com/ethereum/go-ethereum" |
||||
"github.com/ethereum/go-ethereum/accounts/abi" |
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind" |
||||
"github.com/ethereum/go-ethereum/common" |
||||
"github.com/ethereum/go-ethereum/core/types" |
||||
"github.com/ethereum/go-ethereum/event" |
||||
) |
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used. |
||||
var ( |
||||
_ = errors.New |
||||
_ = big.NewInt |
||||
_ = strings.NewReader |
||||
_ = ethereum.NotFound |
||||
_ = bind.Bind |
||||
_ = common.Big1 |
||||
_ = types.BloomLookup |
||||
_ = event.NewSubscription |
||||
) |
||||
|
||||
// StorageMetaData contains all meta data concerning the Storage contract. |
||||
var StorageMetaData = &bind.MetaData{ |
||||
ABI: "[{\"inputs\":[],\"name\":\"retrieve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"}],\"name\":\"store\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", |
||||
} |
||||
|
||||
// StorageABI is the input ABI used to generate the binding from. |
||||
// Deprecated: Use StorageMetaData.ABI instead. |
||||
var StorageABI = StorageMetaData.ABI |
||||
|
||||
// Storage is an auto generated Go binding around an Ethereum contract. |
||||
type Storage struct { |
||||
StorageCaller // Read-only binding to the contract |
||||
StorageTransactor // Write-only binding to the contract |
||||
StorageFilterer // Log filterer for contract events |
||||
} |
||||
... |
||||
|
||||
``` |
||||
|
||||
`Storage.go` contains all the bindings required to interact with |
||||
`Storage.sol` from a Go application. |
||||
|
||||
For instructions on how to deploy this contract to Ethereum from a Go |
||||
native application read our [Go bindings page](/docs/dapp/native.md). Note that the contract bytecode is required in addition to the ABI to deploy the contract. |
||||
To browse the Abigen source code visit the Geth [Github repository](https://github.com/ethereum/go-ethereum/tree/master/cmd/abigen). |
Loading…
Reference in new issue