1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

abigenでabiを.goに書き出し

1
Last updated at Posted at 2020-03-03

はじめに

web3jsで作っていたものをgolangで書き直すことになったので、自分用の覚書として残しておきます。
golangでEthereum開発する場合、abigenが必要なのですが、
Goのversionによっては、make devtoolsした時に、エラーになってしまうことがあり、今回は1.12.1で試しています。

オペレーション

1.GVM

$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
$ source ~/.gvm/scripts/gvm 
$ gvm version

2.Go

$ gvm listall
$ gvm install go1.12.1
$ gvm use go1.12.1
$ go version
$ echo "             
source ~/.gvm/scripts/gvm
gvm use `gvm list | grep -v gvm | grep -v '^ *$' | tr -d '=>' | tail`
">>~/.bash_profile 

3.go-ethereum

(https://github.com/ethereum/go-ethereum)
ここでabigenなどもインストールされる

go get -u github.com/ethereum/go-ethereum
cd $GOPATH/src/github.com/ethereum/go-ethereum/
make && make devtools  

4.fresh

$ go get -u github.com/pilu/fresh
$ fresh 

5. echoで雛形を作る

//prepare
$ go get -u github.com/labstack/echo/...
$ mkdir $GOPATH/src/github.com/oggata/colorul_api
$ vim $GOPATH/src/github.com/oggata/colorul_api/main.go

//build
$ go fmt github.com/oggata/colorul_api
$ go build github.com/oggata/colorul_api
$ ./colorul_api
$ curl localhost:1323

6. abigenで .abi -> .go Convert

サンプルとしてdemo.sqlを用意してrinkebyにdeployしておきます。.abiはremixからコピペして.abiファイルとして作っておく。

demo.sol
pragma solidity >=0.5.0;

contract SimpleStorage {
    uint storedData = 12345;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}
demo.abi
[
	{
		"inputs": [],
		"name": "get",
		"outputs": [
			{
....
//.abi to .go command
$ abigen --abi demo.abi --pkg demo --type demo --out demo.go

ポイントとしては、abigenが作ってくれたdemo.goに、NewDemoというfunctionが出来上がるので、
下記のような形で読んであげて、contractのinstanceを作るという感じです。
さらに、contractの中で"getCardData"という呼び方があるとしたら、abigenで生成された.goの関数名はGetCardDataと頭が大文字になっているため、コードから生成したinstanceでcallするときに、大文字にしてあげないといけない点にちょいハマった。。
他の記述箇所ややっていることはweb3jsなどとほとんど変わらず。

//1.インスタンス生成
instance, err := demo.NewDemo(contract-address, client)

//2.method名の頭が大文字
result, err := instance.GetCardData(big.NewInt(1))

7. SimpleStorage.set / SimpleStorage.get

これができれば大体のことはできるはず。。

contract.go

package controllers
import (
    "net/http"
    "context"
    "crypto/ecdsa"
    "fmt"
    "log"
    "math/big"    
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/accounts/abi/bind"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/ethclient"
    demo "github.com/aaa/bbb/contracts/demo"
    "github.com/labstack/echo"
)

func ContractRead(c echo.Context) error {
    client, err := ethclient.Dial("https://rinkeby.infura.io/v3/------")
    if err != nil {
        log.Fatal(err)
    }
    privateKey, err := crypto.HexToECDSA("---private key-----")
    if err != nil {
        log.Fatal(err)
    }
    publicKey := privateKey.Public()
    publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
    if !ok {
        log.Fatal("error casting public key to ECDSA")
    }
    fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) 
    nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
    if err != nil {
        log.Fatal(err)
    }
    gasPrice, err := client.SuggestGasPrice(context.Background())
    if err != nil {
        log.Fatal(err)
    }
    auth := bind.NewKeyedTransactor(privateKey)
    auth.Nonce = big.NewInt(int64(nonce))
    auth.Value = big.NewInt(0)     // in wei
    auth.GasLimit = uint64(300000) // in units
    auth.GasPrice = gasPrice
    address := common.HexToAddress("-----contract address-----")
    instance, err := demo.NewDemo(address, client)
    if err != nil {
        log.Fatal(err)
    }
    tx, err := instance.Set(auth, big.NewInt(123))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("tx sent: %s", tx.Hash().Hex())
    result, err := instance.Get(&bind.CallOpts{})
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(result)
    return c.JSON(http.StatusOK, tx.Hash().Hex())
}

参考

http://runkiss.blogspot.com/2019/12/deploy-smart-contract-on-ethereum-using.html
https://www.yo1000.com/golang-setup2/

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?