🤔

ブロックチェーンからの返り値をkey + valueにする(Go+Geth+abigen)

に公開

はじめに

gethでブロックチェーンを使ったものを作成してると、よくこんな問題に当たる…

そんな問題にあたったときに見返す用のブログがこちら。

結論

https://geth.ethereum.org/docs/tools/abigen

abigenを使おう!!

構築の仕方

環境前提編

ブロックチェーンのサービスなりを作る場合、だいたいこんな感じで実装する。
個人的にはお気に入りの構成

.
├── README.md
├── backend          # gethを用いたバックエンドサーバー
├── contract         # hardhatを用いたコントラクト操作
└── updatelink.sh    # contractからbackendにabiなどをハードリンクするスクリプト

モノレポにしてハードリンクで連携すると変更もしやすいのでおすすめ!
参考までにupdatelink.shはこんな感じ

#!/bin/bash

# エラー発生時に停止する設定
set -e

# エラー処理関数
handle_error() {
  echo "エラーが発生しました!処理を中止します 😱"
  exit 1
}

# エラーが発生したらhandle_error関数を実行
trap handle_error ERR

echo "ABIファイルのハードリンク作成を開始します..."

# backend/config/abi ディレクトリを一旦削除して再作成
rm -rf backend/config/abi/json || { echo "backend/config/abi/jsonの削除に失敗しました"; exit 1; }
mkdir -p backend/config/abi/json || { echo "backend/config/abi/jsonの作成に失敗しました"; exit 1; }

# contract/abi ディレクトリに移動
cd contract/abi || { echo "contract/abiディレクトリへの移動に失敗しました"; exit 1; }

# contract/abi 内のファイルを探して backend/config/abi にハードリンクを作成
find . -type f -exec ln {} ../../backend/config/abi/json \; || { echo "backendへのリンク作成に失敗しました"; exit 1; }

# 元のディレクトリ(プロジェクトルート)に戻る
cd ../.. || { echo "元のディレクトリへの移動に失敗しました"; exit 1; }

echo "ABIファイルのハードリンクを作成しました!✨"

abigenの導入

基本gethは入ってる想定で話すとこんな感じ

abigenのインストール

go install github.com/ethereum/go-ethereum/cmd/abigen@latest

いちいちやるのめんどくさいので、abigen.shを作っておく

#!/bin/bash

# abigen の存在確認
if ! command -v abigen &> /dev/null; then
    echo "❌ abigen が見つかりません。 go install github.com/ethereum/go-ethereum/cmd/abigen@latest を実行してください"
    exit 1
fi

ABI_DIR="./config/abi/json"
OUTPUT_DIR="./config/abi"

echo "🛠️ ABIからGoコードを生成するよ〜っ💫"

# .json を全部ループして生成!
for abi_json in "$ABI_DIR"/*.json; do
    base=$(basename "$abi_json" .json)
    pkgname=$(echo "$base" | tr '[:upper:]' '[:lower:]')

    echo "🔧 $base.json → $base.go(パッケージ名: $pkgname)"

    mkdir -p "$OUTPUT_DIR/$base"

    abigen --abi="$abi_json" \
           --pkg="$pkgname" \
           --type="$base" \
           --out="$OUTPUT_DIR/$base/$base.go"
done

echo "完了しましたっ 🚀🚀🚀"

ちょっと解説しておくと、できればパッケージ名は全部小文字にしたいから、全小文字にしてる。
可読性を上げるために、コントラクト毎1ディレクトリにしてる。

これをやることにより、config/abiディレクトリにコントラクトごとのディレクトリが作成され、そのファイルが作成する。

使い方

ただ生成したパッケージをインポートして、その中の関数を実行するだけ!
これでやるとkeyまで使うことができる!!

最後に

ぜひみなさんもgolangで実装しましょ!

NonEntropy Tech Blog

Discussion