description: Tutorial on how to compile a smart contract and read the ABI with Go.

Smart Contract Compilation & ABI

In order to interact with a smart contract in a Go application, we must first generate the ABI (application binary interface) of the contract and compile the ABI to a format that we can import into our Go application.

Install the Solidity Compiler

The first step is to install the Solidity compiler (solc). In this guide, we’re using Solidity 0.4.24.

Solc is available as a snapcraft package for Ubuntu.

  1. sudo snap install solc --edge

Solc is available as a Homebrew package for macOS.

  1. brew update
  2. brew tap ethereum/ethereum
  3. brew install solidity

Alternatively, you can run solc with Docker using the following command:

  1. ## Download Docker image
  2. docker pull ethereum/solc:0.4.24
  3. ## Usage: docker run --rm -v $(pwd):/root ethereum/solc:0.4.24 <command_here>
  4. # To generate ABI file from .sol file and send output to ./build folder
  5. docker run --rm -v $(pwd):/root ethereum/solc:0.4.24 --abi /root/Store.sol -o /root/build

For other platforms or for installing from source, check out the official solidity install guide.

Install abigen tool

We also need to install a tool called abigen for generating the ABI from a solidity smart contract.

Assuming you have Go all set up on your computer, simply run the following to install the abigen tool.

  1. go get -u github.com/ethereum/go-ethereum
  2. cd $GOPATH/src/github.com/ethereum/go-ethereum/
  3. make
  4. make devtools

Create smart contract

We’ll create a simple smart contract to test with. More complex smart contracts, and smart contract development in general is out of scope for this book. I highly recommend checking out truffle framework for developing and testing smart contracts.

This simple contract will be a key/value store with only 1 external method to set a key/value pair by anyone. We also added an event to emit after the value is set.

  1. pragma solidity ^0.4.24;
  2. contract Store {
  3. event ItemSet(bytes32 key, bytes32 value);
  4. string public version;
  5. mapping (bytes32 => bytes32) public items;
  6. constructor(string _version) public {
  7. version = _version;
  8. }
  9. function setItem(bytes32 key, bytes32 value) external {
  10. items[key] = value;
  11. emit ItemSet(key, value);
  12. }
  13. }

Although this smart contract is simple, it will work for this example.

Create Go contract file

Now we can generate the ABI from a solidity source file.

  1. solc --abi Store.sol -o build

It’ll write it to a file called ./build/Store.abi

Now let’s convert the ABI to a Go file that we can import. This new file will contain all the available methods the we can use to interact with the smart contract from our Go application.

  1. abigen --abi=./build/Store.abi --pkg=store --out=Store.go

In order to deploy a smart contract from Go, we also need to compile the solidity smart contract to EVM bytecode. The EVM bytecode is what will be sent in the data field of the transaction. The bin file is required for generating the deploy methods on the Go contract file.

  1. solc --bin Store.sol -o build

Now we compile the Go contract file which will include the deploy methods because we includes the bin file.

  1. abigen --bin=./build/Store.bin --abi=./build/Store.abi --pkg=store --out=Store.go

That’s it for this lesson. In the next lessons we’ll learn how to deploy the smart contract, and then interact with it.

Full code

Commands

  1. go get -u github.com/ethereum/go-ethereum
  2. cd $GOPATH/src/github.com/ethereum/go-ethereum/
  3. make
  4. make devtools
  5. solc --abi --bin Store.sol -o build
  6. abigen --bin=./build/Store.bin --abi=./build/Store.abi --pkg=store --out=Store.go

Store.sol

  1. pragma solidity ^0.4.24;
  2. contract Store {
  3. event ItemSet(bytes32 key, bytes32 value);
  4. string public version;
  5. mapping (bytes32 => bytes32) public items;
  6. constructor(string _version) public {
  7. version = _version;
  8. }
  9. function setItem(bytes32 key, bytes32 value) external {
  10. items[key] = value;
  11. emit ItemSet(key, value);
  12. }
  13. }