「SolidityとEthereumによる実践スマートコントラクト開発」を読んではまったところメモ
サンプルコード
p34
正誤表にも書かれているが、Parityのインストールコマンドは今は動かない
$ bash <(curl https://get.parity.io -L)
p84
訳注にある通りopenethereumコマンドでgoerliを起動しようとするとエラーになる
~$ openethereum --version
OpenEthereum Client.
version OpenEthereum/v3.2.1-stable-5fdedf0-20210317/x86_64-macos/rustc1.50.0
Copyright 2015-2020 Parity Technologies (UK) Ltd.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
By Wood/Paronyan/Kotewicz/Drwięga/Volf/Greeff
Habermeier/Czaban/Gotchac/Redman/Nikolsky
Schoedon/Tang/Adolfsson/Silva/Palm/Hirsz et al.
~$ openethereum --chain=goerli
For db versions 15 and lower (v2.5.13=>13, 2.7.2=>14, v3.0.1=>15) please use upgrade db tool to manually upgrade db: https://github.com/openethereum/3.1-db-upgrade-tool
Error: 1
マイグレーションとやらが必要らしい
ただ https://github.com/openethereum/3.1-db-upgrade-tool 通りにコマンドをやってみたが解決できなかったのでopenethereum自体を使うのを諦めてGethに変更した
OSごとのPARITY_PATHはここにのっている
Gethでgoerliネットワークに接続するのも、オプションの有無でLooking for peers
のまま止まったりして苦戦したが、以下のコマンドでブロックの同期を確認できた
$ geth --goerli --syncmode "fast" --rpc --nodiscover
goerliのetherscan
truffle migrate --network goerli
したときのgeth側のターミナルの出力
WARN [03-20|13:02:03.845] Served eth_call conn=127.0.0.1:61542 reqid=15 t="87.145µs" err="err: insufficient funds for gas * price + value (supplied gas 6721975)"
truffle migrate --network goerli
のdeployが失敗したのでgethのコマンドを調整
$ geth --goerli --networkid 5 --syncmode "full" --rpc --nodiscover
出たエラー
- "Migrations" could not deploy due to insufficient funds
- goerliのfausetでethは取ってきているのになぜか0になったので、syncmodeをfullにした(fastだとだめ?)
- Error: err: insufficient funds for gas * price + value (supplied gas 6721975)
- https://ja.stackoverflow.com/questions/41262/イーサリアムで送金エラー-error-insufficient-funds-for-gas-price-value を参考にgoerliのnetworkidの5を追加
Error: err: insufficient funds for gas * price + value (supplied gas 6721975)
が消えない
https://qiita.com/Hitoshi5858/items/be5a6181191df7b267dc#15-hdwalletprovider生成 を参考に、コンソールでウォレットの生成がうまくいってるか調べる
$ truffle console --network goerli
truffle(goerli)> const HDWallterProvider = require("truffle-hdwallet-provider");
truffle(goerli)> const wallet = new HDWallterProvider("***", "http://127.0.0.1:8545");
truffle(goerli)> wallet
自分のアドレスが出たので問題なさそう
truffleのコンソールでweb3.eth.getBlock('latest')
を見るとnumber: 4460643
で今の最新ブロックの4673975より古いので、gethの同期が遅れていると思われる
truffle(goerli)> web3.eth.getBlock('latest')
{
difficulty: '2',
extraData: '0x4e65746865726d696e6420312e31302e34312d302d6439646231653439392d32f8f2ba2b91bf1015cbd5caaa6bab369cf24b791d5c68e2f970b40f009c01929f7f3a34849eb8e5d56e6811260e4dfa6225272bee7987f147317ae1865d48187101',
gasLimit: '0x7a1200',
gasUsed: '0x6ad6',
hash: '0x8705d7d7a4aa189704385c325ff24ebc82496c87fff884e942bf4aba78467f0f',
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
miner: '0x0000000000000000000000000000000000000000',
mixHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
nonce: '0x0000000000000000',
number: 4460643,
parentHash: '0x036e0cbe4837efd839889a189ea6d090928dab590c461330bcebe7394401dcad',
receiptsRoot: '0x9f2d8f739b581108dae10ac0a55dde4116caf5d27603a49451a8145d7f7c89b4',
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
size: 753,
stateRoot: '0x77ce2e2871f7ac019106c0627114d71b3f3cd49ca38fb351f6a3dac26ccd86e2',
timestamp: 1616045376,
totalDifficulty: '6585792',
transactions: [
'0x14b59e81c20c1bdaf5ac5272c65aa7a98c3bcbcfe5a5ebbd492fe5d0301d751c'
],
transactionsRoot: '0x0521aa419883a72324d92666240db02b651f9e9148826f0a3e7da65f5b896b1d',
uncles: []
}
Looking for peers
のまま永遠に終わらなくなってしまったので、localに残ってたgoerliの同期データを消して再チャレンジ
$ rm -R ~/Library/Ethereum/goerli/geth/chaindata
syncmodeはfastに戻す、--nodiscover
は外す、--cache=1024
を付けてみる
$ geth --goerli --syncmode "fast" --rpc --cache=1024
やはり4460643でとまる
「4460643 goerli」で検索すると、https://gitter.im/paritytech/parity が引っかる
gethのcommitを見るとBerlin fork numberなるものが追加されていて、446064〜以降のIDが追加されている
ethハードフォークの影響っぽい
リリースタグはv1.10.2
使っていたgethのversion
$ geth version
Geth
Version: 1.9.24-stable
homebrewでinstallしたgethを上げる
$ brew upgrade ethereum
$ geth version
Geth
Version: 1.10.2-stable
同期中に以下のログがいっぱい出るようになった
INFO [04-24|22:12:28.482] Resuming state snapshot generation root="c43c22…b92ab8" in="4273c6…31ec3e" at="1701ed…759c98" accounts=299688 slots=6923981 storage=525.04MiB elapsed=52m44.745s eta=2h30m27.091s
INFO [04-24|22:12:28.742] Aborting state snapshot generation root="c43c22…b92ab8" in="4273c6…31ec3e" at="1b6847…9ae672" accounts=299688 slots=6924250 storage=525.06MiB elapsed=52m45.006s eta=2h30m27.835s
スナップショットの同期?をしているらしく最初はこのままにするつもりだったが、1ブロックを同期させるのに時間がかなり掛かるようになったので--snapshot=false
を追加する
$ geth --goerli --syncmode "fast" --rpc --cache=1024 --snapshot=false
truffle migrate --network goerli
時に、compileがないというエラーの場合は一度ファイルを削除して再度試してみる
本に沿っていた場合、./client/src/contracts
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Network up to date.
Network up to date.
"Migrations" -- only replay-protected (EIP-155) transactions allowed over RPC.
エラーが出て失敗
https://forum.openzeppelin.com/t/migrations-only-replay-protected-eip-155-transactions-allowed-over-rpc/6166/2 に沿って、--rpc.allow-unprotected-txs
を付けてgethを再起動
やっとgoerliでcontractをdeployできた。。長い戦いだった(p84)
最終的なgethコマンド
$ geth --goerli --syncmode "fast" --rpc --cache=1024 --snapshot=false --rpc.allow-unprotected-txs
最終的なtruffle-config.js
本に書いてあるコードと同じ
goerliの部分だけ抜粋
goerli: {
provider: () => {
const mnemonic = process.env["MNEMONIC"]
return new HDWallterProvider(mnemonic, "http://127.0.0.1:8545");
},
network_id: "*",
},
学び
- gethの最新バージョンを使う
- fausetからethを取ったのに、
insufficient funds for gas * price + value
とか出る場合は、同期しているブロックが最新になっているか確認する
$ truffle console --network goerli
truffle(goerli)> web3.eth.getBlock('latest', (error, block) => {console.log(block.number);});
4678565
p108
truffle-config.js に追加する
compilers: {
solc: {
version: "0.6.0", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
}
},
truffleを新しくしたら、0.8系のSolidityになってしまったのでファイルを更新
$ truffle version
Truffle v5.3.3 (core: 5.3.3)
Solidity - ^0.8.0 (solc-js)
Node v12.20.2
Web3.js v1.3.5
- truffle-config.js
version: "^0.8.0",
- contracts/Fundraiser.sol
pragma solidity >0.4.23 <0.9.0;
- contracts/Migrations.sol
pragma solidity >=0.4.21 <0.9.0;
p123
最新のOpenZeppelinはSafeMathがutilsの中に移動しているようなので、importも修正する必要がある
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
p147
deployed()
とnew()
の違い
p177
以下は別ターミナルでそれぞれ開いておく必要がある
$ truffle develop
$ npm run start
p179
新規に作って入ってないと思われるため、openzeppelin-solidityのインストールもいる
$ npm i openzeppelin-solidity
p182
以下のエラーが出て、hello worldが出ない
Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas?
エラーで検索すると、はまってる人が多い
再マイグレーション
以下でリセットしてみたが効果なかった
関係ないのかもしれないが、migrateコマンドは--reset
を付けないとうまくコンパイルされない気がする
$ rm -r client/src/contracts/
$ migrate --reset
solcのバージョン
https://zenn.dev/kuromoka/scraps/a8cf68d4ec033e#comment-eb159659c674b0 から0.8を使っていたのだが、本にも合わせてtruffleのsolcのバージョンを下げる
version: "0.6.0",
openzeppelin-solidityの部分で引っかかる
openzeppelin-solidity/contracts/access/Ownable.sol:3:1: ParserError: Source file requires different compiler version (current compiler is 0.6.0+commit.26b70077.Emscripten.clang - note that nightly builds are considered to be strictly less than the released version
pragma solidity ^0.8.0;
^---------------------^
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md#400-2021-03-23 > Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin.
と書かれているので、3.4.0をインストールし直す
$ npm uninstall openzeppelin-solidity
$ npm install openzeppelin-solidity@v3.4.0
これをやっても同様のエラー
metamask設定
http://127.0.0.1:8545
をmetamaskのカスタムRPCに追加しなきゃだめ
http://localhost:8545
のRPCを使っていたのがだめだったもよう
truffle develop
したときに出る、テスト用アカウントをmetamaskにインポート
RPCの違いでなぜか以下の挙動になる
-
http://127.0.0.1:8545
エラーが出ないが、テスト用のETHがもらえないのでトランザクションを送れない -
http://localhost:8545
テスト用のETHが100反映されているが、前述のエラーが出るのでアプリが動かない
truffleとmetamaskで、127.0.0.1のport番号を変えてみたら解決
develop: {
port: 9545,
}
10章、11章は正直説明がざっくりしすぎている・・・
サンプルコードも11章が終わった時点のコードしかなく、本を見ながらステップを踏んでやれば理解は深まりそうだが、本に書いてあるコードを1文字1文字打っていくのは大変