GitHub リポジトリ:- https://github.com/PradhumnaPancholi/Figbot こんにちは、みなさん!少し前に、スマート コントラクトを開発および監査するための素晴らしいツールがある について学習していました。そして、私はその経験をとても気に入っていましたが、それが秘密の開発段階にあることをすぐに知りました.これは、カジュアル/個人ユーザーが、サポートと更新についてメンテナーに依存できないことを意味します。 Dapp Tools それから私は に出くわしました。組み込みのシンボリック実行以外に、Dapp Tools が提供するすべての機能を備えています (Trail of Bits で e を使用しているため、これは問題ではありません)。これは監査に関連しているため、想像力を働かせてもスマート コントラクトの開発を妨げるものではありません。 ファウンドリー Manticor Foundry で少し働いた後、私はその経験を楽しんで、それを他の人と共有したいと思いました.ということで、この記事。 この記事では、Foundry の利点、インストール プロセス、NFT の開発 (誰もが興味を持っているため)、コントラクトのテスト、 での展開について説明します。 Figment Datahub Foundry は、Rust で記述された Ethereum アプリケーション開発用の超高速でポータブルなモジュラー ツールキットです。 Foundry は、次の 3 つのコンポーネントで構成されています。 Ethereum テスト フレームワーク (Truffle、Hardhat、Dapptools など)。 Forge: EVM スマート コントラクトとやり取りし、トランザクションを送信し、チェーン データを取得するためのスイス アーミー ナイフ。 キャスト: ローカル イーサリアム ノード、Ganache、Hardhat Network に類似 Anvil: 今日の焦点は しかし、今後数週間でカーストとアンビルに関する詳細な記事を投稿する予定です. フォージです。 ファウンドリーを選ぶ理由: Truffle、Hardhat、Brownie など、多くのスマート コントラクト開発ツールがあります。しかし、そもそも Dapp Tools を調べた主な理由の 1 つは、ネイティブの Solidity テストでした。 Hardhat や Brownie などのフレームワークを切り替える場合、スマート コントラクトを作成することは難しくありません。これらはプラグインを備えた素晴らしいツールですが、テストを実行するには JavaScript/TypeScript と Python に精通している必要があります。 Foundry を使用すると、Solidity でネイティブにテストを作成できます。これにより、新しい開発者のオンボーディングにかかる時間が大幅に節約され、プロセスがスムーズになります。人々がスマート コントラクト開発への道を進むのを支援してきた私の経験から、若手開発者が DAO/コミュニティで維持されているプロジェクトに関与するための最善かつ最も効率的な方法は、テストを作成し、コード ベース自体について学ぶことであることがわかりました。 が、Bankless で Finance を開発する際に同じアプローチを使用したと述べたことがあることを覚えています。 Scupy Trooples Alchemix それに加えて、組み込みのファジング、チート コード、Cast、および Anvil により、スマート コントラクトをテストするための堅実なスイートになります。これらのコンポーネントについては、近日中に詳細な記事を掲載する予定です。 【静的アナライザーの組み込みが簡単】 それでは、NFT プロジェクトを作成してみましょう。 インストール: Mac または Linux を使用している場合は、次の 2 つのコマンドを実行するだけです。 curl -L https://foundry.paradigm.xyz | bash foundryup を実行する前に、必ずターミナルを閉じてください。 foundryup そして出来上がり!これで完了です。 Windows の場合、Rust をインストールしてから: cargo install --git https://github.com/foundry-rs/foundry --locked プロジェクトのセットアップ: この記事では、Figbots という単純な NFT プロジェクトを作成します。 まず、「Figbots」というディレクトリを作成します。ディレクトリに入ったら を実行します。このコマンドは、 が初期化されたファウンドリ プロジェクトを作成します。 forge init git フォルダ構造を簡単に見てみましょう。 src、lib、および test という 3 つのプライマリ フォルダーがあります。コントラクトは に記述し、テストは に記述します。lib には、インストールしたすべてのライブラリ ( など) が含まれます。それに加えて、これらのフレームワークを使用した場合は、 や と同じように、すべての構成を含む を取得します。もう 1 つの便利な機能は、Github アクションを記述できる .github です。チームで作業するときのテストに非常に役立ちます。 src test lib hardhat.config.js brownie-config.yaml foundry.toml 構築を始めましょう! Figbot と呼ばれる、供給、コスト (鋳造用)、および引き出しが制限された単純な NFT を作成します。このアプローチにより、さまざまなテストのエッジをカバーできます。まず、 と の名前をそれぞれ と に変更します。さて、Openzeppelin なしではスマート コントラクトを作成できませんね。 Contract.sol test/Contract.t.sol Figbot.sol Figbot.t.sol Foundry でのライブラリのインストールは、Hardhat や Brownie とは少し異なります。 npm または pip パッケージはありません。 Foundry のソース (GitHub リポジトリ) からライブラリを直接インストールします。 forge install Openzeppelin/openzeppelin-contracts これで、ERC721URIStorage.sol 拡張機能をインポートして NFT を作成できます。すべてが問題ないことを確認するために、コマンド を実行すると、プロジェクトがコンパイルされます。何か問題がある場合、コンパイラはあなたに怒鳴ります。それ以外の場合、コンパイルは成功します。 forge build 依存関係の管理 他のパッケージ マネージャーと同様に、Forge では 、および を使用して依存関係を管理できます。 forge install <lib>, forge remove <lib> forge update <lib> NFT契約を完了しましょう: Openzeppelin からの 3 つの契約を使用します。カウンター、ERC721URIStorage、Ownable。 を使用して を IPFS にアップロードします。 Ownable コントラクトを使用して展開アドレス を設定し、 修飾子にアクセスして、所有者のみが資金を引き出すことができるようにします。 NFT コントラクトをシンプルに保つためのトークン ID と をサポートする 。 Pinata アセット owner onlyOwner ERC721URIStorage Counters 状態変数の設定: を 100 に MAX_SUPPLY から 0.69 イーサ COST から CID へ、ピニャータから受け取ります TOKEN_URI トークン ID にカウンターを使用する: using Counters for Counters.Counter; Counters.Counter private tokenIds; ERC721 コンストラクター: constructor() ERC721(“Figbot”, “FBT”) {} ミント機能: が より大きいかどうかを確認します msg.value COST が 以上かどうかを確認します tokenIds.current() MAX_SUPPLY と を実行する _safeMint _setTokenURI 引き出し機能: function withdrawFunds() external onlyOwner { uint256 balance = address(this).balance; require(balance > 0, "No ether left to withdraw"); (bool success, ) = (msg.sender).call{value: balance}(""); require(success, "Withdrawal Failed"); emit Withdraw(msg.sender, balance); } TotalSupply 関数: function totalSupply() public view returns (uint256) { return _tokenIds.current(); } 契約のテスト: ご存知のように、スマート コントラクトをテストすることは非常に重要です。このセクションでは、 をしっかりと理解し、ネイティブの堅牢性でテストを書くことに慣れるために、いくつかのテストを書いていきます。テスト シナリオに合わせてアカウントの状態を管理するために、3 つの を使用します (大好きです!)。 forge test Foundry チート コード 次のシナリオでテストを行います。 最大供給量 成功したミント 残高不足によるミント失敗 撤回(所有者による) チートコード スマート コントラクトに複雑なロジックを含めることができるためです。そして、それらは状態、呼び出しに使用されたアカウント、時間などに応じて異なる動作をすることが期待されています。そのようなシナリオに対処するために、チートコードを使用してブロックチェーンの状態を管理できます。 Foundry の ライブラリの一部である インスタンスを使用して、これらのチートコードを使用できます。 Test vm テストでは 3 つのチートコードを使用します。 : が呼び出されるまで、後続のすべての呼び出しに対して を設定します。 startPrank stopPrank msg.sender : stopPrank によって開始されたアクティブないたずらを停止し、 と を が呼び出される前の値にリセットします。 startPrank msg.sender tx.origin startPrank : アドレス提供アドレスの残高を、指定された残高に設定します。 deal 設定 Foundry には組み込みのテスト ライブラリが付属しています。まず、このテスト ライブラリ、コントラクト (テストしたいもの) をインポートし、テストを定義し、変数を設定し、 関数を設定します。 setUp pragma solidity ^0.8.13; import"forge-std/Test.sol"; import "../src/Figbot.sol"; contract FigbotTest is Test { Figbot figbot; address owner = address(0x1223); address alice = address(0x1889); address bob = address(0x1778); function setUp() public { vm.startPrank(owner); figbot = new Figbot(); vm.stopPrank(); } } 状態変数については、タイプ の変数 を作成します。これは、私がユーザー アカウントを定義するのが好きな場所でもあります。 Foundry では、構文 を使用してアドレスを記述できます。これには任意の 4 文字の英数字を使用できます。 owner、Alice、bob という名前のアカウントをそれぞれ作成しました。 Figbot figbot address(0x1243) 次に 関数です。これは、Foundry でテストを作成するための要件です。これは、すべての展開とその性質のことを行う場所です。 を使用して、ユーザーを「所有者」に切り替えました。デフォルトでは、Foundry は特定のアドレスを使用してテスト コントラクトをデプロイします。しかし、これにより、 のような特別な権限を持つ関数をテストすることが難しくなります。したがって、この展開の「所有者」アカウントに切り替えます。 setUp startPrank withdrawFunds MaxSupply をテストします。 Foundry の規則を学ぶための簡単なアサーション テストから始めます。慣例により、すべてのテスト関数には接頭辞 が必要です。 を使用して、2 つの値が等しいかどうかをテストします。 test assertEq コントラクトで説明したように、 関数を呼び出して、結果の値が 100 かどうかをテストします。そして、テストを実行するために を使用します。 MaxSupply forge test そして出来上がり!!!テストに合格しました。 テストミント: 簡単なテストを書いたので、チートコードを使って書いてみましょう。私たちの契約の主な機能。 ユーザー アカウントを Alice に切り替えます。 Alice の残高を 1 イーサに設定します ミント関数を呼び出す Alice が 1 かどうかを確認する balanceOf TestFail ミント: 失敗すると予想されるテストに使用される別のテスト関数があります。このようなテストに使用されるプレフィックスは です。呼び出し元の資金が不十分な場合に 関数が元に戻るかどうかをテストします。 testFail mint ユーザー アカウントを Bob に切り替えます ボブの残高を 0.5 イーサに設定します (NFT は 0.69 イーサです) mint 関数を呼び出します (十分な資金がないため、元に戻されます) Bob が 1 かどうかを確認する balanceOf mint が通過しなかったため、Bob の残高は 1 になりません。したがって、それは失敗します。これは、まさに を使用する目的です。したがって、 を実行すると、パスします。 testFail forge test テスト撤回: ここでは、「所有者」だけが正常に実行できる機能をテストします。このテストでは、次のことを行います。 ユーザーをボブに切り替える ボブの口座に 1 イーサの残高を与える Bob のアカウントから Figbot を作成します (これにより、コントラクトに 0.69 イーサの残高が与えられます) ユーザーを所有者アカウントに切り替えます 機能を実行します(成功した場合、所有者の残高は0.69イーサになります) withdrawFunds 確認するために、所有者の残高が 0.69 イーサであるかどうかをアサートします 展開: コントラクトをテストしたので、それをデプロイします。ウォレットへの秘密鍵 (いくつかの Rinkeby テスト ETH を含む) と RPC URL が必要です。 RPC URL には を使用します。 Figment DataHu Figment DataHub は、Web 3 で開発するためのインフラストラクチャを提供してくれます。Ethereum、Celo、Solana、Terra などの複数のチェーンをサポートしています。 Figment DataHub のセットアップ: でアカウントを作成します。 Figment DataHub 「新しいアプリを作成」をクリックします。 アプリ名を入力します。 環境は「ステージング」を選択。 提供されたオプションから「イーサリアム」を選択します。 「プロトコル」タブから、Rinkeby の RPC URL を取得できます。 ターミナルを開いて、これらの両方を環境変数として入力します。 export FIG_RINKEBY_URL=<Your RPC endpoint> export PVT_KEY=<Your wallets private key> 環境変数を取得したら、すべてデプロイする準備が整いました forge create Figbot --rpc-url=$FIG_RINKEBY_URL --private-key=$PVT_KEY 検証: これでほぼ完了です。これまでのところ、Foundry と Figment DataHub を使用してスマート コントラクトを作成、テスト、デプロイしました。しかし、まだ完全に終わったわけではありません。現在、契約内容を確認中です。そのためには、 API キーを設定する必要があります。 Etherscan export ETHERSCAN_API=<Your Etherscan API Key> これで、スマート コントラクトを検証できます。 forge verify-contract --chain-id <Chain-Id> --num-of-optimizations 200 --compiler-version <Compiler Version> src/<Contract File>:<Contract> $ETHERSCAN_API おめでとう!これで、Foundry を使用してスマート コントラクトを作成、テスト、デプロイできるようになりました。この記事を楽しんで学んでいただければ幸いです。これを書くのは本当に楽しかったです。それについてのあなたの考えを私に知らせてください。