description: Tutorial on how to deploy a smart contract with Go.

Deploying a Smart Contract

If you haven’t already, check out the section on smart contract compilation since this lesson requires knowledge on compiling a solidity smart contract to a Go contract file.

Assuming you’ve imported the newly created Go package file generated from abigen, and set the ethclient, loaded your private key, the next step is to create a keyed transactor. First import the accounts/abi/bind package from go-ethereum and then invoke NewKeyedTransactor passing in the private key. Afterwards set the usual properties such as the nonce, gas price, gas limit, and ETH value.

  1. auth := bind.NewKeyedTransactor(privateKey)
  2. auth.Nonce = big.NewInt(int64(nonce))
  3. auth.Value = big.NewInt(0) // in wei
  4. auth.GasLimit = uint64(300000) // in units
  5. auth.GasPrice = gasPrice

If you recall in the previous section, we created a very simpile Store contract that sets and stores key/value pairs. The generated Go contract file provides a deploy method. The deploy method name always starts with the word Deploy followed by the contract name, in this case it’s Store.

The deploy function takes in the keyed transactor, the ethclient, and any input arguments that the smart contract constructor might takes in. We’ve set our smart contract to take in a string argument for the version. This function will return the Ethereum address of the newly deployed contract, the transaction object, the contract instance so that we can start interacting with, and the error if any.

  1. input := "1.0"
  2. address, tx, instance, err := store.DeployStore(auth, client, input)
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. fmt.Println(address.Hex()) // 0x147B8eb97fD247D06C4006D269c90C1908Fb5D54
  7. fmt.Println(tx.Hash().Hex()) // 0xdae8ba5444eefdc99f4d45cd0c4f24056cba6a02cefbf78066ef9f4188ff7dc0
  8. _ = instance // will be using the instance in the next section

Yes it’s that simply. You can take the transaction hash and see the deployment status on Etherscan: https://rinkeby.etherscan.io/tx/0xdae8ba5444eefdc99f4d45cd0c4f24056cba6a02cefbf78066ef9f4188ff7dc0

Full code

Commands

  1. solc --abi Store.sol
  2. solc --bin Store.sol
  3. abigen --bin=Store_sol_Store.bin --abi=Store_sol_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. }

contract_deploy.go

  1. package main
  2. import (
  3. "context"
  4. "crypto/ecdsa"
  5. "fmt"
  6. "log"
  7. "math/big"
  8. "github.com/ethereum/go-ethereum/accounts/abi/bind"
  9. "github.com/ethereum/go-ethereum/crypto"
  10. "github.com/ethereum/go-ethereum/ethclient"
  11. store "./contracts" // for demo
  12. )
  13. func main() {
  14. client, err := ethclient.Dial("https://rinkeby.infura.io")
  15. if err != nil {
  16. log.Fatal(err)
  17. }
  18. privateKey, err := crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
  19. if err != nil {
  20. log.Fatal(err)
  21. }
  22. publicKey := privateKey.Public()
  23. publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
  24. if !ok {
  25. log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
  26. }
  27. fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
  28. nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
  29. if err != nil {
  30. log.Fatal(err)
  31. }
  32. gasPrice, err := client.SuggestGasPrice(context.Background())
  33. if err != nil {
  34. log.Fatal(err)
  35. }
  36. auth := bind.NewKeyedTransactor(privateKey)
  37. auth.Nonce = big.NewInt(int64(nonce))
  38. auth.Value = big.NewInt(0) // in wei
  39. auth.GasLimit = uint64(300000) // in units
  40. auth.GasPrice = gasPrice
  41. input := "1.0"
  42. address, tx, instance, err := store.DeployStore(auth, client, input)
  43. if err != nil {
  44. log.Fatal(err)
  45. }
  46. fmt.Println(address.Hex()) // 0x147B8eb97fD247D06C4006D269c90C1908Fb5D54
  47. fmt.Println(tx.Hash().Hex()) // 0xdae8ba5444eefdc99f4d45cd0c4f24056cba6a02cefbf78066ef9f4188ff7dc0
  48. _ = instance
  49. }

solc version used for these examples

  1. $ solc --version
  2. 0.4.24+commit.e67f0147.Emscripten.clang