Solidity

【スマートコントラクト開発】最初のコントラクトで詰んだ話

今回は最初のコントラクトを作成してみよう編!

最初に失敗するテストを書いてから、次に成功させるコードを書く。

テストを成功させる過程でエラーを体験しておくことで、エラーの種類を知ることができ、対処方法が身に付く。

今回もオライリー社の「スマートコントラクト開発」から学んでいきます。

セットアップ

Macでターミナルを開いてさっそく入力していく。

アプリケーションを格納するようのディレクトリ(フォルダ)を作成します。

greeterという名前でディレクトリ作成。

mkdir greeter

作成したディレクトリに移動。

cd greeter

新しいtruffleプロジェクトを初期化。つぎのコマンド入力。

truffle init
このような出力がでればOK

greeterディレクトリにあるファイルを次のコマンドで表示。上記画像一番下。

greeter ls
  • contracts
  • migrations
  • test
  • truffle-config.js (アプリケーションの固有の設定はこのファイルに配置される。)

初期構造の準備が完了。

テスト駆動開発(Test-driven development)

最初のテストは空のコントラクトを正しくデプロイできることを確認する。

デプロイとは、配備する、配置する、展開する、配置につく、などの意味を持つ英単語。ITの分野では開発したソフトウェアを実際の運用環境に配置・展開して実用に供することを指す場合が多い。

コントラクト自体が存在しないエラー

testディレクトリにgreeter_test.jsというファイルを作成。

touch test/greeter_test.js

vimを開いてテストコードを追加。vimコマンドの後ろに作成したjsファイルの名前を記載。

vim greeter_test.js
コントラクトをデプロイできるかのテストコード

テストを実行すると。。。

truffle test
Eror: Could not find artifacts for Greeter from any sources

上記エラー画面では、コントラクトがコンパイルされたあと、TruffleがGreeterというコントラクトを見つけられなかったとわかる。

空のコントラクトで実行したので、上記エラーがでるのは当然です。

コンパイルとは、プログラミング言語で書かれたコンピュータプログラム(ソースコード)を解析し、コンピュータが直接実行可能な形式のプログラム(オブジェクトコード)に変換すること。そのためのソフトウェアをコンパイラ(compiler)という。

コントラクトがネットワーク上にデプロイされていないエラー

今度は、Greeterファイルを作成して

touch contracts/Greeter.sol

下記コードを追記

pragma solidity >= 0.4.0 < 0.7.0;

pragma行では、このコードにSolidityの0.4.0以上、0.7.0未満のバージョンとの互換性があることをコンパイラに伝えている。

バージョンは新しいものを入力しましょう!2022/2/6時点で0.8.11なので0.7.0でやると違うエラーがでます。

contract Greeter {

}

{}で囲まれたデータと関数・メソッドの定義はそのコントラクトだけのもので、他のコントラクトからは切り離される。

空のGreeterコントラクト

追記を行ったら再度テストコードを実行!

truffle test
こういうエラー出力

今回のエラーは、コントラクトがまだネットワーク上に存在していないことを示している。

truffle testコマンドを実行すると、まずコントラクトをコンパイル→テストネットワークにデプロイする。

そして、コントラクトをデプロイするためにはTruffleが提供する別のツール「マイグレーション」を使う。

マイグレーションを使ってデプロイする

「マイグレーション」はJavaScriptで書かれたスクリプトで、デプロイメントを自動化するために使う。

contractsディレクトリ内のMigrations.solファイルに含まれているデフォルトのマイグレーションコントラクトは、

migrationsディレクトリ内の1_initial_migration.jsファイルによってデプロイされる。

現時点でテストネットワーク上に存在してる唯一のコントラクトです。

Greeterコントラクトも同様にテストネットワーク上にデプロイするために、マイグレーションを作成する必要がある。

まずマイグレーションを格納するファイルを作成

touch migrations/2_deploy_greeter.js

このファイルにコードを追加、vimを開いて

vim 2_deploy_greeter.js
Greeterコントラクトをデプロイするコード
成功!

正しくセットアップされて準備が整ったことがわかりました。

Hello World!

通常であればこの段階で「Hello World」を出力するために printIn()などを使用しますが、

Solidityでは標準出力やファイルシステム、ネットワークなどにはアクセスできない。

Solidityにあるのは関数だけ。

デプロイされたスマートコントラクトはイーサリアムネットワークの特定のアドレスに格納されます。

コントラクトで実行できる処理は関数で定義されて、何らかの関数を実行する要求がくるまで休止状態になる。

なので、関数によって「Hello World」と出力させないといけません。

さきほど作成したtest/greeter_test.jsにテストを追加。

期待値を設定して、コントラクトから値を取り出し、それらの値が等しいかどうかを確認するテスト。

コントラクトとやりとりするためにローカルのテストブロックチェーンを呼び出すことになるため、

テスト関数をasyncとして定義する必要がある。

asyncとは非同期通信のこと。
非同期通信は、やり取りする相手からの反応を待たないで次の処理を始める通信です。
相手に要求を投げたら、応答が返ってくるまで待ちません。
さっさと次の処理を進めます。

テストを実行すると。。。

書籍に記載の通りのコードが出ない!!!

イレギュラーなエラーが二箇所。。。

謎エラー①:SPDX?

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

翻訳

Warning: SPDX ライセンスの識別子がソース ファイルで提供されていません。公開する前に、"SPDX-License-Identifier" を含むコメントを追加することを検討してください。" というコメントを各ソース ファイルに追加することを検討してください。SPDX-License-Identifier "を使用してください。オープンソースでないコードには、"UNLICENSED "を使用してください。詳しくは、https://spdx.org をご覧ください。
--> project:/contracts/Greeter.sol

要するに「このSolidityファイルはこう扱いましょう」みたいなテンプレの宣言文章のことだと思われる。

とりあえず文頭に

// SPDX-License-Identifier: GPL-2.0

と入力しておけば大丈夫らしい。

SPDXについてはこちらのサイトに助けられました。

謎エラー②:詰んだ。。

This version of µWS is not compatible with your Node.js build:

Error: Cannot find module './uws_darwin_x64_64.node'
Falling back to a NodeJS implementation; performance may be degraded.

翻訳

このバージョンの µWS は、ご使用の Node.js ビルドと互換性がありません。

Error: モジュール './uws_darwin_x64_64.node' が見つかりません。
NodeJSの実装にフォールバックします。パフォーマンスが低下する可能性があります。

Node.jsのバージョンが新くて、互換性がない??

ダウングレードしたら大丈夫そうな感じかな??

node.jsのバージョンを書籍の時点のバージョンにダウングレードして試してみましたが

結果は同じでした。。。

3日ググってわからず。。。解決したら追記します

-Solidity