初心者向けのHello Worldスマートコントラクト
このチュートリアルは、ブロックチェーンの開発が初めてで、どこから始めたらよいのか分からない場合や、 スマートコントラクトをデプロイしてやり取りする方法を理解したいだけの場合に、最適なガイドとなります。 このチュートリアルでは、仮想ウォレット(MetaMask(opens in a new tab))、Solidity(opens in a new tab)、Hardhat(opens in a new tab)、Alchemy(opens in a new tab)を使用して、Goerli テストネットワーク上で簡単なスマートコントラクトを作成してデプロイする方法を順を追って説明します(現時点でしっかりと理解できていなくても、心配はご無用です。後ほど説明します)。
このチュートリアルのパート 2(opens in a new tab)では、ここでデプロイしたスマートコントラクトとやり取りする方法について説明します。パート 3(opens in a new tab)では、そのスマートコントラクトを Etherscan で公開する方法について説明します。
質問がある場合は、いつでもAlchemy Discord(opens in a new tab)でお問い合わせください。
ステップ 1: イーサリアムネットワークに接続する
イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡略化のため、ここでは Alchemy の無料アカウントを使用します。これは独自のノードを実行することなく、イーサリアムチェーンとの通信を可能にするブロックチェーンのデベロッパープラットフォームと API です。 このプラットフォームには、スマートコントラクトのデプロイメントにおいて内部で何が起こっているのかを把握するためにこのチュートリアルで利用する、監視と分析のためのデベロッパーツールも備わっています。 Alchemy のアカウントをお持ちでない場合は、こちら(opens in a new tab)から無料で登録できます。
ステップ 2: アプリ(および API キー)を作成する
Alchemy のアカウントを作成すると、アプリを作成することで API キーを生成できるようになります。 これにより、Goerli テストネットワークへのリクエストが可能になります。 テストネットに詳しくない場合は、こちらのページをご覧ください。
- ナビゲーションバーの「Apps」にマウスを合わせて、「Create App」をクリックし、Alchemy ダッシュボードの「Create App」ページに移動してください。
- アプリに「Hello World」という名前を付け、簡単な説明を記述し、環境に「Staging」を選択(アプリのブックキーピングに使用)し、ネットワークに「Goerli」を選択します。
- 「Create app」をクリックして完了です。 アプリが下の表に表示されます。
ステップ 3: イーサリアムアカウント(アドレス)を作成する
トランザクションの送受信には、イーサリアムアカウントが必要です。 このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットである Metamask を使用します。 トランザクションの詳細。
Metamask のアカウントはこちら(opens in a new tab)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は(実際に支払いが発生しないように)右上の「Goerli Test Network」に切り替えてください。
ステップ 4: フォーセットからイーサ(ETH)を追加する
テストネットワークにスマートコントラクトをデプロイするには、偽の ETH が必要になります。 ETH を取得するには、Goerli フォーセット(opens in a new tab)にアクセスし、Alchemy アカウントでログインしてウォレットアドレスを入力し、「Send Me ETH」をクリックしてください。 ネットワークトラフィックのために偽の ETH を受け取るのに時間がかかる場合があります。 (この記事の執筆時点では、30 分ほどかかりました。) MetaMask アカウントに ETH が表示されるはずです!
ステップ 5: 残高を確認する
残高を再確認するために、eth_getBalance(opens in a new tab)をAlchemy のコンポーザーツール(opens in a new tab)を使用してリクエストしてみましょう。 このリクエストをすると、ウォレット内の ETH の額が返されます。 MetaMask アカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。
1{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }コピー
注: この結果の単位は、ETH ではなく wei です。 wei は ETH の最小単位として使われています。 wei から ETH へ変換すると、1 eth = 1018 wei になります。 つまり、0x2B5E3AF16B1880000 を 10 進数に変換すると、5*10¹⁸ となり、5 ETH に相当します。
ご安心ください。 偽のお金はすべてそこにあります
。
ステップ 6: プロジェクトを初期化する
まず、プロジェクトのフォルダを作成する必要があります。 コマンドラインに移動し、次のように入力します。
1mkdir hello-world2cd hello-world
プロジェクトフォルダ内に入ったら、npm init
を使用してプロジェクトを初期化します。 まだ npm がインストールされていない場合は、こちらの手順(opens in a new tab)に従ってください(Node.js も必要となりますので、こちらもダウンロードしてください。)
1npm init
インストール時の質問についてはどのように回答してもかまいませんが、参考までに以前行った回答を以下に示します。
1package name: (hello-world)2version: (1.0.0)3description: hello world smart contract4entry point: (index.js)5test command:6git repository:7keywords:8author:9license: (ISC)10About to write to /Users/.../.../.../hello-world/package.json:1112{13 "name": "hello-world",14 "version": "1.0.0",15 "description": "hello world smart contract",16 "main": "index.js",17 "scripts": {18 "test": "echo \\"Error: no test specified\\" && exit 1"19 },20 "author": "",21 "license": "ISC"22}すべて表示
package.json を承認すれば完了です。
ステップ 7: Hardhat(opens in a new tab)をダウンロードする
Hardhat は、イーサリアムのソフトウェアをコンパイル、デプロイ、テスト、デバッグするための開発環境です。 デベロッパーがライブチェーンにデプロイする前に、スマートコントラクトや分散型アプリケーション(Dapp)をローカルに構築する際に役立ちます。
先ほど作成したhello-world
プロジェクト内で、以下を実行します。
1npm install --save-dev hardhat
インストール手順(opens in a new tab)の詳細については、こちらのページをご覧ください。
ステップ 8: Hardhat プロジェクトを作成する
プロジェクトフォルダ内で以下を実行します。
1npx hardhat
ウェルカムメッセージと、次に何をするのかを選択できるオプションが表示されます。 「Create an empty hardhat.config.js」を選択します。
1888 888 888 888 8882888 888 888 888 8883888 888 888 888 88848888888888 8888b. 888d888 .d88888 88888b. 8888b. 8888885888 888 "88b 888P" d88" 888 888 "88b "88b 8886888 888 .d888888 888 888 888 888 888 .d888888 8887888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.8888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888910👷 Welcome to Hardhat v2.0.11 👷?1112What do you want to do? …13Create a sample project14❯ Create an empty hardhat.config.js15Quitすべて表示
hardhat.config.js
ファイルが生成されます。このファイルでプロジェクトのすべての設定を行います(ステップ 13 で行います)。
ステップ 9: プロジェクトフォルダを追加する
プロジェクトを整理するために、2 つの新しいフォルダを作成します。 コマンドラインでプロジェクトのルートディレクトリに移動し、次のように入力します。
1mkdir contracts2mkdir scripts
contracts/
は、Hello World スマートコントラクトのコードファイルを格納する場所です。scripts/
は、コントラクトをデプロイして対話するスクリプトを保持する場所です。
ステップ 10: コントラクトを作成する
一体いつになったらコードを書くのだろうと疑問をお持ちではないでしょうか 。 このステップ 10 でコードを書いていきましょう。
お気に入りのエディタで hello-world プロジェクトを開きます(通常はVScode(opens in a new tab)を使用しています)。 スマートコントラクトは、Solidity と呼ばれる言語で記述されています。HelloWorld.sol スマートコントラクトの作成にこの言語を使用します。
- 「contracts」フォルダに移動し、HelloWorld.sol という名前の新規ファイルを作成します。
- 以下は、このチュートリアルで使用するイーサリアム・ファウンデーションの Hello World スマートコントラクトのサンプルです。 以下の内容をコピーして、HelloWorld.sol ファイルに貼り付けます。コメントを読んで、このコントラクトが何を行うのかを理解してください。
1// Specifies the version of Solidity, using semantic versioning.2// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma3pragma solidity ^0.7.0;45// Defines a contract named `HelloWorld`.6// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html7contract HelloWorld {89 // Declares a state variable `message` of type `string`.10 // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.11 string public message;1213 // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.14 // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors15 constructor(string memory initMessage) {1617 // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).18 message = initMessage;19 }2021 // A public function that accepts a string argument and updates the `message` storage variable.22 function update(string memory newMessage) public {23 message = newMessage;24 }25}すべて表示コピー
これは、作成時にメッセージを保存し、update
関数を呼び出すことで更新できる非常にシンプルなスマートコントラクトです。
ステップ 11: MetaMask と Alchemy をプロジェクトに接続する
ここまでで、MetaMask ウォレットと Alchemy アカウントを作成し、スマートコントラクトも作成しました。次はこの 3 つを接続しましょう。
仮想ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使用した署名が必要です。 この権限をプログラムに提供するため、秘密鍵(および Alchemy API キー)を環境ファイルに安全に保存できます。
トランザクションの送信の詳細については、web3 を使用したトランザクションの送信についてのこちらのチュートリアルをご覧ください。
まず、プロジェクトディレクトリに dotenv パッケージをインストールします。
1npm install dotenv --save
次に、 .env
ファイルをプロジェクトのルートディレクトリに作成し、そのファイルに Metamask の秘密鍵と HTTP Alchemy API の URL を追加します。
- 秘密鍵をエクスポートするには、こちらの手順(opens in a new tab)に従ってください。
- HTTP Alchemy API の URL を取得するには、以下を参照してください。
Alchemy API の URL をコピーします。
.env
ファイルは次のようになります。
1API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"2PRIVATE_KEY = "your-metamask-private-key"
これらの変数を実際にコードに接続するために、ステップ 13 でこれらの変数をhardhat.config.js
ファイル内で参照します。
.env
ファイルをコミットしないでください! .env
ファイルを誰かと共有したり公開したりしないようにしてください。秘密が漏洩する可能性があります。 バージョン管理ツールを使用している場合は、.env
をgitignore(opens in a new tab)ファイルに追加します。ステップ 12: Ethers.js をインストールする
Ethers.js は、よりユーザーフレンドリーなメソッドで標準の JSON-RPC メソッドをラップすることにより、イーサリアムとの対話やリクエストを簡単にするライブラリです。
Hardhat は、追加のツールと拡張機能のためのプラグイン(opens in a new tab)の統合を非常に簡単にしてくれます。 コントラクトのデプロイメントにEthers プラグイン(opens in a new tab)を利用します(Ethers.js(opens in a new tab)には、複数の非常にクリーンなコントラクトのデプロイメント方法があります)。
プロジェクトのホームディレクトリで以下を実行します。
1npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"
次のステップのhardhat.config.js
でも Ethers(.js)が必要になります。
ステップ 13: hardhat.config.js を更新する
ここまでで、いくつかの依存関係とプラグインを追加しました。次に、hardhat.config.js
を更新して、プロジェクトがそれらすべてについて認識できるようにする必要があります。
hardhat.config.js
を以下のように更新します。
1require('dotenv').config();23require("@nomiclabs/hardhat-ethers");4const { API_URL, PRIVATE_KEY } = process.env;56/**7* @type import('hardhat/config').HardhatUserConfig8*/9module.exports = {10 solidity: "0.7.3",11 defaultNetwork: "goerli",12 networks: {13 hardhat: {},14 goerli: {15 url: API_URL,16 accounts: [`0x${PRIVATE_KEY}`]17 }18 },19}すべて表示
ステップ 14: コントラクトをコンパイルする
ここまででしっかりと動作していることを確認するため、コントラクトをコンパイルしてみましょう。 compile
タスクは、組み込みの Hardhat タスクの 1 つです。
コマンドラインで以下を実行します。
1npx hardhat compile
SPDX license identifier not provided in source file
という警告が表示される場合がありますが、心配する必要はありません。警告が表示されないのがベストですが、 表示された場合は、いつでもAlchemy discord(opens in a new tab)でメッセージを送信できます。
ステップ 15: デプロイスクリプトを書く
コントラクトの作成と設定ファイルの作成が完了したら、いよいよコントラクトのデプロイのためのスクリプトを作成します。
scripts/
フォルダに移動して、deploy.js
という名前のファイルを新規に作成し、以下の内容を追加します。
1async function main() {2 const HelloWorld = await ethers.getContractFactory("HelloWorld");34 // Start deployment, returning a promise that resolves to a contract object5 const hello_world = await HelloWorld.deploy("Hello World!");6 console.log("Contract deployed to address:", hello_world.address);}78main()9 .then(() => process.exit(0))10 .catch(error => {11 console.error(error);12 process.exit(1);13 });すべて表示
Hardhat がコードの各行で行っている驚くべき内容については、Hardhat のコントラクトチュートリアル(opens in a new tab)で説明されています。以下では、その説明を採用しています。
1const HelloWorld = await ethers.getContractFactory("HelloWorld");
ethers.js のContractFactory
は新しいスマートコントラクトをデプロイするための抽象化であり、ここでのHelloWorld
は hello world コントラクトのインスタンスのためのファクトリです。 hardhat-ethers
プラグインを使用する場合、ContractFactory
およびContract
インスタンスはデフォルトで最初の署名者に接続されます。
1const hello_world = await HelloWorld.deploy();
ContractFactory
でdeploy()
を呼び出すとデプロイメントが開始され、Contract
に解決すべきPromise
が返されます。 これは、スマートコントラクトの各関数に対するメソッドを持つオブジェクトです。
ステップ 16: コントラクトをデプロイする
ようやく、スマートコントラクトをデプロイする準備が整いました。 コマンドラインに移動し、以下を実行します。
1npx hardhat run scripts/deploy.js --network goerli
次のような画面が表示されるはずです。
1Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
Goerli etherscan(opens in a new tab)に移動し、コントラクトアドレスを検索すると、コントラクトが正常にデプロイされていることを確認できるはずです。 トランザクションは以下のようなものになります。
From
アドレスは MetaMask アカウントアドレスと一致する必要があります。To アドレスには「Contract Creation」と表示されますが、トランザクションをクリックすると、To
フィールドにコントラクトアドレスが表示されます。
おめでとうございます! イーサリアムチェーンにスマートコントラクトをデプロイできました 🎉
内部で何が起こっているのかを理解するために、Alchemy ダッシュボード(opens in a new tab)の Explorer タブに移動してみましょう。 Alchemy のアプリが複数ある場合は、必ずアプリでフィルタリングし、「Hello World」を選択してください。
ここでは、.deploy()
関数を呼び出した際に、Hardhat/Ethers が内部で行った JSON-RPC の呼び出しを見ることができます。 ここで呼び出している 2 つの重要な JSON-RPC は、実際に Goerli チェーン上でコントラクトを書き込むリクエストのeth_sendRawTransaction
(opens in a new tab)と、(トランザクションの際の典型的なパターンである)ハッシュを与えられているトランザクションに関する情報を読み取るリクエストのeth_getTransactionByHash
(opens in a new tab)です。 トランザクションの送信の詳細については、こちらのチュートリアルのWeb3 を使用したトランザクションの送信をご覧ください。
こちらのチュートリアルのパート 1 は以上となります。パート 2 では初期メッセージの更新によるスマートコントラクトとの実際のやり取り(opens in a new tab)を、パート 3 ではEtherscan へのスマートコントラクトの公開(opens in a new tab)を行い、やり取りする方法を学びます。
Alchemy の詳細については、 ウェブサイト(opens in a new tab)をご覧ください。 アップデートを見逃したくない場合は、 こちら(opens in a new tab)でニュースレターを購読してください。 Twitter(opens in a new tab)もあわせてフォローし、Discord(opens in a new tab)にもご参加ください。
最終編集者: @, 2023年8月15日