# Flare for Go Devs

> Learn how to interact with Flare using geth.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/network/guides/flare-for-go-developers

This guide is for developers who want to interact with Flare using Go. In this guide, using Go, you will learn how to:

-   Query a contract on Flare using the Go API for [Geth](https://github.com/ethereum/go-ethereum), a client that implements the full Ethereum JSON-RPC API.
-   Compile a Solidity contract using the CLI interface of [solc](https://github.com/argotorg/solidity), the Solidity compiler.
-   Deploy your compiled contract on Flare.

tip

All examples in this guide are available at [developer-hub/examples](https://github.com/flare-foundation/developer-hub/tree/main/examples).

## Getting started[​](#getting-started "Direct link to Getting started")

Install Geth by following the instructions in the [Geth documentation](https://geth.ethereum.org/docs/getting-started/installing-geth). Also install the Solidity compiler by following the instructions in the [Solidity documentation](https://docs.soliditylang.org/en/latest/installing-solidity.html#linux-packages). The main commands are provided here:

```
brew tap ethereum/ethereumbrew install ethereum solidity
```

```
sudo add-apt-repository -y ppa:ethereum/ethereumsudo apt updatesudo apt install ethereum solc
```

Add the `ethclient` and `keystore` packages to your Go project:

```
go get github.com/ethereum/go-ethereum/ethclientgo get github.com/ethereum/go-ethereum/accounts/keystore
```

The folder structure of your Go project should look like:

```
developer-hub-go/├── coston2/│   └── *.go├── flare/│   └── *.go├── main.go├── go.mod└── go.sum
```

### Usage[​](#usage "Direct link to Usage")

You need to connect to testnet or mainnet via an RPC, any RPC listed on the [Network Configuration](/network/overview#configuration) page will work. For this guide, you can use the Public RPC.

coston2/chain\_id.go

```
package coston2import (	"context"	"fmt"	"math/big"	"github.com/ethereum/go-ethereum/ethclient")func ChainId() *big.Int {	cl, err := ethclient.Dial("https://coston2-api.flare.network/ext/C/rpc")	if err != nil {		panic(err)	}	chainid, err := cl.ChainID(context.Background())	if err != nil {		panic(err)	}	fmt.Println("Chain ID is", chainid)	// Chain ID is 114	return chainid}
```

flare/chain\_id.go

```
package flareimport (	"context"	"fmt"	"math/big"	"github.com/ethereum/go-ethereum/ethclient")func ChainId() *big.Int {	cl, err := ethclient.Dial("https://flare-api.flare.network/ext/C/rpc")	if err != nil {		panic(err)	}	chainid, err := cl.ChainID(context.Background())	if err != nil {		panic(err)	}	fmt.Println("Chain ID is", chainid)	// Chain ID is 14	return chainid}
```

## Querying a contract[​](#querying-a-contract "Direct link to Querying a contract")

To query a contract, two pieces of information are required:

-   Contract address
-   Contract ABI (Application Binary Interface)

For this example, you can use the `FlareContractRegistry` contract which has the same address `0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019` across both testnet and mainnet.

### Fetch ABI[​](#fetch-abi "Direct link to Fetch ABI")

To fetch a contract's ABI, copy the FlareContractRegistry ABI from the appropriate Routescan endpoint and paste it into `FlareContractRegistry.abi` next to your `go.mod`. The `FlareContractRegistry` itself is deployed at the same `0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019` on every Flare-family network — pick the URL that matches the chain you'll deploy to:

-   **Flare Testnet Coston2 (chain id 114):** [routescan URL](https://api.routescan.io/v2/network/testnet/evm/114/etherscan/api?module=contract&action=getabi&address=0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019&format=raw)
-   **Flare Mainnet (chain id 14):** [routescan URL](https://api.routescan.io/v2/network/mainnet/evm/14/etherscan/api?module=contract&action=getabi&address=0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019&format=raw)

To generate the ABI bindings, which will be saved to `FlareContractRegistry.go`:

```
abigen --abi FlareContractRegistry.abi --pkg coston2 --type FlareContractRegistry --out coston2/FlareContractRegistry.go
```

```
abigen --abi FlareContractRegistry.abi --pkg flare --type FlareContractRegistry --out flare/FlareContractRegistry.go
```

### Make query[​](#make-query "Direct link to Make query")

You can now query the `FlareContractRegistry` contract to get the addresses of other Flare contracts.

For example, querying it for the address of the `WNat` contract:

coston2/make\_query.go

```
package coston2import (	"context"	"fmt"	"github.com/ethereum/go-ethereum/accounts/abi/bind"	"github.com/ethereum/go-ethereum/common"	"github.com/ethereum/go-ethereum/ethclient")func MakeQuery() []common.Address {	client, err := ethclient.Dial("https://coston2-api.flare.network/ext/C/rpc")	if err != nil {		panic(err)	}	registryAddr := common.HexToAddress("0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019")	registry, err := NewFlareContractRegistry(registryAddr, client)	if err != nil {		panic(err)	}	callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}	addr, err := registry.GetContractAddressesByName(callOpts, []string{"WNat"})	if err != nil {		panic(err)	}	fmt.Println("WNat contract address is", addr)	// WNat contract address is [0xC67DCE33D7A8efA5FfEB961899C73fe01bCe9273]	return addr}
```

flare/make\_query.go

```
package flareimport (	"context"	"fmt"	"github.com/ethereum/go-ethereum/accounts/abi/bind"	"github.com/ethereum/go-ethereum/common"	"github.com/ethereum/go-ethereum/ethclient")func MakeQuery() []common.Address {	client, err := ethclient.Dial("https://flare-api.flare.network/ext/C/rpc")	if err != nil {		panic(err)	}	registryAddr := common.HexToAddress("0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019")	registry, err := NewFlareContractRegistry(registryAddr, client)	if err != nil {		panic(err)	}	callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}	addr, err := registry.GetContractAddressesByName(callOpts, []string{"WNat"})	if err != nil {		panic(err)	}	fmt.Println("WNat contract address is", addr)	// WNat contract address is [0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d]	return addr}
```

## Compiling with solc[​](#compiling-with-solc "Direct link to Compiling with solc")

For this example, you can use the `FtsoV2FeedConsumer` contract to query the FTSOv2 feeds. Copy the `FtsoV2FeedConsumer` sample contract code given below, and save the `.sol` file in the same folder as your `go.mod`.

<details>
<summary>FtsoV2FeedConsumer sample contract</summary>

`FtsoV2FeedConsumer` sample contract

Note that the contract interface dependencies have been inlined to avoid any import issues.

FtsoV2FeedConsumer.sol

```
// SPDX-License-Identifier: MITpragma solidity >=0.8.0 <0.9.0;interface IFlareContractRegistry {    function getContractAddressByName(        string calldata _name    ) external view returns (address);}/** * THIS IS A TEST INTERFACE. * Functions are payable in the production interface. */interface TestFtsoV2Interface {    function getFeedsById(        bytes21[] calldata _feedIds    )        external        view        returns (            uint256[] memory _values,            int8[] memory _decimals,            uint64 _timestamp        );}/** * THIS IS AN EXAMPLE CONTRACT. * DO NOT USE THIS CODE IN PRODUCTION. */contract FtsoV2FeedConsumer {    IFlareContractRegistry internal contractRegistry;    TestFtsoV2Interface internal ftsoV2;    // Feed IDs, see https://dev.flare.network/ftso/feeds for full list    bytes21[] public feedIds = [        bytes21(0x01464c522f55534400000000000000000000000000), // FLR/USD        bytes21(0x014254432f55534400000000000000000000000000), // BTC/USD        bytes21(0x014554482f55534400000000000000000000000000) // ETH/USD    ];    /**     * Constructor initializes the FTSOv2 contract.     * The contract registry is used to fetch the FtsoV2 contract address.     */    constructor() {        contractRegistry = IFlareContractRegistry(            0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019        );        ftsoV2 = TestFtsoV2Interface(            contractRegistry.getContractAddressByName("FtsoV2")        );    }    /**     * Get the current value of the feeds.     */    function getFtsoV2CurrentFeedValues()        external        view        returns (            uint256[] memory _feedValues,            int8[] memory _decimals,            uint64 _timestamp        )    {        /* Your custom feed consumption logic. In this example the values are just returned. */        return ftsoV2.getFeedsById(feedIds);    }}
```

</details>

To compile the contract, use the Solidity compiler:

```
solc --evm-version cancun --abi --bin FtsoV2FeedConsumer.sol -o build
```

The compiled contract will be saved in the `build/` folder.

## Create account[​](#create-account "Direct link to Create account")

Before deploying a contract, you need an account. You can create an account using the following code:

create\_account.go

```
package mainimport (	"fmt"	"github.com/ethereum/go-ethereum/accounts/keystore")func CreateAccount() {	ks := keystore.NewKeyStore(".", keystore.StandardScryptN, keystore.StandardScryptP)	account, err := ks.NewAccount("Creation password")	if err != nil {		panic(err)	}	fmt.Println("Account: ", account.Address.Hex())}
```

This will generate a new account and save the keystore file in the current directory. The account address will be printed to the console.

danger

-   Never share your private keys.
-   Never put your private keys in source code.
-   Never commit private keys to a Git repository.

-   For testnet, you can get free testnet C2FLR on the [Coston2 Faucet](https://faucet.flare.network/coston2).
-   For mainnet you will need FLR.

## Deploying with geth[​](#deploying-with-geth "Direct link to Deploying with geth")

To deploy the contract, you need to first generate the contract bindings:

```
abigen --bin=build/FtsoV2FeedConsumer.bin --abi=build/FtsoV2FeedConsumer.abi --pkg coston2 --type FtsoV2FeedConsumer --out coston2/FtsoV2FeedConsumer.go
```

```
abigen --bin=build/FtsoV2FeedConsumer.bin --abi=build/FtsoV2FeedConsumer.abi --pkg flare --type FtsoV2FeedConsumer --out flare/FtsoV2FeedConsumer.go
```

This will generate the `FtsoV2FeedConsumer.go` file, with the function `DeployFtsoV2FeedConsumer`.

Copy the contents of the generated keystore file into the `key` constant in the following code:

deploy\_contract.go

```
// THIS IS EXAMPLE CODE. DO NOT USE THIS CODE IN PRODUCTION.package coston2import (	"context"	"fmt"	"strings"	"time"	"github.com/ethereum/go-ethereum/accounts/abi/bind"	"github.com/ethereum/go-ethereum/ethclient")// Paste the contents of the generated keystore file here// DO NOT USE THIS CODE IN PRODUCTION.// NEVER COMMIT PRIVATE KEYS TO A GIT REPOSITORY.const key = ``func DeployContract() {	conn, err := ethclient.Dial("https://coston2-api.flare.network/ext/C/rpc")	if err != nil {		panic(err)	}	ctx := context.Background()	chainId, err := conn.ChainID(ctx)	if err != nil {		panic(err)	}	auth, err := bind.NewTransactorWithChainID(strings.NewReader(key), "Creation password", chainId)	if err != nil {		panic(err)	}	address, tx, ftsoV2FeedConsumer, err := DeployFtsoV2FeedConsumer(auth, conn)	if err != nil {		panic(err)	}	fmt.Printf("Contract pending deploy: 0x%x\n", address)	fmt.Printf("Transaction waiting to be mined: 0x%x\n\n", tx.Hash())	time.Sleep(2000 * time.Millisecond)	feeds, err := ftsoV2FeedConsumer.GetFtsoV2CurrentFeedValues(&bind.CallOpts{Context: ctx, Pending: true})	if err != nil {		panic(err)	}	fmt.Println("Feeds values and decimals:", feeds)}
```

deploy\_contract.go

```
// THIS IS EXAMPLE CODE. DO NOT USE THIS CODE IN PRODUCTION.package flareimport (	"context"	"fmt"	"strings"	"time"	"github.com/ethereum/go-ethereum/accounts/abi/bind"	"github.com/ethereum/go-ethereum/ethclient")// Paste the contents of the generated keystore file here// DO NOT USE THIS CODE IN PRODUCTION.// NEVER COMMIT PRIVATE KEYS TO A GIT REPOSITORY.const key = ``func DeployContract() {	conn, err := ethclient.Dial("https://flare-api.flare.network/ext/C/rpc")	if err != nil {		panic(err)	}	ctx := context.Background()	chainId, err := conn.ChainID(ctx)	if err != nil {		panic(err)	}	auth, err := bind.NewTransactorWithChainID(strings.NewReader(key), "Creation password", chainId)	if err != nil {		panic(err)	}	address, tx, ftsoV2FeedConsumer, err := DeployFtsoV2FeedConsumer(auth, conn)	if err != nil {		panic(err)	}	fmt.Printf("Contract pending deploy: 0x%x\n", address)	fmt.Printf("Transaction waiting to be mined: 0x%x\n\n", tx.Hash())	time.Sleep(2000 * time.Millisecond)	feeds, err := ftsoV2FeedConsumer.GetFtsoV2CurrentFeedValues(&bind.CallOpts{Context: ctx, Pending: true})	if err != nil {		panic(err)	}	fmt.Println("Feeds values and decimals:", feeds)}
```

Congratulations! You have now successfully deployed a contract on Flare using Go.

What's next?

Learn how to interact with Flare's enshrined oracle [FTSOv2 using Go](/ftso/guides/read-feeds-offchain).
