由於有很多公開的優秀在線資源,因此,我不會解釋所有的基本概念,而是嘗試解釋一些值得分享的有趣事物(即安全性和gas優化技巧),並在嘗試解決一些練習時回顧一下我的思考過程。
提示
三種轉移方式:send、transfer 和 call
盡管可以使用這 3 種方法來轉移以太坊,但它們具有值得了解的關鍵區別。send()和transfer()曾經被推薦使用,因為它們會將 gas 支出限製在 2300 gwei。利用這個數量的gas,人們可以進行一些次要的 fallback 操作,比如發出事件,甚至更新存儲,但這還不足以重入合約。然而,這從來都不是避免重入攻擊的好方法,因為 gas 成本會隨著協議更新而變化(即伊斯坦布爾分叉增加了SLOD操作碼的 gas 成本)。
因此,建議使用低級功能call(),默認轉發所有可用的gas。然後,你可以使用 Reentrancy Guard 或 Checks-Effects-Interactions 模式 來保護你的函數。
索引事件參數與非索引(常規)
具有索引參數的事件更容易檢索,因為它們在世界狀態(在logsBloom中)中被特別索引。因此,它們比只有常規參數的事件稍微貴一些。
這個解釋可以通過這個簡單的 Foundry 示例來確認:
索引事件和非索引事件之間的 gas 費比較。
註意:日誌由主題(最多 4 個)和數據組成。其中一個主題為事件簽名保留,因此你最多可以有 3 個索引參數。
在以太坊黃皮書中,可以斷言每個主題花費 375 gwei,數據中的每個字節花費 8gwei。
以太坊黃皮書中定義的事件 gas 成本
任務:創建一個基本的眾籌平臺
搭建一個符合以下要求的簡單眾籌平臺的主幹:
- 任何人都可以創建一個活動(Campaign)來為其項目獲取資金。
- 每個活動至少必須擁有:
名字
所有者
活動類型(初創公司或慈善機構)。
籌資目標
時間限製,不能超過 60 天
- 上述所有屬性都必須在活動創建時定義,並且無法被更新。
- 在達到給定活動的時間限製之前,任何人都可以通過發送以太坊來資助它。達到時限後,便無法再接收資金。
- 活動的所有者只有在達到時限後才能提取所籌集的以太坊。
- 所有者提取資金後,應將活動標記為完全資助 FullyFunded(如果籌得資金 >= 資金目標)或部分資助 PartiallyFunded(如果籌得資金 < 資金目標)。
- 所有者必須能夠取消活動。如果發生這種情況,該活動將無法再收到以太坊。
- 實施所有相關的事件。
解決方案設計
當有一個想法時,你首先需要弄清楚的是解決方案應該具有的架構設計。在我看來,最合理的做法是為每個活動製定一個獨立的合約,這樣所有者就可以直接與之互動並擁有完全的所有權。因此,我決定創建一個工廠合約 CampaignFactory 和一個名為 Campaign 的活動合約。
工廠合約的運作模式
鑒於上述的架構,我首先創建了 Campaign 合約,確保它符合所有給定的要求。
你可以在此 GitHub gist中查看完整的腳本https://gist.github.com/0xRusowsky/5b583aeff7e387fa00652a9b079c34ad
首先,我們需要定義變量以及可能需要的任何 枚舉 enum 或 結構 structs。
註意 owner 必須是一個 payable address,因為它將具有提取資金的能力。
一旦我們設置了所有變量,我們就可以創建合約構造函數。在這種情況下,構造函數將使用 require() 函數來確保截止日期小於 60 天。
由於在 solidity 中的時間戳是 unix 格式(從1970 年1 月1 日開始以表計算)中表示的,因此構造函數_deadline中使用的輸入變量將具有相對範圍(require 語句狀態_deadline <= 3600*24*60)。盡管如此,全局變量deadline將具有絕對引用,因此我們可以將它與任何給定的時間戳進行比較。
由於 owner 是 a payable address,我們必須更改 _owner 類型以使其符合要求。
在對構建的合約進行編碼之後,我創建了相關的事件和一些修改器,這些修改器將有助於我們在活動功能中實現所需的驗證。
事件和修飾符的實現。
最後,我們需要實現合約功能。在這種情況下,我們只需要 4 個函數:fallback(), receive(), withdrawFunds(), cancelCampaign().
為了 fallback() 和 receive() 能夠從其他合約以及 EOA 中接收以太幣,我們需要使它們payable。最重要的是,我們還將添加liveCampaign修改器以確保在活動結束後不再收到捐款。
另一個值得一提的話題是如何處理提款。正如之前在提示部分中所解釋的,我們在這裏使用低級函數call()。
執行競選合約功能。
至此,活動合約完成。現在,我們只需要再創建一個眾籌工廠合約。
在這種情況下,工廠合約將只有一個函數,該函數將在調用時部署活動合約的新實例。最重要的是,我們還將添加一些映射以更好地處理已部署的活動。這些映射將按所有者(使用數組)跟蹤已部署的活動合約,以及每個人已部署的活動數量(以導航數組)。
執行眾籌工廠合約。
原文鏈接:https://journal0xrusowsky.substack.com/p/first-interactions-with-solidity?utm_source=twitter&sd=pf