# Foundry 筆記 ## 🧔‍♂️ 資料來源 [Getting Started With Forge ](https://w.mirror.xyz/mOUlpgkWA178HNUW7xR20TdbGRV6dMid7uChqxf9Z58) ## 🧔‍♂️ 首先需要先安裝 Foundry (mac) ``....需要補齊,找一天來重做一次`` - homebrew - brew install libusb (若是有跳出 dyld: Library not loaded) - 安裝 Foundry ``` curl -L https://foundry.paradigm.xyz | bash source /Users/beard/.zshrc # 重啟終端機 foundryup ``` ## 🧔‍♂️ 建立專案 ``` forge init [project name] cd [project name] ``` <br/><br/> ## 🧔‍♂️ 開始進行測試吧! ### 前提 需要注意幾個事項: - 測試檔案放置於 /test 中 - 檔案命名會為 xxxx.t.sol - 需要測試的 function 需要以 test 當成前綴詞命名 ![](https://i.imgur.com/b6sD1rf.png) <br/><br/> ### 印出文字/資訊 測試中可以利用 emit log 來印出相關的資訊,也需要依照格式呼叫相對應的 function ![](https://i.imgur.com/IF2yK1C.png) <br/><br/> ### 開始測試 進行測試,可以在後續的參數增加 [-v ~ -vvvvv] ``` forge script script/Counter.s.sol [-v][-vv][-vvv][-vvvv][-vvvvv] ``` - -v : 預設模式,一般來說的錯誤顯示 - -vv : 印出 log - -vvv : 印出 [錯誤]測試的追蹤 - -vvvv : 印出測試的狀態追蹤,若是有[錯誤]測試會顯示相關設定 - -vvvvv : 印出所有測試的相關設定 <br/><br/> ### 模糊測試 (Fuzzing) Foundry 測試時,遇到需要傳入的資訊,他會自動依照格式塞入隨機資訊進行測試,並且計算 gas 花費的資訊,以及平均使用值 ![](https://i.imgur.com/N28n82F.png) - runs:代表此 function 測試運作 256 次 - μ:平均 gas 花費 27387 - ~:gas 中位數為 28320 <br/><br/> ### 強制重新 Compile 若是 Foundry 發現您沒有修改調整 Code, 他則會直接利用原本的Compile file直接在運作,而不會重新 Compile。 若是在修改無進行測試的相關程式後,需要重新Compile,則要使用參數 --fouce ``` forge test --force ``` <br/><br/> ### 作弊碼 (Cheat Codes) 作弊碼可以達到超乎想像的操作,偽裝錢包地址....可查看 [forge](https://github.com/foundry-rs/foundry/tree/master/forge) - 模擬轉到mainnet (利用到 infura ) <code>vm.createSelectFork("https://mainnet.infura.io/v3/34578ae15.....83");</code> - 轉成錢包(*address*)的擁有者 <code>vm.prank(*address*);</code> - 直接給 address(0x1) 10,000顆eth <code>vm.deal(address(0x1), 10000 ether);</code> <br/><br/> ### 安裝相依套件 若是需要使用 [ERC721Psi](https://github.com/estarriolvetch/ERC721Psi),可以利用以下指令進行安裝: ``` forge install estarriolvetch/ERC721Psi ``` - 名稱 (estarriolvetch/ERC721Psi) 為 githob repo name <br/><br/> ### 重新映射(Remappings) 部分合約是使用類似 NPM 的引入方式(@開頭),這時候則需要設定檔案對應,否則會取得不到。 以下利用 Openzeppelin ERC20 為案例 1. 【套件安裝】首先進行套件安裝: ``` forge install OpenZeppelin/openzeppelin-contracts ``` 2. 【建立合約程式】在 src 資料夾中,建立 Mytoken.sol,並建立最簡單的 ERC20 範例合約(如下) ``` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract Mytoken is ERC20 { constructor(uint256 initialSupply) ERC20("MyToken", "MT") { _mint(msg.sender, initialSupply); } } ``` 3. 【建立測試檔案】在 test 資料夾中,建立 Mytoken.t.sol,並寫入測試的程式。 ``` // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import "forge-std/Test.sol"; import "../src/Mytoken.sol"; contract MytokenTest is Test { Mytoken public mytoken; function setUp() public { mytoken = new Mytoken(30000); } function testlog() public { console.log(mytoken.totalSupply()); } } ``` 4. 【!進行編譯異常】若是此時直接進行測試編譯,會發現錯誤 ``` forge test --force ``` 會顯示出以下錯誤 - 找不到匯入的套件檔案: ![](https://i.imgur.com/LSTgSEy.png) 5. 此時需要進行映射(檔案對應),需要在 forge 專案目錄下建立:remappings.txt,內容新增如下,將 @openzeppelin 對應到 lib路徑中 ``` @openzeppelin/=lib/openzeppelin-contracts/ ``` 檔案位置參考如下: ![](https://i.imgur.com/Ha78Hse.png) ## 🧔‍♂️ 進階用法 ### 匹配標誌 (Matching flag) 如果只想測試部分的測試,可以利用參數: -m *string* 進行,會找出名稱中有 *string* 的function 進行測試。 例如。運行 ```forge test -vvvv -m Revert``` 並且函數名稱中帶有 ```"Revert"```的測試都會運行! ### 快照 (snapshot) 可以測試查看gas的耗費狀況 -- *目前版本看來已經內建顯示 gas 耗費* ### 分岔模式(forking mode) 可以模擬真實鏈上的數據進行測試, 只要輸入 ``forge test -f <uri>``. (URI 可以從 Alchemy 或是 Infura的服務中取得),這樣可以模擬出真正鏈上的回傳跟處理狀況的回應,並獲得實時網絡狀態的響應。這可以使用於難以模擬的合約或狀態進行測試。 ###### tags: 開發/閱讀筆記