iT邦幫忙

1

智慧合約開發的生命週期與測試腳本撰寫

  • 分享至 

  • xImage
  •  

寫完 Code 絕對不能直接上主網

在過去兩天中,我們順利開發了 ERC20 代幣與去中心化交易所(DEX)的核心合約。對於傳統軟體開發來說,寫完程式碼、跑起來沒報錯,可能就準備打包上線了。

但在 Web3 與智慧合約的世界裡,這是一個極度危險的想法。一旦合約部署上鏈,不僅程式碼難以竄改,裡面更可能鎖倉了價值數百萬美元的資產。只要出現一個未處理的邊界條件,駭客就能輕易掏空資金池。身為資安系的學生,我們必須建立一套嚴謹的「智慧合約生命週期」觀念,而其中最重要的一環,就是撰寫測試腳本。

智慧合約的生命週期
一個成熟且安全的 Web3 專案,從無到有通常會經歷以下五個階段:

  1. 需求分析與架構設計:確定合約需要哪些功能、變數該存在 Storage 還是 Memory、以及權限控制模型(例如誰能呼叫 mint 函數)。
  2. 本地開發:使用 Solidity 撰寫業務邏輯(如我們前兩天的實作)。
  3. 本地測試與靜態分析:撰寫單元測試、模糊測試(Fuzzing),並使用工具(如 Slither)掃描常見漏洞。(我們今天與後續 Phase 4 的重點)
  4. 專業資安稽核:交由第三方資安團隊(如 CertiK、Trail of Bits)進行人工程式碼審查。
  5. 測試網到主網部署:先在 Sepolia 等測試網運行,確認無誤後才正式部署至以太坊主網。

Foundry 測試框架:為什麼它對資安如此重要?
在 Day 9 建立環境時我們提過,Foundry 最大的優勢在於「用 Solidity 測試 Solidity」。這讓我們在寫測試腳本時,不需要在 JavaScript 與 Solidity 之間切換語境。

更強大的是,Foundry 內建了 vm(虛擬機操作物件),這是一組被稱為「作弊碼 (Cheatcodes)」的神兵利器。透過 vm,我們可以任意改變區塊時間、強制設定某個地址的餘額、甚至偽造別人的身分(msg.sender)來模擬駭客發起攻擊。

實戰:為 ERC20 代幣撰寫單元測試
讓我們回到前天寫的 MySecureToken 合約。我們要在 Foundry 專案的 test/ 資料夾下,建立一個名為 MySecureToken.t.sol 的測試檔(.t.sol 是 Foundry 測試檔的標準副檔名)。
'''
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

// 引入 Foundry 的標準測試庫
import "forge-std/Test.sol";
// 引入我們要測試的目標合約
import "../src/MySecureToken.sol";

// 測試合約必須繼承 Test
contract MySecureTokenTest is Test {
MySecureToken public token;

// 建立兩個模擬帳戶:老闆與駭客
address owner = address(0x1);
address hacker = address(0x2);

// setUp() 函數會在「每一個」測試函數執行前自動跑一次,用於初始化狀態
function setUp() public {
    // vm.prank 可以將下一筆交易的呼叫者 (msg.sender) 偽裝成指定的地址
    vm.prank(owner);
    token = new MySecureToken(); // 由 owner 部署合約
}

// 測試案例 1:Owner 應該能成功鑄造代幣
function test_MintByOwner() public {
    vm.prank(owner); // 偽裝成 owner
    token.mint(owner, 1000); 
    
    // 斷言 (Assertion):檢查 owner 的餘額是否正確增加了 1000(加上初始鑄造量)
    assertEq(token.balanceOf(owner), 1000000 * 10**18 + 1000);
}

// 測試案例 2(資安防護測試):駭客試圖呼叫 mint 應該要被拒絕 (Revert)
function test_RevertWhen_MintByHacker() public {
    vm.prank(hacker); // 偽裝成駭客
    
    // vm.expectRevert 宣告下一行程式碼「必定會發生錯誤並退回」,
    // 如果下一行沒有出錯,這個測試案例反而會判定為失敗!
    vm.expectRevert(); 
    token.mint(hacker, 1000); 
}

}
'''

執行測試與解讀報告
寫好測試腳本後,打開終端機,輸入以下指令:
'''
forge test -vv
'''
(-vv 代表詳細輸出模式,會顯示各個測試函數的日誌與變數狀態)

如果程式碼邏輯無誤,你將會看到閃亮亮的綠字報告,顯示兩個測試案例皆以極快的速度 [PASS] 成功通過!這代表我們的權限控制修飾子 onlyOwner 確實在防禦駭客越權鑄幣上發揮了作用。

有了撰寫測試腳本的能力,我們就不再只是「開發者」,而是具備了「合約攻擊者與防禦者」的視角。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言