プライベートネット上でスマートコントラクト実装
はじめに
本記事はローカルの環境で実装を行っています。
そのため、環境が整っていない方は、下記記事を参考に環境を整えることで、同様の操作で進めることができると思います。
実行環境
Ubuntu 22.04.2
Solidity 0.8.20
geth 1.12.0
Solidityコンパイラ(solc)のインストール
$ sudo add-apt-repository ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install solc
インストールの確認
$ solc --help
HelloWorld.solファイルの作成
バージョン(0.8.20)を使用している
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract HelloWorld {
function sayHelloWorld() public pure returns (string memory) {
return "Hello World";
}
}
コンパイル
下記コマンドでコンパイルを行い、出力内容を記録しておく(トランザクション送信時に使用)
$ solc --abi --evm-version paris --bin HelloWorld.sol
出力
Binary:
長いので省略
6080604052348015~ 長いので省略 ~0008140033
Contract JSON ABI
[{"inputs":[],"name":"sayHelloWorld","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]
注意
バージョン0.8.20から「--evm-version」のデフォルト値が「shanghai」になっている。
そのため、ローカルでブロックチェーンを起動させている場合、EVMのバージョンとの差により、トランザクションとして送信するときエラーになる可能性がある。
出力されるエラー:「invalid opcode: PUSH0"」
それを回避するため、上記コマンドでは意図的に「--evm-version paris」としている。
トランザクション送信
consoleを指定しそのまま対話型で進めてもよいがログを確認したいため、今回は指定せずに起動
$ geth --datadir data --networkid 12345 --nodiscover --mine --unlock 0xE508ba2eF0075d89979dE7F5973db88F4d56B5e3 --miner.etherbase 0xE508ba2eF0075d89979dE7F5973db88F4d56B5e3
別ターミナルで対話型コンソールにアタッチする。
$ geth attach data/geth.ipc
変数にコンパイル時出力されたbinaryとabiを格納する。
binの頭に「0x」を入れておく。
> bin = "0x6080604052348~ 長いので省略 ~430008140033"
> abi = [{"inputs":[],"name":"sayHelloWorld","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]
> cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin})
出力ログ
INFO [07-18|18:14:56.971] Setting new local account address=0xE508ba2eF0075d89979dE7F5973db88F4d56B5e3
INFO [07-18|18:14:56.973] Submitted contract creation hash=0x044fdca630b208c6f6551636e616da58ae1587ba1ec003924ff19bba4aa91225 from=0xE508ba2eF0075d89979dE7F5973db88F4d56B5e3 nonce=4 contract=0xC5b437a088B58717CD8ead6B65EDCD687eBF4661 value=0
INFO [07-18|18:14:57.004] Commit new sealing work number=561 sealhash=fb6553..6d4a63 uncles=0 txs=1 gas=133,111 fees=0.000133111 elapsed="964.6μs"
INFO [07-18|18:14:58.002] Successfully sealed new block number=561 sealhash=fb6553..6d4a63 hash=672ecd..538112 elapsed=997.683ms
ログを見ると、contractのアドレス「0xE508ba2eF0075d89979dE7F5973db88F4d56B5e3」が割り当たってることが確認できる。
contractへのアクセス
contractへアクセスするオブジェクトを作成する。
> contract_helloWorld = eth.contract(abi).at(cnt.address)
#出力
{
abi: [{
inputs: [],
name: "sayHelloWorld",
outputs: [{...}],
stateMutability: "pure",
type: "function"
}],
address: "0xc5b437a088b58717cd8ead6b65edcd687ebf4661",
transactionHash: null,
allEvents: function bound(),
sayHelloWorld: function bound()
}
sayHelloWorldの呼び出し
> contract_helloWorld.sayHelloWorld.call()
#出力
"Hello World"
おわりに
プライベートネット環境でのスマートコントラクト実装という感じで進めてみましたがどうでしたでしょうか。
自分自身、バージョンの問題などでかなり時間がかかってしまったんですが、何とか出来てよかったです・・・
やっと環境を作ることができたので、これからSolidityの勉強も進めていきたいと思います
勉強しながら記事の作成をしているので、内容に間違い等ございましたらご指摘よろしくお願いいたします。
日本語の情報が少なかったため、この記事が誰かの役に立てばすごい嬉しいです。