「SolidityとEthereumによる実践スマートコントラクト開発」の沼4
第4章p51~p56でコントラクトをコンパイル/デプロイする過程でTDDを実施。
コマンドセット
-
truffle init
=新しいtruffleプロジェクトを初期化 -
truffle compile
=contracts配下のコントラクトを全てコンパイル -
truffle migrate
=migrations配下のスクリプトを実行することで、コンパイル済みのコントラストをデプロイ -
truffle test
=test配下のテストを実施
ubuntuを起動して、プロジェクトのセットアップ
$ mkdir greeter
$ cd greeter
$ truffle init
Starting init...
================
> Copying project files to /home/sekai/greeter
Init successful, sweet!
Try our scaffold commands to get started:
$ truffle create contract YourContractName # scaffold a contract
$ truffle create test YourTestName # scaffold a test
http://trufflesuite.com/docs
階層構造はこんな感じ
$ tree
.
├── contracts
│ └── Migrations.sol
├── migrations
│ └── 1_initial_migration.js
├── test
└── truffle-config.js
TDDでテストコード書いて、コード管理やリファクタリングに生かそう!
$ touch test/greeter_test.js
①truffleにおいてartifacts.requireで、コンパイル済みのコントラクトを読み込んで操作可能になる
③ブロックチェーンとのやり取りはすべて非同期で行われるため、JSのasync/await構文を使う
const GreeterContract = artifacts.require("Greeter"); ①
contract("Greeter", () => {
it("has been deployed successfully", async () => { ③
const greeter = await GreeterContract.deployed();
assert(greeter, "contract failed to deploy");
});
});
さて、テストを実行してみよう
$ truffle test
Compiling your contracts...
===========================
✔ Fetching solc version list from solc-bin. Attempt #1
✔ Downloading compiler. Attempt #1.
> Compiling ./contracts/Migrations.sol
> Artifacts written to /tmp/test--1681-8XFoMaAqwVoQ
> Compiled successfully using:
- solc: 0.8.9+commit.e5eed63a.Emscripten.clang
Error: Could not find artifacts for Greeter from any sources
at Resolver.require (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/resolver.js:61:1)
at Object.require (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/Test.js:281:1)
at Object.<anonymous> (/home/sekai/greeter/test/greeter_test.js:1:35)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:93:18)
at /home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/node_modules/mocha/lib/mocha.js:390:36
at Array.forEach (<anonymous>)
at Mocha.loadFiles (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/node_modules/mocha/lib/mocha.js:387:14)
at Mocha.run (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/node_modules/mocha/lib/mocha.js:961:10)
at /home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/Test.js:157:1
at new Promise (<anonymous>)
at Object.run (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/Test.js:156:1)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at Object.run (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/test/index.js:208:1)
at Command.run (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/core/lib/command.js:183:1)
Truffle v5.4.16 (core: 5.4.16)
Node v14.18.0
フィードバックの大まかなポイントとしては下記の通り
/コントラクトのコンパイルが通り成功した。
> Compiled successfully using:
- solc: 0.8.9+commit.e5eed63a.Emscripten.clang
//しかし、Greeterというソースはどこにも見つからない(Truffleが見つけられていない)
Error: Could not find artifacts for Greeter from any sources
もちろん、テストで書いたコントラクト名は未実装の内容であるため、妥当な内容である。
では、contracts/Greeter.solを作成して、このエラーをなくしてみよう。
pragma solidity >= 0.4.0 < 0.7.0;
contract Greeter {
}
もっかいテストを走らせよう
$ truffle test
Compiling your contracts...
===========================
> Compiling ./contracts/Greeter.sol
> Compiling ./contracts/Migrations.sol
ParserError: Source file requires different compiler version (current compiler is 0.8.9+commit.e5eed63a.Emscripten.clang) - note that nightly builds are considered to be strictly less than the released version
--> project:/contracts/Greeter.sol:1:1:
|
1 | pragma solidity >= 0.4.0 < 0.7.0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Truffle is currently using solc 0.8.9, but one or more of your contracts specify "pragma solidity >= 0.4.0 < 0.7.0".
Please update your truffle config or pragma statement(s).
(See https://trufflesuite.com/docs/truffle/reference/configuration#compiler-configuration for information on
configuring Truffle to use a specific solc compiler version.)
Compilation failed. See above.
Truffle v5.4.16 (core: 5.4.16)
Node v14.18.0
フィードバックではpragmaの互換性がないと怒られている。
pragma行はコンパイラ命令であり、Solidityのバージョン指定範囲に互換性があることをコンパイラに伝えている。
少しバージョン指定範囲が狭いようなので、下記のように変更。
pragma solidity >=0.4.22 <0.9.0;
contract Greeter {
}
で、もっかいテスト
$ truffle test
Compiling your contracts...
===========================
> Compiling ./contracts/Greeter.sol
> Compiling ./contracts/Migrations.sol
> Compilation warnings encountered:
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> project:/contracts/Greeter.sol
> Artifacts written to /tmp/test--1834-i8q7CvOeNwqq
> Compiled successfully using:
- solc: 0.8.9+commit.e5eed63a.Emscripten.clang
Contract: Greeter
1) has been deployed successfully
> No events were emitted
0 passing (120ms)
1 failing
1) Contract: Greeter
has been deployed successfully:
Error: Greeter has not been deployed to detected network (network/artifact mismatch)
at Object.checkNetworkArtifactMatch (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/contract/lib/utils/index.js:247:1)
at Function.deployed (/home/sekai/.nvm/versions/node/v14.18.0/lib/node_modules/truffle/build/webpack:/packages/contract/lib/contract/constructorMethods.js:83:1)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at Context.<anonymous> (test/greeter_test.js:5:21)
p55の応答と同じ成果を得られた。
しかし、ネットワークにはこのコントラクトが存在しないことが記載されている。
Error: Greeter has not been deployed to detected network (network/artifact mismatch)
上記の手順にて、truffle testを行うことで
①コントラクトをコンパイル
②それらをテストネットにデプロイ
が見えてくる。
②を行うには、truffle migrateが必要。
( ..)φメモメモ
そもそも、マイグレーションは、JSで記載されたスクリプトであり、コントラクトのテストネットデプロイを自動化するもの
たとえば、Migrations.solは1_initial_migration.jsによって自動デプロイされている、まじでかああ
つまり、作成した空コントラクト(Greeter.sol)をデプロイするにはMIgrations配下にマイグレーションスクリプトを作成する必要がある。
2_deploy_greeter.js:
const GreeterContract = artifacts.require("Greeter");
module.exports = function(deployer) {
deployer.deploy(GreeterContract);
}
デプロイしよう
$ truffle test
Compiling your contracts...
===========================
> Compiling ./contracts/Greeter.sol
> Compiling ./contracts/Migrations.sol
> Compilation warnings encountered:
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> project:/contracts/Greeter.sol
> Artifacts written to /tmp/test--1934-CtniGQqCXGfN
> Compiled successfully using:
- solc: 0.8.9+commit.e5eed63a.Emscripten.clang
Contract: Greeter
✓ has been deployed successfully
1 passing (82ms)
p56の出力と同じ、これで機能実装に必要なセッティングが完了した。