コンテンツへスキップ
0%

Solidity ABI(アプリケーションバイナリインターフェース)とは?

執筆者 Mohammad

2022年10月4日 公開読了時間 1 分

Ethereumの開発者は、Ethereumネットワーク向けにスマートコントラクトのコードを書くためにSolidityプログラミング言語を使用します。しかし、SolidityはEthereum Virtual Machine(EVM)とどのように連携し、動作するのでしょうか?それはすべて、スマートコントラクトのコンパイルから始まります。

この記事では、以下について説明します:

  • スマートコントラクトのコンパイルの必要性を紹介しながら、Solidity ABIとは何かを説明
  • ABIがSolidityコンパイラとしてどのように機能するか
  • バイトコードとは何か、コンパイルの過程における役割
  • Solidity ABIとは何か、APIとの違い
  • ABIの仕組み(具体例を交えて)

スマートコントラクトのコンパイルとは何か

スマートコントラクトのコンパイルとは、Solidityで書かれたスマートコントラクトのコードを、Ethereum Virtual Machineの言語と互換性のある言語に変換するプロセスです。

開発者は、人間が読んで理解できる高水準プログラミング言語であるSolidityでスマートコントラクトを書きます。EVMはSolidityを理解できません。仮想マシンがSolidityを理解できないため、コンパイルによって人間が理解できるSolidityコードを機械が読み取れる言語に変換します。Ethereumエコシステムでは、スマートコントラクトのコンパイルにSolidityコンパイラを使用します。

Solidityコンパイラとは何か

Solidityコンパイラは、solcとも呼ばれ、Solidityベースのスマートコントラクトを、EVMが理解できるバイトコードとApplication Binary Interface(ABI)にコンパイルします。バイトコードとSolidityコントラクトのABIは、Ethereumのスマートコントラクトとやり取りするための主要な構成要素です。

バイトコードとは何か

バイトコードとは、Ethereum Virtual Machine上でバイナリ形式で表されたスマートコントラクトの情報です。バイトコードは人間には読めず、機械(EVM)のみが読み取ることができます。言い換えると、SolidityはEVMが必要な処理を実行できるように、コンパイルされて機械が読み取れるバイトコードに変換されます。

バイトコードには、オペコードと呼ばれる機械が理解できる一連の命令が含まれており、それぞれ1バイト(8ビット)の長さです。つまり、バイトコードは1バイトのオペコードの集合体です。

バイトコードは以下の2種類に分けられます:

  1. クリエーションバイトコード
  2. ランタイムバイトコード

クリエーションバイトコードとは何か

スマートコントラクトのコンパイルによって、コンストラクタのロジックとコンストラクタのパラメータを含むクリエーションバイトコードが生成されます。 クリエーションバイトコードは、ランタイムバイトコードを生成する役割を担います。

任意の統合開発環境(IDE)プラットフォームでスマートコントラクトの「compilation details」をクリックすると、クリエーションバイトコードが表示されます。クリエーションバイトコードはデプロイ時に1回のみ実行されます。

オンチェーンのクリエーションバイトコードを取得するには、以下を使用します:

JSON RPC呼び出しでオフチェーンからクリエーションバイトコードを取得するには、次のメソッドを使用します:getTransactionByHash

ランタイムバイトコードとは何か

ランタイムバイトコードは、恒久的に実行可能なコードとしてオンチェーンに保存される、コンパイル済みのスマートコントラクトデータです。クリエーションバイトコードとは異なり、ランタイムバイトコードにはコンストラクタのロジックやコンストラクタのパラメータは含まれません。

オンチェーンのランタイムバイトコードを取得するには、以下を使用します:

JSON RPC呼び出しでオフチェーンからランタイムバイトコードを取得するには、次のメソッドを使用します:getCode

バイトコードとのやり取りの方法

スマートコントラクトのデータは、EVM上では機械が読み取れるバイトコードとして保存され、外部アプリケーション上ではJavaScriptやその他のスマートコントラクトなど、人間が読めるSolidity言語で扱われます。これは、これらがバイトコードと直接通信できないためです。ここで、スマートコントラクトのコンパイルの2つ目の構成要素であるApplication Binary Interface(ABI)が、このやり取りを可能にします。

SolidityにおけるApplication Binary Interface(ABI)とは何か

Application Binary Interface(ABI)は、EVMのバイトコードとの通信を仲介するインタープリタです。Solidity ABIは、特定の関数を実行するための、スマートコントラクト上のメソッドの人間が読めるリストです。ABIは、ethers.jsのようなライブラリと組み合わせてスマートコントラクトとやり取りするために使用できます。

SolidityにおけるABIは、API(Application Program Interface)と似ていますが、異なるものでもあります。

Solidity ABIとAPIの違いは何か

web2では、APIはWebアプリケーションと集中管理されたサーバーとのやり取りを仲介しますが、Solidity ABIはスマートコントラクトのデータをアプリケーションや他のコントラクトに提供します。アプリケーションがAPIを使ってサーバーにデータをリクエストすると、APIがそのデータを返しますが、ABIはSolidity Binariesと呼ばれるバイナリのバイトコード形式でスマートコントラクトのデータにアクセスします。

次のセクションでは、Solidity Binariesとは何かを説明します。

Solidity Binariesとは何か

Solidity Binariesは、Ethereumエコシステムにおけるスマートコントラクトのための独自のデータ保存インフラです。

開発者は、人間が読めるSolidityコードをそのままEthereumブロックチェーンにデプロイすることはできません。代わりに、Solidityのスマートコントラクトデータは、バイナリ形式(つまり16進数文字の長い文字列)の生のバイトコードとして保存されます。これがSolidity Binariesと呼ばれるもので、これによりブロックチェーン上でのデータ保存のコストを抑えることができます。

では、ABIはどのようにしてSolidity Binariesにアクセスするのでしょうか。それはABIエンコーディングと呼ばれるプロセスによって行われます。

Solidity ABIエンコーディングとは何か

ABIは、EVMベースのバイトコードが理解できる関数シグネチャと変数宣言を用いてスマートコントラクトを呼び出します。 これはABIエンコーディングと呼ばれ、機械が読み取れるバイトコードが処理するために必要な情報をABIがエンコードするものです。多くの場合、ABIエンコーディングはスマートコントラクトコンパイラによって自動的に行われます。

ABIデコーディングとは何か

EVMバイトコードが命令を実行して結果を返す際、その結果は生の16進数形式になっており、 ABIはこの人間には読めない16進数形式を、人間が読める言語にデコードします。 これはABIデコーディングと呼ばれます。

Solidityのコードはこのようにしてこの結果がABIから得られるようになっており、基本的にABIは機械語との間でデータをエンコード/デコードするインターフェースとして機能します。

SolidityコードはどのようにEVMのオペコードにマッピングされるか

EVMバイトコードは、複数のオペコードから構成されています。ABIエンコーディングが関数を呼び出すとき、それは特定のオペコードを指します。 トランザクションを処理した後、オペコードは結果を返し、それをABIがユーザー向けにデコードします。

Solidityにおいて、ABIはどのように機能するか

ABIは、どの関数を呼び出すか(エンコーディング)を指定し、その関数を実行してユーザーにデータを返します(デコーディング)。 スマートコントラクトには複数の関数が含まれており、それらはバイトコードとしてEVM上にデプロイされます。それぞれのスマートコントラクトには固有のABIがあり、結果を取得するにはそのABIが必要になります。

スマートコントラクトはバイナリ形式で保存されているため、ABIはバイナリのコントラクトとやり取りするための構造とメソッドを定義します。コンパイル後、スマートコントラクトはSolidity JSON ABI形式で表現されたABIを生成します。

Remixのような一部のIDEでは、コントラクトのABIが自動的に生成されます。ただし、Solidity Compiler NPMパッケージを使って手動でABIを作成することもできます。

Solidity JSON ABIは、以下の構成要素を生成します:

  • Type - 関数の性質を定義(receive、fallback、constructor)
  • Name - 関数の名前を定義
  • Inputs - name、type、componentsを持つオブジェクトの配列
  • Outputs - inputsと同様のオブジェクトの配列
  • stateMutability - 関数のミュータビリティを定義(pure、view、non-payableまたはpayable

ABIを用いたトランザクションはどのように機能するか

Solidity ABIファイルを用いたトランザクションは、以下の3つのステップで機能します:

  1. スマートコントラクトのABIが、EtherJSのようなフロントエンドライブラリに提供されます。
  2. フロントエンドライブラリは、メソッド呼び出しと引数を_calldata_に変換し、これがトランザクションの一部としてEthereumノードに提供されます。
  3. トランザクションが検証されると、詳細なログと使用されたgas(トランザクション手数料)を含むレシートトライが生成されます。

レシートトライとは何か

Ethereumのトランザクションは、成功したトランザクションの結果を記録する「レシートトライ」と呼ばれるレシートを生成します。 レシートトライは、以下の4種類の情報から構成されます:

  1. トランザクションの状態
  2. 累積使用gas量
  3. 実行中に生成されたログの集合
  4. ログから構成されるBloomフィルタ

トランザクションの動作をより理解するために、次の例を見てみましょう。

ERC-20トークン送金の例

例えば、ERC-20トークンをあるウォレットから別のウォレットに送金したいとします。以下のコードは、ABIに対してEVMベースのバイトコードにメッセージを送るよう指示します。

ABIエンコーディングは、バイトコードがその関数を認識し、トランザクションを実行することを保証します。結果が生成された後、ABIデコーディングによってその結果が人間の読める形式に変換されます。ユーザーは、ERC-20トークンがあるアドレスから別のアドレスに送金されたことを示すレシートを受け取ります。

Solidity ABIについてさらに学ぶ

Solidityを学ぶ過程で、ABIがEthereumスマートコントラクトの中核であることが理解できるでしょう。ABIは、ブロックチェーンエコシステムにおけるトランザクションを可能にします。スマートコントラクト技術においてABIが重要であるにもかかわらず、開発者向けのチュートリアルではABIが見過ごされがちです。この記事の範囲を超えますが、Solidityインターフェースが何であるかを知ることで、コントラクト同士がどのようにやり取りするかについての理解がさらに深まるでしょう。

ABIを深く理解することは、堅牢なスマートコントラクトやアプリを開発し、Solidity開発者になるための足がかりとなります。

Background gradient

ブロックチェーンで魔法を生み出す

Alchemyは、最も強力なweb3開発者向けプロダクトとツールを、豊富なリソース、コミュニティ、そして卓越したサポートと組み合わせて提供します。