イーサリアム開発環境(Geth)でスマートコントラクト(Solidity)を実行する

前回の記事ではイーサリアム開発環境で送金処理を行いました。

https://qiita.com/fugasat/items/5adca95a0a3231218f6a

今回はSolidityで簡単なスマートコントラクトを作って実行してみます。

# Solidityインストール

Solidityはブロックチェーン上で実行されるスマートコントラクトを記述するためのプログラミング言語です。

まずSolidityをインストールします。
以下コマンドを実行します。
```
$ brew tap ethereum/ethereum
$ brew install solidity
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.8.17+commit.8df45f5f.Darwin.appleclang
```

# スマートコントラクト作成

お約束の「Hello World」を実装します。
HelloWorld.solを作成します。
```
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract HelloWorld {
    function helloWorld() public pure returns (string memory) {
        return "Hello World!";
    }
}
```
コンパイルします。
```
$ solc --abi --bin HelloWorld.sol

======= HelloWorld.sol:HelloWorld =======
Binary:
608060405234801561001057600080fd5b50610173806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c605f76c14610030575b600080fd5b61003861004e565b604051610045919061011b565b60405180910390f35b60606040518060400160405280600c81526020017f48656c6c6f20576f726c64210000000000000000000000000000000000000000815250905090565b600081519050919050565b600082825260208201905092915050565b60005b838110156100c55780820151818401526020810190506100aa565b60008484015250505050565b6000601f19601f8301169050919050565b60006100ed8261008b565b6100f78185610096565b93506101078185602086016100a7565b610110816100d1565b840191505092915050565b6000602082019050818103600083015261013581846100e2565b90509291505056fea26469706673582212209b95e9b1f14a7392b0159486479a626f74c987694337205d513dcfaa968c0eed64736f6c63430008110033
Contract JSON ABI
[{"inputs":[],"name":"helloWorld","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]
```
ABI(Application Binary Interface)とはContractの取り扱い説明書のようなものです。関数の定義内容などが記載されています。

作成したスマートコントラクトをブロックチェーンにデプロイします。
gethコンソール上で以下コマンドを実行します。
binはコンパイル時に出力されたBinaryコードを指定します。
abiはコンパイル時に出力されたJSON ABIコードを指定します。
```
> bin = '（省略）'
> abi = [{"inputs":[],"name":"helloWorld","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xf53ac86545559b81188c48ecfd89183e74a05ba5
Passphrase: 
true
> contract = eth.contract(abi).new({from: eth.accounts[0], data: bin})
{
  abi: [{
      inputs: [],
      name: "helloWorld",
      outputs: [{...}],
      stateMutability: "pure",
      type: "function"
  }],
  address: undefined,
  transactionHash: "0x58799e7b46a782ae619c32ad980acb2c5bfea3c9752f84d4f114ce55d1eab10e"
}
> miner.start(1)
null
```

デプロイしたスマートコントラクトにアドレスが割り当てられていることを確認します。
```
> contract.address
"0x574b913226921fab7783e873ce4e04c792c020bf"
```

# スマートコントラクト実行

先ほどデプロイしたスマートコントラクトにアクセスするオブジェクトを生成します。
```
> contract_helloWorld = eth.contract(abi).at(contract.address)
{
  abi: [{
      inputs: [],
      name: "helloWorld",
      outputs: [{...}],
      stateMutability: "pure",
      type: "function"
  }],
  address: "0x574b913226921fab7783e873ce4e04c792c020bf",
  transactionHash: null,
  allEvents: function bound(),
  helloWorld: function bound()
}
```

このオブジェクトからスマートコントラクトを実行します。
```
> contract_helloWorld.helloWorld.call()
"Hello World!"
```
無事にメッセージが表示されました。  

今後はもっと勉強して、スマートコントラクト本来の目的である、ブロックチェーン上で契約を自動的に実行する仕組みを実装してみたいと考えています。

# 参考サイト  

https://note.com/npaka/n/n91b02969ee70#d4125eef-6ee9-4212-99b0-b91ec1abc369