# Web3勉強記: FoundryでERC20トークンをデプロイする **Published by:** [hatone](https://paragraph.com/@hatone/) **Published on:** 2024-04-01 **URL:** https://paragraph.com/@hatone/web3-foundry-erc20 ## Content @hatoneです。 Web3といえばSTEPNで遊んだくらい…だったのですが、Etherscanのログを眺めるところからはじまり、そろそろ自分で実装・テスト・デプロイを一通り理解したいと思い立ったので、学んだことまとめを書いてみます。フレームワーク| Truffle、Hardhat、FoundryTruffle、Hardhat、Foundryは、いずれもEthereumスマートコントラクトの開発を支援するフレームワークですが、特徴や強みが異なります。Truffleは長い間業界標準だったようですが、Hardhatがより柔軟で拡張性の高い代替手段として盛り上がってきているらしいです。Foundryは比較的新しいツールで、その速度と効率性から急速に注目を集めています。特に、堅牢なテストとファジング機能が高く評価されています。実際に、私が他のWeb3エンジニアの方から勧めてもらったのはFoundryでした。Truffle最も歴史のあるスマートコントラクト開発フレームワークの一つで、広く採用されているGanacheという組み込みのローカルEthereumネットワークを提供し、テストやデバッグを容易にてるコントラクトのコンパイル、テスト、デプロイのためのコマンドラインツールがあるTruffleコンソールを使用して、インタラクティブにコントラクトとやり取りができるHardhatHardhat Network は、フォークやデバッグトレースなどの高度な機能を備えたローカルEthereumネットワークプラグインアーキテクチャを採用しており、プラグインを通じて機能を拡張Typescript のサポートが組み込まれており、型安全な開発が可能今回選択したFoundryRustで書かれた新しいスマートコントラクト開発ツールセットコンパイル、テスト、デプロイのためのコマンドラインツール。そして速いForgeテストフレームワークは、スマートコントラクトのファジングやプロパティベースのテストを可能Vyper というスマートコントラクト言語のサポートFoundryは、Solidityスマートコントラクトの開発、テスト、デプロイのための強力なツールセットです。Truffle、Hardhatなどの他のフレームワークと比較して、Foundryは高速なコンパイル、テストの実行、そしてネイティブのFuzzテストをサポートしています。 今回、Foundryを選択した理由は以下の通り:ネイティブのFuzzテストをサポートドキュメントが割としっかりしてるRustで書かれており、高速で効率的Solidityとシームレスに統合開発言語 | SolidityとVyperSolidityとVyperは、どちらもEthereumスマートコントラクトを開発するための高レベルプログラミング言語ですが、設計思想や目的が異なります。 Solidityは、JavaScriptに似た構文を持ち、オブジェクト指向プログラミングをサポートしています。一方、Vyperは、Pythonに影響を受けた構文を持ち、シンプルで読みやすいコードを書くことに重点を置いています。言語機能としてVyperはモジュラー性を重視するあまり、機能が絞られているようです。ただ、シンプルな機能を実装をしたい場合、Vyperで提供されている機能内で収まりそうなら、そっちを使うという将来がありそうな気がしました。今回はSolidityを使用しましたが、Vyperでのスマートコントラクト開発にも挑戦してみたいです。ステップ0: Foundryインストールcurl -L https://foundry.paradigm.xyz | bash foundryup エラー: libusb-1.0.0.dylib が見つからない私の環境では、forgeコマンドを実行した際に必要なライブラリ libusb-1.0.0.dylib が見つからないという問題が発生してていました。brew install libusbで入れておきました。謎のメッセージ:rustup update stable info: syncing channel updates for 'stable-x86_64-apple-darwin' stable-x86_64-apple-darwin unchanged - rustc 1.76.0 (07dca489a 2024-02-04) info: self-update is disabled for this build of rustup info: any updates to rustup will need to be fetched with your system package manager このメッセージはRustの安定版が最新であること、そしてrustupの自己更新がこのビルドでは無効であるため、システムのパッケージマネージャーを通じてrustupを更新する必要があることを示しています。brew upgrade rustupで上げました。ステップ1: プロジェクトのセットアップまず、新しいFoundryプロジェクトを作成しましょう。ターミナルで以下のコマンドを実行しますforge init MyToken cd MyToken 次に、OpenZeppelinライブラリをインストールforge install OpenZeppelin/openzeppelin-contracts OpenZeppelin ContractsとはなにかOpenZeppelin Contractsは、セキュリティと再利用性を重視したスマートコントラクトのオープンソースライブラリです。このライブラリは、Solidityで書かれており、以下のような一般的なスマートコントラクトの機能を提供しています。ERC20トークン:fungibleトークン(互換性のあるトークン)を実装するための標準インターフェースERC721トークン:非fungibleトークン(NFT)を実装するための標準インターフェースアクセス制御:スマートコントラクトの関数へのアクセスを管理するためのロールベースのアクセス制御システムアップグレード可能なコントラクト:スマートコントラクトをアップグレードするためのメカニズムOpenZeppelin Contractsを使用する主なメリットは、一般的な機能を実装する際に、ゼロから書く代わりにこれらのコントラクトを使用することで、開発時間を短縮できること。これらのコントラクトは、コミュニティによって広くレビューされ、テストされているため、セキュリティの欠陥やバグのリスクが少ない。今回はそんな巨人の肩に乗せてもらいます。ステップ2: ERC20トークンの作成srcディレクトリにMyToken.solファイルを作成し、以下のコードを追加します。pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MyToken is ERC20 { uint8 private constant _decimals = 18; constructor(uint256 initialSupply) ERC20("MyToken", "MTK") { _mint(msg.sender, initialSupply * 10 ** _decimals); } function decimals() public view virtual override returns (uint8) { return _decimals; } } OpenZeppelin ContractsのERC20コントラクトを継承することで、独自のERC20トークンを簡単に作成しました。これにより、トークンの基本的な機能(転送、残高の確認など)を安全に実装することができました。コンストラクタでは、トークンの名前、シンボル、初期供給量を設定します。ステップ3: テストの作成testディレクトリにMyToken.t.solファイルを作成し、以下のコードを追加します。pragma solidity ^0.8.0; import "forge-std/Test.sol"; import "../src/MyToken.sol"; contract MyTokenTest is Test { MyToken public token; address public deployer = address(1); function setUp() public { vm.prank(deployer); token = new MyToken(1000); } function testInitialSupply() public view { assertEq(token.totalSupply(), 1000 * 10 ** 18); assertEq(token.balanceOf(deployer), 1000 * 10 ** 18); } } このテストでは、トークンの初期供給量が正しく設定されているかを確認します。ステップ4: テストの実行以下のコマンドを実行して、テストを実行します。forge test すべてのテストがパスすれば、コントラクトが期待通りに動作していることが確認できます。ステップ5: デプロイスクリプトの作成scriptディレクトリにdeploy.s.solファイルを作成し、以下のコードを追加します。pragma solidity ^0.8.0; import "../src/MyToken.sol"; import "forge-std/Script.sol"; contract Deploy is Script { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); vm.startBroadcast(deployerPrivateKey); new MyToken(0); vm.stopBroadcast(); } } このスクリプトは、MyTokenコントラクトを0トークンの初期供給量でデプロイします。ステップ6: 環境変数の設定プロジェクトのルートディレクトリに.envファイルを作成し、以下の変数を設定します。RPC_URL=your_rpc_url PRIVATE_KEY=your_private_key ETHERSCAN_API_KEY=your_etherscan_api_key your_rpc_url、your_private_key、your_etherscan_api_keyを実際の値に置き換えてください。これらの値は、それぞれAlchemy、MetaMask、Etherscanから取得します。ステップ6-1: Alchemyアカウント取得Alchemyは、イーサリアムや他のブロックチェーンネットワークへのアクセスを提供するサービスです。以下の手順でAlchemyアカウントを作成し、RPCエンドポイントを取得します。 アプリを新規作成する際に、Chainをどれにするか聞かれるので、Sepoliaを選びましょう。 「View Key」をクリックすると、HTTP URLとWebSocket URLが表示されます。このうち、HTTP URLがyour_rpc_urlに相当します。ステップ6-2: SepoliaETH取得SepoliaETHを自分のウォレットへ送るボタンを押下後、ちょっと怖いようなカッコいいようなダークサイバーな感じの演出があります。アングラ感がちょっとあって、正直ワクワクしました。ステップ6-3: ETHERSCAN_API_KEYの取得ステップ7: デプロイの実行以下のコマンドを実行して、MyTokenコントラクトをSepoliaテストネットワークにデプロイします。forge script script/deploy.s.sol --rpc-url $RPC_URL --broadcast --verify -vvvv デプロイが成功すると、Ethescan上で見えるようになります。 私がテストネットワークにデプロイした様子はこちらです。次のやりたいことデプロイされたコントラクトとのインタラクションを試すトークンの機能メインネットワークへのデプロイ(Etheriumのメインネットのガス代高いですね……さいごにFoundryを使用して、スマートコントラクトの開発はじめの一歩、テスト、デプロイをやってみました。つまづくポイントも少なく、独自のERC20トークンを作成する方法を学びはじめることが出来ました。 新しい知識を自分で学ぶ力が弱くなっている不安があったので、細く長く楽しんでWeb3開発を学んでいこうと思います。 ## Publication Information - [hatone](https://paragraph.com/@hatone/): Publication homepage - [All Posts](https://paragraph.com/@hatone/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@hatone): Subscribe to updates - [Twitter](https://twitter.com/hatone): Follow on Twitter