深入了解智能合約的最小代理“EIP-1167”

2021-11-30 15:11:33

概述

在一开始,代理合約很難去掌握,在這篇文章中,我們將分析最小代理標准或“EIP-1167”,並創建一個代碼示例。

在开始之前,不要混淆可升級代理和最小代理,這是非常重要的,它們是完全不同的。在這篇文章中,我們只討論最小代理。

最小代理標准早在2018年就正式發布了,這個標准的主要思想是盡可能便宜地部署基礎合約的副本。讓我進一步展开:

最好的例子是一個多重籤名錢包。讓我們假設用戶創建了一個非常簡單的多重籤名錢包,它可以接收資金、發送資金和設置n個所有者的數量。當然,為了發送資金,用戶需要達到一定的法定人數(n≥m)。一旦智能合約准備好了,有兩種主要的方法可以讓它准備好投入生產。第一個是部署合約,使所有用戶直接交互,這意味着所有的資金將存儲在該合約,為了跟蹤誰擁有什么,需要創建一個映射(地址 => uint) 公共余額+ 一些修飾符。這種方法的問題在於,用戶將所有內容集中在一個地方,最重要的是,用戶打开了額外攻擊向量的可能性。換句話說,用戶使合約更加復雜了。我們不想這樣做,我們想把安全作為我們的首要任務。想到的第二種方法是讓用戶部署合約,為了做到這一點,用戶需要編譯合約,將字節碼放在前端,並讓用戶部署合約。這種方法的問題是效率非常低,而且gas價格昂貴。想象一下,如果合約變得太大太復雜,部署成本將非常高,再加上我們正在用大量存儲轟炸鏈。解決這個問題的方法是實現最小代理標准。

最小代理所做的是創建一個廉價的克隆(我們稱它為廉價,因為它的部署成本非常低),它具有與實現合約完全相同的邏輯,但具有自己的存儲狀態。這是通過低級別的委托調用實現的。


      深入了解智能合約的最小代理“EIP-1167”

為了實施這個標准,我們需要:

  • 執行合約:有時被稱為基礎合約、核心合約、主合約等。重要的是,執行合約是所有邏輯所在的地方。

  • 代理工廠或克隆工廠:顧名思義,克隆工廠合約將是我們的工廠。這意味着用戶將調用工廠的一個函數,而工廠將克隆一份實施合同的精確副本,但擁有自己的存儲空間。這意味着每個克隆都有相同的邏輯,但存儲狀態獨立。

  • 代理:如前所述,代理合約是實施合約的克隆,但具有獨特的存儲。

現在我們有了一個大致的了解,讓我們創建一個示例來鞏固我們的知識。我們將在Remix中做這個例子,使它更簡單。

合約將會非常簡單,這裏的目的是理解標准。

為此我們需要以下合約:

  • 實現:這是我們的邏輯所在的地方,我們將其稱為Implementation.sol。

  • CloneFactory:這將是我們的工廠,我們將有一個clone() 函數,用戶將觸發該函數,工廠將輸出代理的地址。工廠的名稱將是CloneFactory.sol。

  • 代理:與代理無關,代理將是CloneFactory.sol 中的clone() 函數的輸出。可以有盡可能多的不同代理,這就是整個目的,以創建許多Implementation.sol的克隆。

這是它看起來的樣子:


      深入了解智能合約的最小代理“EIP-1167”

需要記住的一個非常重要的方面是,克隆不知道構造函數,因此我們使用initialize()函數“替換構造函數”,而不是使用構造函數來分配重要變量。我們只需要確保initialize()函數只被調用一次,這樣人們就不能篡改合約,類似於構造函數的工作原理。為了做到這一點,我們通常使用openZeppelin的Initializabl。對於本例,我們不打算使用任何第三方合約,只是為了更清楚地說明。

讓我們從Implementation.sol开始。合約唯一要做的就是擁有一個帶有setter函數和修飾符的uint公共變量,限制只有所有者才能更改變量的訪問權限。


      深入了解智能合約的最小代理“EIP-1167”

讓我們來分析一下:

uint public x→我們將在setter函數中更改的無符號整數(默認為0)。

bool public isBase→這個布爾值將確保實現合約永遠不會被初始化。如果在構造函數中看到,我們將:isBase設置為true,並且initialize()函數的第一個require語句是require(isBase ==false)。這保證了實現合約只用於邏輯,沒有人可以篡改。請記住,代理或克隆合約不知道構造函數,因此isBase將被設置為其默認值false。

address public owner→合約所有者(外部擁有的账戶)。所有者默認為address(0)。在Solidity中,如果不分配地址類型,則默認值為address(0)。

modifier onlyOwner()→希望用戶不需要解釋這個,但基本上這是說只有所有者可以調用這個函數。

initialize(address _owner)→一旦創建代理克隆,需要立即調用initialize函數。這就像我們的構造函數,意味着如果之前有人調用這個函數,它將控制合約。如我們所見,它有一個參數(address _owner)。該參數將在CloneFactory 中提供。這裏有兩個重要的考慮:

  • 用戶需要確保initialize函數只被調用一次。我們這樣做,是通過檢查所有者是否是地址(0)。一旦分配了所有者,並且我們試圖再次調用該函數,交易將恢復。強烈建議在Initializable合約中使用這個體系結構+ OpenZppelin的initializer()修飾符。這確保了函數只能被調用一次。

  • 使實現合約不可用:通過在構造函數中賦值isBase=true,並在initialize()函數中要求isBase== false,我們可以確保沒有人可以篡改合約。該合約的唯一目的是充當邏輯合約,如果有人試圖調用基礎合約的初始化函數,它將立即恢復。

一旦我們准備好了Implementation.sol,讓我們創建CloneFactory.sol。為此,我們將使用 OpenZeppelin 的 Clone 庫中的 clone() 函數。


      深入了解智能合約的最小代理“EIP-1167”

讓我們來分析一下:

interface Implementation→initialize()是我們在Implementation.sol中需要的唯一函數。一旦創建了克隆合約,我們將立即調用它。

address public implementation→implementation .sol的地址。

mapping(address => address[]) public allClone →這只是一個跟蹤所有已部署克隆的映射,第一個地址是 msg.sender 或克隆的所有者。

clon(address implementation)→這個函數來自Open Zeppelin。在較高的層次上,我們提供實現地址(implementation .sol),它返回該地址的一個實例,換句話說,它返回一個完全相同的implementation .sol的克隆。

clone()→這是用戶將要調用的函數。一旦有人調用這個函數,第一件事就是創建一個新的克隆並將它保存在地址 sameChild 下。這個地址將持有與Implementation.sol相同的邏輯,但有自己的存儲狀態。正如我們在clone()的第三行中看到的,我們正在調用initialize函數:


      深入了解智能合約的最小代理“EIP-1167”


      深入了解智能合約的最小代理“EIP-1167”

這是至關重要的,這就是為什么我們要立即調用它。這將使clone()函數的調用者成為克隆合約的所有者。一旦做了,就沒有回頭路了。

用戶可以克隆任意數量的合約,每個合約都有自己的存儲空間。任何調用_clone()函數的人都將是唯一能夠訪問更改“x”的帳戶。

結論

當我們需要為一個合約創建多個副本時,最小代理標准非常有效,每個副本都有自己的存儲狀態。最常見的用例是:Multi-Sig-Wallet、托管账戶、某種類型的流動性池等。

作為提醒,無論何時執行此標准,都要特別注意以下事項:

  • 實現合約中的initialize()函數只能被調用一次。

  • 需要盡快觸發實現合約中的initialize()函數。

  • 使實現合約不可用。

Source:https://medium.com/coinmonks/diving-into-smart-contracts-minimal-proxy-eip-1167-3c4e7f1a41b8

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。

推薦文章

btc日內再次下跌 短线應當如何處理?

盡管以太坊現貨ETF獲批是個好消息,但市場反應卻不如預期。在消息公布後,以太坊價格出現了小幅下跌,...

加密蓮
134 3個月前

7月23日、BTC(合約)ETH(合約)行情分析及操作策略

昨日收益還是不錯的,日內給出的現價空單分別止盈我們目標點位,恭喜跟上的朋友喫肉。時間一晃到月底了,...

倪老師
134 3個月前

幣圈院士:血與淚的教訓!交易者為何總是撞死在同一棵樹上?

幣圈院士談。交易市場中的幾種“死法” 在幣圈市場鱗次櫛比的海洋,風起雲湧,時常讓人感到驚手不及。在...

幣圈院士
139 3個月前

7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC

7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC一個引...

168超神
131 3個月前

悅盈:比特幣68000的空完美落地反彈繼續看跌 以太坊破前高看回撤

一個人的自律中,藏着無限的可能性,你自律的程度,決定着你人生的高度。 人生沒有近路可走,但你走的每...

我是周悅盈
111 3個月前

btc完美盈利 晚間波動較大注意

昨日btc空單完美給到,最大化走出一千七百點空間~ btc: 日內开盤下跌繼續測試66000一线,...

加密蓮
121 3個月前