論文作者:
Ilya Sergey1and Aquinas Hobor2
1 University College London, United Kingdomi.sergey@ucl.ac.uk
2 Yale-NUS College and School of Computing, National University of Singaporehobor@comp.nus.edu.sg
翻譯:渡鴉
「讓國內外的區塊鏈技術沒有時差」。
4、所有權和許可權
替代禁止對合約不受歡迎的幹預的另一種方法是設計一個定製的許可合約,控制不同方面允許的一組操作。
首先如果我們強制執行有限的訪問規則,則可以避免圖3 中的雙線程樣本所展示的問題,並阻止一個斷言其狀態x的任何內容。例如,通過在任何時刻表示最多一個線程可以查詢/修改其狀態。這將授予相應的線程在對象上的獨佔所有權[30] ,因此,證明從執行緒區域做出的有關對象狀態的斷言。
獨佔所有權,從傳統意義上講,是通過禁止任何幹預來獲得的,但專屬者在合約狀態中進行重大改變,Ethereum的合約中保證了獨特的所有權。例如,圖5 (左)顯示了Counter合約的更改版本,所以沒有其他方可以與它進行互動,除了它的“所有者”。所有權規則由Solidity的修飾機制執行,允許人們為功能提供自訂的動態檢查前/後置條件。在我們的樣本中,byOwner修飾符將強制執行,功能的擷取和設定將僅代表固定方 - 合約所有者引用。
圖.5. 獨佔(左)和讀/鎖定(右)合約
這是一個相當粗暴的解決方案,因為這意味著排除合約中的任何並發互動。然而,從一個角度來看,合約作為並發對象的觀點是很明顯的,請看我們的類比:帳號是線程。實際上,如圖5 所示,通過對合約施加特定所有權規則類似於通過對Thread進行明確檢查來增強其Java對等體。currentThread().getId()。
現在讓我們嘗試通過設計具有更詳細存取權限的計數器來進一步推動帳戶和線程之間的比較。我們將確保只要存在“有興趣”的帳戶(即“線程”)使其值不可變(因為內部邏輯可能依賴其不變性),則不允許其他方修改它。同樣,如果目前正好有一方擁有修改合約的唯一許可,則不得允許其他方閱讀。這種同步問題的解決方案是通過名稱讀/鎖定[6],這在並發社區中是眾所周知的。其實現需要跟蹤當前正在讀取和寫入共用對象的線程,所以在執行讀/寫操作之前,線程應該明確擷取相應的許可權,然後在完成後釋放它。
圖5的右側部分顯示了讀/寫鎖定合約實現的基本部分。兩個新領域,跟蹤目前活躍的讀者和作家。新的修飾符canRead和canWrite將被用於省略的get和set操作。最後,只要在系統中沒有活動寫入器,AcquReadRock允許其調用者擷取鎖定,通過讀取器映射註冊。
我們可以看到,以線程方式類比是十分有效。我們提出了一些解決可能的同步問題的方案,可以從並發文獻中逐字逐句地進行。所提出的解決方案的唯一缺點是它是相當整體的事實:合約現在將資料結構(即,計數器)的功能與同步原語(即,鎖)的功能相結合。我們將在第5節中討論提高實現模組性的可能途徑。
關於正式推理和驗證的注意事項。關於許可賬戶和所有狀態分離訪問的正式推理是共用記憶體並發文獻中長期研究的主題(參見例如[8] 的概述)。正式主義,如並發分離邏輯和[30]分數/計數許可權[6]提供了一種靈活的方式來定義抽象所有權規則,並驗證一個特定的實現是否忠實地遵循。例如,我們的讀/寫鎖合約可以通過Bornat等人的正式的許可權模型證明是安全的(即禁止並發修改)[6]。
5討論
5.1合約的編寫
在第4節中考慮的鎖定合約“模式”具有重大的延伸:其設計是非模組化的。也就是說,鎖定機構是由合約本身而不是由第三方資料實施的。這與軟體工程的良好做法不同,建議將同步原語(例如普通和可重新進入鎖)實現為獨立庫,可用於管理訪問用戶端特定的資源。
但是一旦鎖定邏輯被解除合約之外,關於合約行為的推理就顯得更加困難,因為為了證明其內部不變數的儲存,需要瞭解鎖定協議的屬性,例如編者的獨特性,這在合約之外。換句話說,合約的驗證不能再以孤立的方式進行,需要建立一個模型,允許對與其他嚴格指定的合約互動的合約進行推理。解除合約邏輯的想法不只是我們這樣認為的,而且在合約開發中是至關重要的。例如,同樣的想法被提倡作為通過引入和額外的間接層次來實施Ethereum可升級合約的一種方式[11]。擁有由任何一方可以援引的另一個合約的“合約工廠”構成了與證明高階並發對象的安全屬性(即,與其他對象一起作用)類似的驗證挑戰[19]。
使用並發邏輯的組合推理和相互依賴和高階並發對象驗證的思想在過去十年中一直個熱門課題[12,33,34, 37]。而大多數都集中在協議的概念上,在同時更新的情況下,作為對象行為的抽象介面,同時隱藏低級實現細節(即實際代碼)。我們相信,通過利用我們的類比,我們將能夠開發一種用於這種多合約互動的模組化驗證的方法。
5.2活性
隨著鎖定和獨佔訪問的引入,出現了另一個並發相關問題:推理合約實現的進展和活動屬性。例如,不難想象一種情況,其中在圖5 的樣本中註冊為“讀者”的特定帳戶可能永遠不會釋放讀卡機鎖,從而阻止其他人能夠更改合約未來的狀況。在這種情況下的活躍意味著最終會有好的事情發生,這意味著任何一方都有適當的激勵來解除鎖定。在並發詞彙中,這樣的假設可以被重新表述為系統調度器的公平性,使得可以重用現有的證明方法來進行單個和多合約執行中的進展[25] 和終止[18]的模組化推理。
6、相關工作
智能合約的正式推理是一個新興和令人興奮的,適用於描述合約行為的抽象行為,是值得研究的課題。在本節中,我們將我們的觀察結果與正式化和驗證合約屬性的現有結果聯絡起來,概述將從我們的並發類比中受益的領域。
6.1驗證合約實施
自從DAO bug [9] 以來,Ethereum社區一直專註於防止類似錯誤,藉助通用工具進行程式驗證。
目前,Solidity所寫的合約可以用Hoare樣式的前置/後置條件注釋,並轉換為OCaml代碼[32],所以他們可以使用Why3工具進行驗證,該工具使用自動化來排除產生的驗證條件[16] 。這種方法對於驗證Solidity程式的基本安全屬性是有效,例如總是位於特定數組索引邊界內的特定變數,以及保留一般合約不變數(通常以一個形式表示,如果在uint值變數的值上的線性方程式)方法邊界和執行外部合約調用之前–這也正是DAO合約違反的。
Bhargavan等人最近翻譯了Solidity子集(無迴圈和遞迴)[5] 到F-a程式設計語言和驗證架構,基於依賴類型[35] 。他們還提供了從EVM位元組碼到F程式的翻譯。這兩種方法可以使用F作為驗證合約屬性的統一工具,例如不變數儲存和不存在未處理的異常,通過F對索引Hoaremonad的支援而被編碼為效果[36] 。Pettersson和Edstr [31]採用了一種類似的指定合約行為和依賴類型的方法,他們實現了一種基於效果的小型合約DSL作為淺埋嵌入到Idris[7] 中,其可執行代碼提取到Serpent[14] 一種Python風格的合約語言。
Hirai最近將Lem[28] 中的EthereumVirtual Maine [22] 的完整規範正式提交給了Isabelle/ HOL驗證助手,對於編譯為EVM位元組碼的合約的機械化驗證,具有許多安全屬性包括對可變狀態的斷言以及潛在的可重新進入的缺失。與以前的方法不同,Hirai的正式化並沒有提供構造和組合證明的句法方式(例如通過Hoare式程式邏輯),所有關於合約行為的推理都是從低級執行語義[38]中進行的。
與這些主要側重於低層級安全性質和不變性儲存的工作相比,我們的觀察提示了更高層次的形式意義,用於捕獲合約行為的屬性及其與外界的溝通模式。特別地,我們考慮將抽象狀態轉換系統(STS)[29]作為適當的形式來進行通訊,使用諸如TLA+[24]等已建立的工具集來跟蹤合約執行和活動屬性。為了將這樣的抽象表示與低級合約代碼串連起來,必須證明進階和低級表示之間,即在STS和代碼之間的細化[3] 。從某種意義上說,找到一個合適的合約不變數,並通過Why3或F證明它驗證一個狀態轉換系統之間的細化,使得唯一的狀態是不變數描述的狀態,以及保留它的一個實現。然而,我們預計將需要更複雜的STS才能推理具有搶佔並發性的合約。
6.2推動全球合約
[27].Luu等人發現,由於幹擾現象,一些合約容易出現無意或者對抗性濫用的觀點。他們將問題類似於我們在第3 節中的計數器樣本中所表現,即交易順序依賴性(TOD),根據我們的並發類比可以將其概括為無限制幹擾的問題。Luu等人提出的TOD問題的解決方案需要改變Ethereum事務的語義,提供一個與圖4中的testAndSet類似的原語。雖然這種方法的優點是沒有需要修改已經部署的合約(只有與用戶端代碼互動的代碼需要更改),才需要所有相關的使用者升級他們的用戶端應用程式,以便考慮更改。本質上,Luu等人的解決方案針對非常具體的併發模式:通過添加塊支援的讀 - 修改 - 寫入原語來加強由原子寄存器提供的同步。意識到問題的本質,暗示我們的類比,可能會提出替代合約解決方案,例如工程化鎖定代理合約。然而,這種方法的缺點在於,在設計和部署合約的時刻需要預見這種行為。也就是說,這樣一種對這種行為進行建模的能力讓我們相信我們的比喻能夠實現的。
7、結論
我們相信,我們在智能合約和並發對象之間的比較可以提供新的視角,刺激研究,並允許有效地重用現有的結果,工具以及瞭解,調試和驗證分布式分類帳中複雜的合約行為的見解。作為比喻,我們不應該逐字地採取行動:一方面,確實存在並發問題,在合約規劃中似乎幾乎不可觀察到; 另一方面,智能合約執行者也應該謹慎對待並發領域沒有直接對應的觀念,例如氣體執行和資金管理。
總而言之,我們留給讀者幾個猜測,靈感來自我們的觀察,但既沒有解決也不反對:
- 非垃圾收集語言中的常見並發挑戰是跟蹤堆位置的唯一性,這可以被後期回收和重用 - 被稱為ABA問題[10] 。由於缺乏應有的謹慎,ABA問題可能導致違反對象狀態完整性。我們可以想象在多合約環境中有類似的情況嗎。
- 繼續比較,如果將區塊鏈看作共用狀態,那麼挖掘協議定義了調度的優先順序。我們可以利用有效並發線程管理的洞察力來分析和改進現有的分布式分類帳。
- 線性化[21] (又名原子性)是指定無鎖並發對象的進階行為的正確性的標準概念。對於具有多種交易操作的複合合約(例如BlockKing),什麼是等同的事實上的一致性概念。
原文: https://zhuanlan.zhihu.com/p/29354702