Dapp-Development

一份通用契約,還是為每個實例生成一份新契約?

  • December 4, 2020

優點與缺點是什麼,或者執行一個通用契約或為每個實例生成一個新契約。假設我提供了一份契約,以便人們可以創建自己的眾籌。每次使用合約創建新的眾籌時,最好使用“new”關鍵字生成一個具有自己資料結構的新合約。還是讓所有眾籌實例保持一個總體結構更實際?

在我的應用程序中,不同實例之間不會有互動。

根據您的經驗,在做出此類決定時應該注意什麼。

我不相信產生新實例是保持簡單的理想方法。啟動一個眾籌實例肯定會變得更加昂貴,這在汽油價格高時可能是有害的。

單例不必很複雜。您可以考慮使用定義類型、Crowdsale 和原始函式的庫來分離關注點。這可以在旨在處理所有這些問題的契約中為您提供不錯的可讀性。

單例的另一個優點是可升級邏輯的可能性,這在許多實例中會變得有些麻煩。

這裡有一個小想法可以幫助您考慮將庫用於資料結構和簡單方法:

pragma solidity 0.7.4;

// SPDX-License-Identifier: Unlicensed

library CrowdsaleLib {
   
   struct Crowdsale { // the "using" statement refers to this Type
       address owner;
       // this would contain the funders, targets, etc.
   }
   
   modifier onlyOwner(Crowdsale storage self) {
       require(msg.sender == self.owner, "You do not own this crowdsale");
       _;
   }
   
   function close(Crowdsale storage self) internal onlyOwner(self) {
       // implement the rules
       // do something to self, which is the complete instance state
   }
   
}

contract Crowdsalw {
   
   using CrowdsaleLib for CrowdsaleLib.Crowdsale;
   
   mapping(bytes32 => CrowdsaleLib.Crowdsale) crowdsales;
   
   function close(bytes32 crowdsaleId) public {
       CrowdsaleLib.Crowdsale storage c = crowdsales[crowdsaleId];
       c.close();
   }
}

希望能幫助到你。

讓事情盡可能簡單

大多數智能合約都依賴於使事情盡可能簡單。

本著這種精神,建議為每個客戶端實例化新合約,因為它減少了合約中所需的程式碼/邏輯,並將攻擊者的表面限制在所述合約上。

而且你也不會把所有的雞蛋(ETH / Tokens / Value)都放在一個籃子裡,如果確實發生的話,這會減緩合約的流失。

在談論“眾籌”時,您需要不同的合約來儲存稱為“代幣跟踪器”的“erc20 代幣”,所以您已經在這樣做了。

您還需要記住,適合一份合約的邏輯必須適合 8 百萬 gas 限制,對於這樣的合約來說,這個限制可能非常小。

現實世界的例子:

也許我們是偏執狂,但我們一直在開發的 Crowd Funding DAO 確實將這一點發揮到了極致,為每個單獨的眾籌基金的每個捐款地址創建了個人資金庫

這是一個硬編碼 2 個輸出和 2 個控制器地址的智能合約:

請參閱此 github 連結以獲取原始碼

輸出:

  1. 一 - Vault Owner(發送 eth 的錢包地址)
  2. 二 - Team Multi 簽名地址

控制器:

  1. 一 - Funding Manager 智能合約,它可以請求資金,然後將其發送到“團隊”地址,(只有當合約中的所有邏輯每次都按預期工作時才會發生)
  2. 二 - 保險庫所有者 - 可以要求他們的資金返還,以防他們進行“現金返還”

如果您將多個項目/地址堆疊到一個實例中,這樣的事情就不會真正可靠甚至安全。

這些金庫確實要花很多錢,但要確保除了團隊投資者之外,沒有其他人可以從中獲得“價值”。

希望這可以幫助。

引用自:https://ethereum.stackexchange.com/questions/61730