Go-Ethereum – How to Deploy Smart Contracts Using Golang

go-ethereumgolangtokens

I tried to deploy smart contracts using go and go-ethereum.
To deploy it, I use sendTransaction function from go-ethereum library, but when i check it on ropsten explorer, it just a basic transaction not contract creation. Why are thats happen?

Here is the code

package main

import (
        "context"
        "crypto/ecdsa"
        "fmt"
        "io/ioutil"
        "log"
        "strings"

        "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"
)

func main() {
        // get the account private key from file .key
        key, err := ioutil.ReadFile(".key")
        if err != nil {
                log.Fatalln(err)
        }

        // connect into ropsten eth
        client, err := ethclient.Dial("https://speedy-nodes-nyc.moralis.io/bf6148e21d21cfe6e13519a7/eth/ropsten")
        if err != nil {
                log.Fatalln(err)
        }

        prv, err := crypto.HexToECDSA(strings.ReplaceAll(string(key), "\n", ""))
        if err != nil {
                log.Fatalln(err)
        }

        pubkey, ok := prv.Public().(*ecdsa.PublicKey)
        if !ok {
                log.Fatalln("not ok")
        }

        fromAddress := crypto.PubkeyToAddress(*pubkey)
        gasLimit := uint64(210000)
        gasPrice, err := client.SuggestGasPrice(context.Background())
        if err != nil {
                log.Fatalln(err)
        }

        sc, err := ioutil.ReadFile("./contracts/Token.sol")

        nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
        if err != nil {
                log.Fatalln(err)
        }

        // 0x + sc bytecode compiled using command "solcjs --bin ./Token.sol"
        data := []byte("0x"+string(sc))

        // create new transaction
        tx := types.NewTransaction(nonce, common.BytesToAddress([]byte{}), nil, gasLimit, gasPrice, data)

        // get the chain id
        chainId, err := client.NetworkID(context.Background())
        if err != nil {
                log.Fatalln(err)
        }

        // sign the transaction
        sgtx, err := types.SignTx(tx, types.NewEIP155Signer(chainId), prv)

        // send the transaction
        err = client.SendTransaction(context.Background(), sgtx)
        if err != nil {
                log.Fatalln(err)
        }

        fmt.Println(sgtx.Hash().Hex())
}

And this is the result

0xcf7f4ec9fc7add65b3d4b7e713f359e8efbaf0ec5d9166f7f504bd3ffc56b5f5

Best Answer

I'm not a go developer, but I can point out a couple of issues that are wrong.

  • There should be a types.NewContractCreation that should be used to deploy contracts
  • The source code is being deployed. It should be the bytecode produced by the solc compiler.