Closed18

「SolidityとEthereumによる実践スマートコントラクト開発」の沼4

ikmzkroikmzkro

第4章p51~p56でコントラクトをコンパイル/デプロイする過程でTDDを実施。

ikmzkroikmzkro

コマンドセット

  • truffle init
    =新しいtruffleプロジェクトを初期化

  • truffle compile
    =contracts配下のコントラクトを全てコンパイル

  • truffle migrate
    =migrations配下のスクリプトを実行することで、コンパイル済みのコントラストをデプロイ

  • truffle test
    =test配下のテストを実施

ikmzkroikmzkro

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
ikmzkroikmzkro

階層構造はこんな感じ

$ tree
.
├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
└── truffle-config.js
ikmzkroikmzkro

TDDでテストコード書いて、コード管理やリファクタリングに生かそう!

$ touch test/greeter_test.js
ikmzkroikmzkro

①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");
  });
});
ikmzkroikmzkro

さて、テストを実行してみよう

$ 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
ikmzkroikmzkro

フィードバックの大まかなポイントとしては下記の通り

/コントラクトのコンパイルが通り成功した。
> Compiled successfully using:
   - solc: 0.8.9+commit.e5eed63a.Emscripten.clang

//しかし、Greeterというソースはどこにも見つからない(Truffleが見つけられていない)
Error: Could not find artifacts for Greeter from any sources
ikmzkroikmzkro

もちろん、テストで書いたコントラクト名は未実装の内容であるため、妥当な内容である。

では、contracts/Greeter.solを作成して、このエラーをなくしてみよう。

pragma solidity >= 0.4.0 < 0.7.0;
contract Greeter {

}
ikmzkroikmzkro

もっかいテストを走らせよう

$ 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
ikmzkroikmzkro

フィードバックではpragmaの互換性がないと怒られている。

pragma行はコンパイラ命令であり、Solidityのバージョン指定範囲に互換性があることをコンパイラに伝えている。

少しバージョン指定範囲が狭いようなので、下記のように変更。

pragma solidity >=0.4.22 <0.9.0;

contract Greeter {

}
ikmzkroikmzkro

で、もっかいテスト

$ 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)
ikmzkroikmzkro

p55の応答と同じ成果を得られた。
しかし、ネットワークにはこのコントラクトが存在しないことが記載されている。

Error: Greeter has not been deployed to detected network (network/artifact mismatch)
ikmzkroikmzkro

上記の手順にて、truffle testを行うことで
①コントラクトをコンパイル
②それらをテストネットにデプロイ
が見えてくる。

②を行うには、truffle migrateが必要。

ikmzkroikmzkro

( ..)φメモメモ

そもそも、マイグレーションは、JSで記載されたスクリプトであり、コントラクトのテストネットデプロイを自動化するもの

たとえば、Migrations.solは1_initial_migration.jsによって自動デプロイされている、まじでかああ

つまり、作成した空コントラクト(Greeter.sol)をデプロイするにはMIgrations配下にマイグレーションスクリプトを作成する必要がある。

ikmzkroikmzkro

2_deploy_greeter.js:

const GreeterContract = artifacts.require("Greeter");

module.exports = function(deployer) {
  deployer.deploy(GreeterContract);
}
ikmzkroikmzkro

デプロイしよう

$ 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)
ikmzkroikmzkro

p56の出力と同じ、これで機能実装に必要なセッティングが完了した。

このスクラップは2022/05/28にクローズされました