o_1de6acq85gpnfvjgpdrsr17hlp.jpg

在 ETH Cape Town 黑客馬拉松期間,我們使用功能強大的,新的以太坊操作碼 —— CREATE2,製作了一個合約錢包的快速概念證明。較之 CREATE 操作碼,CTEATE2 操作碼可以在使用以太坊合約來生成新合約時更好地控制新合約的地址,當你想要反事實地(counter-factually)部署並使用一個自定義權限的合約時,這是非常有用的。

Wisp 合約的目標是演示一種生成穩定合約錢包地址的技術,該地址可與其他用戶共享,也可以實現代幣和以太幣轉賬功能,同時還可以在不保留任何鏈上合約錢包代碼的情況下控制鏈上資產(例如 ENS 域名)。

Wisp 地址的優點包括:首先,所有發給這種 Wisp 地址的交易都只需要確定的 21, 000 gas,但是更重要的是,這意味着可以訪問代幣、資金以及其他鏈上資產的合約錢包不能被攻擊,因爲它的代碼實際上不在鏈上。

如果合約錢包中出現錯誤,可於再次使用前在客戶端進行更新,此期間所有加密資產都是安全的。

使用靜態引導程序_initcode 可以_獲取 CREATE2 runtime 合約字節碼從而生成可複用的合約地址。

initcode 是什麼?

在深入瞭解這種技術之前,先得理解以太坊合約的部署過程。

合約的部署過程使用了一段被叫做 initcode 的代碼,它只是一個普通的以太坊程序,正常執行將返回部署合約實際所用的合約字節碼。雖然有點抽象,但是它可以支撐功能非常強大的部署系統。

你可以想象一下,JavaScript 中 「Hello Word」 的 initcode 可能就是這樣:

這個程序運行時將返回一個「Hello World」 程序。這樣做可以實現額外的部署時配置,例如:

需要注意的非常重要的一點是:被部署的不是 initcode,而是 initcode 的運行結果。

CREATE vs CREATE2

儘管大多數以太坊開發者都使用了 CREATE 操作碼(來部署鏈上合約),但是他們可能並沒有意識到這件事。Solidity 所生成的字節碼實際上是 initcode,它使用 CREATE 來執行構造函數中的對應操作,隨後返回合約除構造函數外的其他部分。實際部署上鍊的代碼不包含構造函數代碼。

爲確定部署上鍊的合約地址, CREATE 使用的標準參數包括:

  1. 發送賬戶 (它本身可能也是一個合約) 2. 發送賬戶的 當前交易序號 (也可以是一個合約當前的 nonce)
    因此,任意兩個不同的發送者將生成不同的合約地址,而來自同一個賬戶的任意兩筆不同交易也將生成不同的合約地址。

爲確定部署上鍊的合約地址,新的 CREATE2 使用:

  1. 發送賬戶 (同樣,它本身可能也是一個合約) 2. 合約 initcode (執行產生合約字節碼) 3. 由開發人員設定的 自定義數(salt)
    因此,CREATE2 與 CREATE 一樣,不同的發送者將生成不同的合約地址。而 initcode 相同 但是自定義數不同時將生成不同的合約地址;而 initcode 不同時(通常意味着不同合約),也將生成不同的合約地址。

CREATE2 的另一個值得注意的(有用的)是,由於其對計算合約地址的參數多了一點控制, 如果一個合約自毀了,那麼新合約未來可以再次部署到這個地址上 。但是,如果已經有非自毀合約部署到這個地址上了,那麼 CREATE2 不能在這個地址上再次部署一個合約。

綜合一下

由於控制發送者以及自定義數很容易,因此實現 Wisp 合約目標唯一要做的事情就是繞過 CREATE2 的第二個參數;最終允許兩個不同的合約在不同的時期被部署在同一個地址上

但是,initcode 只是一個用於確定所部署合約的程序。這一特點可以用各種有趣的方法加以利用。

每個 Wisp 合約的入口都是一個啓用和管理所有 CREATE2 調用的跳板合約(SpringboardContract),因此跳板合約將一直是發送者。至於 salt,因爲使用 msg.sender 的哈希值作爲自定義數,因此同一個賬戶的任意兩個調用將始終指向同一個 Wisp 合約。

剩下的是一個普通的(靜態)引導程序 initcode。initcode 要在新合約中運行,但是此時新合約還未創建;這意味着 msg.sender 實際上是跳板合約。因此,跳板合約會將所需的合約字節碼保存在自己的存儲空間中,並提供一個名爲 getPendingBytecode() 的公共方法,引導程序的(僞)代碼可以簡單地表示成如下形式:

也就是說,大體上,我們針對源碼刪除了一些小細節,同時又添加了一些額外的內容,總之,該技術運行良好,感興趣的開發者已經可以使用了!

Wisp 合約生存週期

這是一個用於幫助說明 WIsp 合約生存週期的簡單圖表及摘要:

1. 一筆交易的目的地址是跳板合約(請注意,合約也可以調用跳板合約,在這種情況下,該合約地址將擁有 Wisp 合約)

2. CREATE2 被用於初始化 Wisp 合約

3. 在初始化期間,Wisp 合約回調跳板合約以獲取所需的 runtime 字節碼,該字節碼隨後由 initcode 返回。

4. Wisp 合約的 execute() 方法被調用時,運行所有所需的操作

5. Wisp 合約的 die() 方法被調用時,銷燬該 Wisp 合約,因此未來可在該地址重新創建合約。

注意: 所有 ETH 都將返還給 Wisp 合約所有者,因爲 ETH 在計劃會自毀的合約中是不安全的。

跳板合約代碼(Solidity)

一個簡單的例子:這是被部署到 Ropsten 上的,在黑客馬拉松期間使用的代碼。就像大多黑客馬拉松的代碼那樣,它有點簡陋,因此不要將其用於實際應用。

該版本同時支持外部所有賬戶(EOA)和 ENS 域名。如果調用 ENS 域名版本,則 ENS 域名所有者控制 Wisp 合約,該版本允許通過修改 ENS 解析的地址來轉移 Wisp 所有者(以及它控制的所有資產)。

在黑客馬拉松期間使用的引導程序非常簡單,並且是手寫代碼,因此可以使用部署腳本中的幾行 JavaScript 代碼輕鬆組裝。但是由於該代碼穩健性不夠好,需要檢查返回狀態。

Wisp 示例

GitHub repo 中有幾個 Wisp 合約的例子,但是基本上所有的操作都可以放在 execute() 函數中。

出於黑客馬拉松的目的,任何轉發給 Wisp 的餘額在 CREATE2 部分都作爲捐贈提供,因此使用 this.balance 而不是 msg.value。正如上面的插圖展示的那樣,可以轉發給至 execute() 函數 。下面是一些可在 Wisp 合約中完成的工作的例子:

結論

CREATE2 操作碼非常棒並且功能多樣。目前我們仍在進行相關探索,我們嘗試着在我們的多簽名合約錢包中使用它創建資產商店。

我們的目標是創造一個可靠並且靈活的資產商店,其可以存儲大量的 CryptoKitties,ENS 域名以及各種代幣,同時可以輕鬆實現資產在多簽名實例之間的轉移。由於 Wisp 合約可以針對其控制的資產執行任意操作,因此它甚至可以使用資產被訪問之時還不存在的功能。

可以說它基本上就是一個花哨的委託調用(Delegate Call)。

來源:以太坊愛好者

玩幣族:最早的幣圈媒體。www.wanbizu.com

文章來源:http://www.gongxiangcj.com/posts/20277 原文作者:Wisps 特別申明:區塊鏈行業 ICO 項目魚龍混雜,投資風險極高;各種數字貨幣真假難辨,需用戶謹慎投資。blockvalue.com 只負責分享信息,不構成任何投資建議,用戶一切投資行爲與本站無關。

來源鏈接:www.blockvalue.com