一文探討如何在智能合約裡實現鏈上數據的讀取權限?
責編| Carol
責編| Carol
責編| Carol
責編| Carol
經常有人問到一個問題:“怎麼在合約裡實現鏈上數據的讀取權限?”
這樣的需求背後,是開發者想把一些數據上鍊,讓智能合約管理和運算,以達成業務上的共識,但又不希望數據公開可見,避免鏈上其他未授權參與者讀取,導致信息洩露。
最直觀的實現思路,就是在合約代碼裡寫一段過濾邏輯,判斷調用者滿足某些條件(如在白名單裡)才允許返回數據,否則拒絕。
我們設定一個案例:有一個積分聯盟鏈,鏈上參與者有Alice、Bob、Carl、Dave等多方以及他們的家人,每個人的積分餘額希望設定只有自己和家人可見,其他參與者不可見。
客戶端通過區塊鏈的應用級接口,發送請求到某個節點,調用智能合約的get方法查Bob的積分,智能合約寫了權限控制邏輯,拒絕越權訪問。
因為智能合約在每個節點上的運行邏輯是一致的,因此無論請求發往哪個節點,結果都一樣。這看起來貌似沒啥問題,但實際是否也是如此?
這裡先說結論:這是個“治標不治本”的做法,並不能確保數據不洩露。
現在開始我們要用“多中心、去信任”的思維重新去審視這個案例。
我們先分析下:鏈上數據是怎麼存儲?在什麼情況下會被洩露呢?
區塊鍊網絡節點分佈在不同參與者的環境裡,出於區塊鏈的數據一致性特性,每個節點都持有一份完整的數據副本。無論這個數據庫是LevelDB/RocksDB這樣的文件型數據庫,還是Mysql這樣的關係型數據庫,數據都會落到每個節點的數據庫實例裡。
也就是說Bob的積分餘額,在所有的節點硬盤上都存了一份,在MySQL數據庫工具裡看,大概這個樣子:
如果鏈上(小概率地)存在某個有點兒區塊鏈技術經驗的參與者,暗戳戳地怀揣“惡意”(也就是俗稱的拜占庭玩家),他可以用工具打開本地的數據庫,直接查詢Bob的餘額。這樣,用合約去防止數據洩露的控制邏輯就會完全被繞過。就這麼簡單。
另外,區塊鏈的數據不僅與合約相關,還和交易記錄密切相關。
在發送交易的時候,交易參數會包含一部分或全部數據(如Alice給Bob轉賬100),交易會打包進區塊,最終也寫入節點數據庫裡。
對區塊和交易數據的查詢一般不會用合約邏輯實現,於是,僅僅在合約裡寫過濾邏輯並無法防止這些數據的讀取。拜占庭玩家可以在本地數據庫裡遍歷區塊數據,獲取交易歷史明細,從頭到尾回放交易流水,得知現在Bob的餘額是300。
和和和“一致性”和,只要明文數據在鏈上廣播,別人就有無數種方法去獲取。無論是在合約層還是底層代碼,幾乎所有的讀控制邏輯都像一捅就破,像窗戶紙一捅就破,像
馬其諾防線
一樣形同虛設。
看到這裡,有人可能會問:讀數據如此不設防,那區塊鏈上的“寫”權限還有意義嗎?回答是:有的。
回到積分這個例子,我們設定Alice是積分管理員,她才能發起轉移積分的交易,然後Bob也只接受Alice給自己的積分。轉移積分的交易需要經過全網共識,所有共識節點會檢查合約裡寫的規則,不符合就拒絕簽名,越權交易無法得到共識,則數據不會被修改。這時即使有少量的拜占庭節點,無論在本地節點怎麼折騰,也篡改不了全網數據。
“寫”交易追求共識,所以客戶端發交易(sendTransaction或sendRawTransaction)時,要打上數字簽名,區塊鏈系統驗證簽名,確認是哪個外部賬戶發過來的交易,可以進行嚴格地校驗和準確地追溯。
“讀”操作更強調共享
,讀數據的操作其實並不經過共識流程,在自己的節點翻翻數據就行了。通常區塊鏈系統在讀接口(call)並不用嚴格填寫發送者,也無需打上數字簽名,所以,在合約的讀方法裡判斷外部賬戶,其實是無效的。
綜合以上種種分析,可以得出結論:在鏈上實現讀控制並不是簡單的事情。
如果對讀控制邏輯考慮不足,那麼效果將是:你在自己的節點上讀一下數據來測試驗證,表像看起來OK,你以為歲月靜好,卻不知道在一個拜占庭玩家那裡,數據已經被翻得底朝天了。
考慮到多方協作中的去信任化,追求數據共享、公開、透明的取向,一般來說,如果是關鍵的、不能洩露的敏感數據,一定要慎重上鍊,能上鍊的,一定是大家說好可以分享的“最大公約數”。
事實上很多區塊鏈系統裡的交易和余額等狀態都是全網可見的,所謂的匿名性或隱私性,只是用公私鑰和地址體系代替了明文賬戶,這個級別的“匿名”,在業務模型複雜且強調全面隱私的金融、政務等領域並不適用。那麼我們還有什麼方法,在兼顧共享、透明、開放的同時,適當地控制數據可見性呢?第一個思路是
與鏈外治理結合
,約定責權利邊界。我在合約、接口層面做好權限設計和實現,保證在我的業務系統裡不洩露數據,我的區塊鏈應用層、展示界面、報表、日誌、數據庫等環節都不會被越權訪問,消除我內部操作風險。至於別人的節點,我管不著,那是他們的責任,誰洩露濫用數據,就重罰誰(取證、舉證其實挺難的)。這種邏輯其實有點“各掃門前雪”的意思,在這種模式下,我的敏感數據還是不能上鍊給到別人。第二個思路是
引入密碼學。這裡舉幾個例子。
非對稱加密:上鍊的數據用接受方的公鑰加密,則只有接收方才能用自己的私鑰解開。
密碼信封:上鍊數據採用某個口令加密,口令通過鏈外信道給到接收方,只有知道口令的接收方才能解密。
屬性加密:數據採用屬性加密算法進行加密,符合指定屬性(如具備管理員屬性)的才能解密。這些方案的考量在於運算、傳輸、存儲的開銷都會大一點,另外加密的數據不支持明文運算,難以實現複雜的業務合約邏輯。還要注意的是,即使加了密,本質上數據的全部信息還是都上鍊了,隨著時間推移,計算能力和算法(如量子密碼)的進化,存在被暴力破解的可能性,或者因為密鑰洩露/太簡單被猜到,鏈上的數據又無法撤回,就有被昭告天下的風險。第三個思路是
僅摘要上鍊
,數據明文根本就不上鍊。
其實,區塊鏈的作用並不一定是全面掌握數據和執行複雜的業務規則,而是憑藉多方見證的公信力,驗證數據的準確性、完整性,並起到存證和追溯的作用,事實上現階段很多區塊鏈系統主要是這麼個邏輯,客觀上已經能起到信任的錨點作用。
如果需要明文數據,再通過摘要裡的尋址信息去鏈外系統獲取數據,在這個環節上做精細的權限控制,並和鏈上摘要進行互驗。但,數據不上鍊還是有點不甘心呀,區塊鏈這麼創新的理念,智能合約這麼強大的功能,怎麼充分發揮呢?這就要講到
隱私計算
結語
https://fintech.webank.com/wedpr/VCL
結語https://sandbox.webank.com/wedpr/confidentialpayment/#/start
結語
一級標題
結語


