📜 [專欄新文章] 可升級合約介紹 - 鑽石合約(EIP-2535 Diamond standard)
✍️ Kimi Wu
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
Photo by Evie S. on Unsplash
前言
可升級合約簡單來說是透過 proxy contract(代理合約)來達成,藉由代理合約去呼叫欲執行的合約,若要升級,則把代理合約中的指向的地址換為新的合約地址即可。而執行的方式則是透過 delegateCall,但 delegateCall 不會更動目標合約的狀態。所以要怎麼處理變數,就是一門學問了。
舉例來說,contract B 有個變數 uint256 x,初始值為 0, 而 function setX(uint256),可以改變 x 的值。proxy contract A 使用 delegatecall 呼叫 contract B 的 setX(10),交易結束後,contract B中的 x 依然還是 0。
OpenZeppelin 提出了三種實作方式,可以做到可升級合約,細節可參考 Proxy Patterns,而最終的實作選用了 Unstructured Storage的這個方式,這種方式對於開發較友善,開發時不需特別處理 state variables(不過升級時就需要特別注意了)。而這篇主要是介紹 Diamond standard,OpenZeppelin 的可升級合約就不多做介紹。
USDC V2 : Upgrading a multi-billion dollar ERC-20 token 詳細地介紹代理合約跟變數儲存之間的關係,不了解升級合約的原理,建議先看看。
鑽石合約
名詞介紹
diamond:合約本體,是一個代理合約,無商業邏輯
facet:延伸的合約(實際商業邏輯實作的合約)
loupe:也是一個 facet,負責查詢的功能。可查詢此 diamond所提供的 facet與facet所提供的函式
diamondCut:一組函式,用來管理(增加/取代/減少)此 diamond合約所支援的功能
Loupe
直接來看 loupe的介面,從宣告就能很清楚暸解 diamond合約的實作方式,loupe宣告了一個結構 Facet,Facet結構包含一個地址及 function selector 陣列,所以我們只需要記錄一個 Facet陣列就可以得知這個 diamond 合約有多少個延伸合約及所支援的功能(loupe只定義結構,而實際變數是存在diamon合約中的)。也就是 diamond合約中只記錄延伸合約的地址及其支援的 function selectors,及少數 diamond合約的管理邏輯,並無商業邏輯,因此可以外掛非常非常多的合約上去(就像一個Hub),也就可以突破一個合約只有24K的限制。
// A loupe is a small magnifying glass used to look at diamonds.interface IDiamondLoupe { struct Facet { address facetAddress; bytes4[] functionSelectors; } function facets() external view returns (Facet[] memory facets_); function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_); function facetAddresses() external view returns (address[] memory facetAddresses_); function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);}
DiamondCut
至於 facet在 diamond合約上的註冊或是修改,就由 diamondCut負責,從以下程式碼可以清楚瞭解其功能(EIP中有規範,每次改變都需要發送DiamondCut事件)
interface IDiamondCut { enum FacetCutAction {Add, Replace, Remove} // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);}
Diamond合約
接下來就是最核心的部分 — diamond本體合約。以下是官方的範例,方法上跟 OpenZeppelin 一樣使用 fallback 函式跟 delegateCall 。
呼叫合約所不支援的函式,就會去執行 fallback 函式,fallback 函式中再透過 delegateCall 呼叫 facet 合約相對應的函式
fallback() external payable { address facet = selectorTofacet[msg.sig]; require(facet != address(0)); // Execute external function from facet using delegatecall and return any value. assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 {revert(0, returndatasize())} default {return (0, returndatasize())} }}
主要的差異在於變數的處理,OpenZepplin 是針對單一合約設計的代理合約(也就是每個合約都有自己的代理合約),所以無法處理單一代理合約儲存多個合約的變數(state variables)的狀況(後有圖例)。先由官方的範例程式來了解是怎麼處理變數的
在官方的範例中,都是以更改合約 owner 為例子
首先看到 DimaondStorage這個結構,結構中的前面三個變數都是在維持 diamond合約的運作(同上面loupe的範例),最後一個變數 contractOwner就是我們商業邏輯中所需的變數。
接著看到 function diamondStorage(),取變數的方式就跟OpenZeppelin 儲存特定變數方式一樣(EIP-1967),是把變數存到一個遠方不會跟其他變數碰撞到的位置,在這裡就是從 DIMOND_STORAGE_POSITION 這個 storage slot 讀取。
在實作上就可以有 LibDiamond1 ,宣告DIMOND_STORAGE_POSITION1=keccak256("diamond.standard.diamond.storage1") ,負責處理另一組的變數。藉由這種方式讓每個 facet合約有屬於自己合約的變數, facet合約間就不會互相影響。而最下方的 setContractOwner 是實際使用的範例。
library LibDiamond {
bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
struct FacetAddressAndSelectorPosition { address facetAddress; uint16 selectorPosition; }
struct DiamondStorage { mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition; bytes4[] selectors; mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; }
function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } }
function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; ds.contractOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); }
每個 library 處理了一組或多組變數的存取, facet 合約透過 library 對變數做操作。也就是把變數存在diamond主體合約,延伸的 facet合約只處理邏輯,是透過 library 去操作變數。
下面圖中清楚地解釋了 facet合約,function selectors 與變數之間的關係,從最左上這邊有個 facets 的 map,紀錄了哪個 selector 在哪個合約中,例如func1, func2是 FacetA的函式。左下角宣告了變數,每組變數的存取如同上述 library 的方式處理。
https://eips.ethereum.org/EIPS/eip-2535#diagrams
在 diamond的設計中,每個 facet合約都是獨立的,因此可以重複使用(跟library 的概念一樣)
https://eips.ethereum.org/EIPS/eip-2535#diagrams
小結
diamond合約使用不同的設計來達成合約的可升級性,藉由這種Hub方式可隨時擴充/移除功能,讓合約不再受限於24KB的限制,此外充分的模組化,讓每次升級的範圍可以很小。最後,因為跟library一樣只處理邏輯,並無狀態儲存,所以可以重複被不同的diamond合約所使用。
雖然又不少好處,也是有些缺點。首先,術語名詞太多,facet, diamondCut, loupe等等(其實還有好幾個,不過沒有介紹到那些部分,所以沒有寫出來)。開發上不直覺,把變數跟邏輯拆開,若要再加上合約之間的繼承關係,容易搞混,不易維護。最後,gas的花費,在函式的讀取、呼叫,變數的存取、傳遞都會有不少的額外支出。Trail of Bits 專欄中有點出更多的缺陷 Good idea, bad design: How the Diamond standard falls short,不過作者也有反擊 Addressing Josselin Feist’s Concern’s of EIP-2535 Diamond Standard,有興趣的讀者可以自行看看、比較。
為了模組化及彈性,diamond合約在設計上有點太複雜(over engineering),會造成可讀性越差(這點也是Vyper誕生的原因之一),而可讀性越差就越容易產生bug、也越不容易抓到bug,而在defi專案中,一個小小的bug通常代表著大筆金額的損失 😱😱😱。
雖然如此,筆者還是覺得很酷,有些設計的思維仍然可以使用在自己的專案
ref:
EIP 2535
Diamond 實作
Addressing Josselin Feist’s Concern’s of EIP-2535 Diamond Standard
OpenZeppelin upgradeable contract
可升級合約介紹 - 鑽石合約(EIP-2535 Diamond standard) was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
同時也有1部Youtube影片,追蹤數超過2萬的網紅sandeechan,也在其Youtube影片中提到,「給一直為婚姻平權努力的人們, 讓所有不敢說出名字的愛, 終於能夠勇敢表白。」-by 公主 打字文本來源【The love that dare not speak its name - by Oscar Wilde】 http://www.famous-trials.com/wilde/342-w...
「evie怎麼念」的推薦目錄:
evie怎麼念 在 思逸 SEER 荒人巫思手抄 Facebook 的最佳貼文
【#心得回饋分享】2021塔羅函批心得首發!
#感謝同學熱情分享 #來函照登敬請欣賞
「嗨~來分享我的2021塔羅函批心得!
等等,也太快了!2021不是才剛要開始?
哈哈~因為我注意到整體大方向是延續今年的走向繼續下去的啦!像是工作、財運,基於對自己的了解,心中大致上有點想法,看了函批後覺得更篤定了。投機的事情真的就不要做(立馬打消再次買比特幣的念頭😂)仔細看的話,函批也點出了某些可以改善的個人習慣,對於規劃事情一直很隨性的人也該考慮一下好好訂計畫,以免事情到底怎麼發生的都搞不清楚。
函批看著看著,覺得2021對我來說還不是那種時來運轉的年份,財運甚至有點淒慘(好多錢幣逆位😂),住在好山好水好空氣偏遠觀光區的房租哄抬很高,每年光這部分就一定要破財。但是無法用金錢衡量的隱形資產之豐富讓我驚訝,這部分人生中我時常有感覺,但這次這麼直白地都是好牌,好像說明上天特別眷顧我的某些部分。
長年以來我一直覺得即使自己的財運不是很旺,貴人運卻無敵強,真是宇宙的恩賜。看到2021適合拓展人際關係,貴人運旅遊運都非常好,心中真是千言萬語難以言喻啊!就算過得戰戰兢兢,事後回過頭來總是發現天無絕人之路,我還是安然無恙的,心中非常感謝一切人事物。
進入2021年後也會持續觀察,再來繼續分享心得。」
.
.
|補充說明|
2021年度所有函批報告及護身符均已寄送完畢!
如果您沒趕上,請期待今年十月初的 #2022年度塔羅函批報告 預約報名喔!
.
.
*看看2021塔羅函批服務是甚麼,如何預約,做個參考吧:https://wp.me/p3UNVs-35n
.
.
#奔狼小編愛分享
.
.
Photo by Evie S. on Unsplash
evie怎麼念 在 Facebook 的最佳貼文
做自己情感的好管家,你的情感需要什麼照顧及滋潤,只要你好好聆聽,這個忠實的好管家肯定願意會告訴你。
但前提是你和這個內在管家(內在照顧者)有好的合作關係。如果這個內在的照顧者是失功能的,或是你的內在小孩和內在照顧者之間是衝突和對立的,都會讓你的內在自我發生當機,處於失功能狀態。
我們的內在有許多不同的面向和功能,也可說是不同的能量和狀態,這些不同而多元的面向,整合成一個完整的自體(Self),也就是一個整體。
然而,當沒有一個健康和成熟的內在自我,那麼這些不同的能量和狀態,通常處於渙散、分裂或是混亂,讓自我也欲振乏力,因為早被自己內在的戰爭耗損了。
這種內耗,往往是人,無法有能量發展自體的關鍵,學習力和應變能力都會下降,也無法發展客觀及具有現實感的處事待人態度,包括對待自己,也很難發展真正關懷和照顧自己的能力。
榮格曾經說,往外張望的人在作夢,向內審查的人才是清醒的。向內整合及疏通我們各個矛盾及衝突,甚至陰影之處,我們才有機會活得清醒,真實地了解自己、辨識出自己,也完整自己。
若是因為外在的變化或一個訊息就慌張錯亂,就無意識的直接反應,無論是討好或躲藏,終究是沒有覺察自我的意識,也不是依從及尊重自己的抉擇,那樣就難免有許多懊悔和憾事發生。
人若要安穩的在人前不懼展現自我,又不憂於在人散後失去關係,就是他無論在什麼情境中,他都與自己有一安穩且具有信任的關係。
這樣的自我關係要怎麼實現呢?
那需要時時保持與自己的連結(統整),不會將自己拋於無意識之中,莫名其妙自己的言行舉止,也不明白自己的起心動念。
人願意自我負責也願意面對自己的選擇後果,人才能行得正,坐得穩。
一個人時常對自己不明就裡,常覺得自己是胡亂反應、無意識行事,那他必然對自己的言行舉止難以認同,也難以堅定自我,更不用談到支持自己和肯定自己了。
他也必時常的質疑自己,一下想這樣,一下又反對這樣,像是跟自己一直在摔角,鬥來鬥去,卻沒有一致的力道和目標知道怎麼前進。
一個人和自己的關係混亂及充滿矛盾和衝突,也必然會投射到和其他人的關係上。若是採取對自己冷漠隔離,對他人也會以冷漠隔離對待。
畢竟我們能與自己接觸到的地方,也才能和別人接觸到。
所以,在想建立任何實質交流且有意義的關係之前,與自己的交流和樂意探索自己,才能讓我們的內在豐厚起來,不僅有自我的思想,還有自我的情感。自我豐富了,關係之間也才能豐富。
#先豐富自我內在的情感,才可能豐富關係之間的感情
#做自己情感的好管家
#關愛自己
《療癒孤寂》
30堂課學會接住自己,建立內在安全感,成為能與他人連結的完整自我
https://www.books.com.tw/products/0010876551?sloc=main_mb
#繪者 Evie Hsu
evie怎麼念 在 sandeechan Youtube 的最讚貼文
「給一直為婚姻平權努力的人們, 讓所有不敢說出名字的愛, 終於能夠勇敢表白。」-by 公主
打字文本來源【The love that dare not speak its name - by Oscar Wilde】
http://www.famous-trials.com/wilde/342-wildetestimony (英文參考)
http://opinion.cw.com.tw/blog/profile/187/article/928 (中文參考)
發佈日期:2017年8月29日
陳珊妮 2017 全新專輯【戰神卡爾迪亞】
9月12日 開放預購
10月3日 正式發行
【6502】極限定巡迴演唱會
10/7台北LEGACY . 10/21台中LEGACY
購票連結:
台北:https://www.indievox.com/legacy/event-post/19922
台中:https://www.indievox.com/legacytc/event-post/19923
更多詳情
https://www.facebook.com/SandeeChan.musicface/
導演:談宗藩、吳麗萱
視覺設計:吳麗萱
後期:QFX
監製/腳本:陳珊妮
感謝英文歌詞翻譯:Kewpie Wu
台北工作人員名單
製片/美術:陳蘋琪
攝影:談宗藩
打字手:陳蘋琪
特別感謝:陳奕仁
倫敦工作人員名單:
製片 / 美術:吳麗萱
攝影:Alexis Tillirides (電腦桌面背景)
舉牌的人們和他們的語言(按出現順序)
People with different languages (in order of appearance):
Suzanne Harb (English); Belinda Hewitt (Maori); Doros Polydorou (Greek); Lisa Solovieva (French);
Siddharth Nadkarny (Konkani); Dima Zogheib (Arabic); Nireesha Prakash (Hindi);
Natcha Saereesithipitak (Thai); Tshuà Hō-hi (Tâi-uân-uē);
Iñigo Ruiz-Apilánez (Spanish); Rienkje Attoh (Dutch); Sunghwan Kim (Korean); Evie Kim (Blank);
Kewpie Li Hsuan Wu (Traditional Chinese);
特別感謝:
DayinFlying
===================
詞/曲/編曲 陳珊妮
吉他 徐研培
【□□□□□//亂碼】歌詞:
上一篇文章被刪除後
所有叛逆的字元
決定不再讓空白 沈默
我們比空氣更自由
比時間還富有
沒有文字 無需言語 就能溝通
========================
陳珊妮走過的市中心 --安溥
這是一個常用閒著的樣子忙忙碌碌,也許庸庸碌碌的行業。
再高的才情,還是有要拿來想出一句鼓勵別人意淫什麼的傳播語的時候 ; 再深的一顆觀察世事的心,逢年過節,藉著訪問還是要開放眾人參觀一下傳說中的作者世界。
跟珊妮用很短的時間一起工作完”Dear you and the boy”單曲後,在珊妮後來下張專輯“如同悲傷被下載了兩次”前,我們聊天時聊起行銷和這些事情。我想外界從來沒有感覺到,陳珊妮是一個多麼努力而嚴苛在鍛鍊自己的人。但,是的,珊妮是我遇過最努力的人之一,而她極為厭惡與努力一詞掛勾。
她是非常古典的一個人。所謂古典,是指她永遠無法用樂迷的方式去接觸音樂哪怕體會自己,以至於在作品或舞台表現上留下任何“努力”的痕跡。看得出努力,在這個時代被濫用成一種顯學,意指“要讓人看見我有多努力”,或是“搞得讓觀眾只看得出作品很努力”; 這對我認識的陳珊妮來說是大忌:就算樂迷想買這種帳,卻怎麼可以這麼不負責任。
於是我用當歌手與她開始重疊的過去十年,看著她走了整十年感覺異常寂寞的音樂路。別誤會... 她不覺得寂寞,是我好寂寞。
“如同悲傷被下載了兩次”的歌詞是那年我覺得樂壇最精彩的詞作,它寫出了這世代的完整現象,網路的,世代的,新式的青春男女,即使再新型的時代生活依然籠罩在萬年曆般的,得到幸福失去戀情有人介入我來成全的運作下,陳珊妮完成了一幅暈染加工筆,景深寬闊近物精勾的鳥瞰圖。單曲推出後,我見樂壇迴響少有對詞作的討論也只當成一種情調覺得可惜,當年就問她,為什麼不換個專輯的宣傳模式。但聊著聊著,我往自己提出的問題裡塞頭進去看,華語樂壇的行銷模式換湯不換藥的市場思考中,當年也的確容不下她的樂風需要能有更多選擇的選項:就像是在寸土寸金的城市裡,討論空出一塊市中心的地成為森林公園或是能做奇異的大型裝置作品空間,不會是可不可行的問題,是多少人看到這些好處的問題。
這也反映在珊妮的行事風格上罷。討論事情或工作,她多半從無時間多加點發語詞或狀聲詞,她直言不諱常讓人覺得當刻不知如何回應。這是因為珊妮講的東西有問題,還是這城市的人們將工作當成交際,將交際的時光拿來安置了太沈重的東西了呢,比如說自我認同。而對於我認識多年的陳珊妮來說,也許真的簡單太多了:她始終頑固地認為看到做錯的事情若是不直接講,還拿來旁敲側擊地試探或請託,反而是污辱對方的工作和看低了對方的智商。事實上我最常被她念,我太邋遢動作太慢腦子時間感太差生活習慣太兩光當時怎麼會喜歡這個女生那個男生,但這可能是我最喜歡跟珊妮相處的部分,也是很多聽眾還沒發現的幽默感,關於珊妮的嚴厲與姿態,其實是一種皇后的溫柔。
為什麼說起這些呢... 我看著陳珊妮多年來的倔強,這一年,如同每一年私下工作著的深耕淺言,她要推出新作品了。珊妮給我聽了她的新歌,讓我寫個推薦。跟音樂人們聊,可以說得出那麼多珊妮編曲中層次奇異而多元的技巧,可以講很多修辭上風格與世界觀的延伸,但對樂迷,我也許只希望更多人用自己的感官去看她的演出,用自己的性情去碰撞她的性情,用自己的世界去接觸她的世界形成的音樂。
珊妮形象上的稜角是多麼可貴。如同我一直體會著的,我每一個音樂人和創作者好友他們各自的性情和姿態就是這世界還有奇山峻嶺,激海深流的那些地方。
而在此寫稿的夜裡,我走出家門散步,把自己散在這條乾淨而整齊的市中心大街上。這城市如同人們對進步的期盼,容不下,不承認,也於是已沒有危險與未知的樣貌了。我們也是,下架了市面上不受歡迎的人格特質,我們先把自己四捨五入並整除,用共識和認得出的得體跟彼此相處。如同珊妮讓我推薦的新歌,它叫亂碼,散步時我聽著它,浮現起陳珊妮走在這城市中心的樣子,她這樣一個毫不肯妥協,依然只願意在錄音室裡用建築般的方式解構再打造音樂的女人,也許讓眼前街景都變得尷尬 ; 尷尬於她就是不肯融入其中,但想起來,更倔強的就是她每天都堅持繼續走過人們的市中心啊… 這讓我寂寞,卻不再孤單。
謝謝珊妮,妳那皇后的嚴厲冷冽與因此才有的,言語毫無瑣碎的溫柔。
我總是多說了。但也許就是這樣,我們就是來開始對調角色,這個年代讓我說說這些,而你/妳,你/妳來聽陳珊妮的音樂。

evie怎麼念 在 Evie 白白魚 的推薦與評價
Evie 白白魚- 「いいね!」4066件· 206人が話題にしています- 哈咯我是Evie白白魚:D YouTube小白一名这个面子书专业每个星期都会上传5支独家小影片! ... <看更多>
evie怎麼念 在 這些英文名字你能唸對幾個(超難唸)? Common English Names ... 的推薦與評價
這些英文名字你能唸對幾個(超難唸)? Common English Names Asians Can't Pronounce? ; https://goo.gl/YGbHmr 北門窩泊旅: ; https://goo.gl/iguzRO 請訂閱 ... ... <看更多>