經(jīng)常有人問(wèn)到一個(gè)問(wèn)題:“怎么在合約里實(shí)現(xiàn)鏈上數(shù)據(jù)的讀取權(quán)限?”
這樣的需求背后,是開(kāi)發(fā)者想把一些數(shù)據(jù)上鏈,讓智能合約管理和運(yùn)算,以達(dá)成業(yè)務(wù)上的共識(shí),但又不希望數(shù)據(jù)公開(kāi)可見(jiàn),避免鏈上其他未授權(quán)參與者讀取,導(dǎo)致信息泄露。
最直觀的實(shí)現(xiàn)思路,就是在合約代碼里寫(xiě)一段過(guò)濾邏輯,判斷調(diào)用者滿足某些條件(如在白名單里)才允許返回?cái)?shù)據(jù),否則拒絕。
我們?cè)O(shè)定一個(gè)案例:有一個(gè)積分聯(lián)盟鏈,鏈上參與者有Alice、Bob、Carl、Dave等多方以及他們的家人,每個(gè)人的積分余額希望設(shè)定只有自己和家人可見(jiàn),其他參與者不可見(jiàn)。
客戶端通過(guò)區(qū)塊鏈的應(yīng)用級(jí)接口,發(fā)送請(qǐng)求到某個(gè)節(jié)點(diǎn),調(diào)用智能合約的get方法查Bob的積分,智能合約寫(xiě)了權(quán)限控制邏輯,拒絕越權(quán)訪問(wèn)。
因?yàn)橹悄芎霞s在每個(gè)節(jié)點(diǎn)上的運(yùn)行邏輯是一致的,因此無(wú)論請(qǐng)求發(fā)往哪個(gè)節(jié)點(diǎn),結(jié)果都一樣。這看起來(lái)貌似沒(méi)啥問(wèn)題,但實(shí)際是否也是如此?
這里先說(shuō)結(jié)論:這是個(gè)“治標(biāo)不治本”的做法,并不能確保數(shù)據(jù)不泄露。
現(xiàn)在開(kāi)始我們要用“多中心、去信任”的思維重新去審視這個(gè)案例。
我們先分析下:鏈上數(shù)據(jù)是怎么存儲(chǔ)?在什么情況下會(huì)被泄露呢?
區(qū)塊鏈網(wǎng)絡(luò)節(jié)點(diǎn)分布在不同參與者的環(huán)境里,出于區(qū)塊鏈的數(shù)據(jù)一致性特性,每個(gè)節(jié)點(diǎn)都持有一份完整的數(shù)據(jù)副本。無(wú)論這個(gè)數(shù)據(jù)庫(kù)是LevelDB/RocksDB這樣的文件型數(shù)據(jù)庫(kù),還是Mysql這樣的關(guān)系型數(shù)據(jù)庫(kù),數(shù)據(jù)都會(huì)落到每個(gè)節(jié)點(diǎn)的數(shù)據(jù)庫(kù)實(shí)例里。
也就是說(shuō)Bob的積分余額,在所有的節(jié)點(diǎn)硬盤(pán)上都存了一份,在MySQL數(shù)據(jù)庫(kù)工具里看,大概這個(gè)樣子:
如果鏈上(小概率地)存在某個(gè)有點(diǎn)兒區(qū)塊鏈技術(shù)經(jīng)驗(yàn)的參與者,暗戳戳地懷揣“惡意”(也就是俗稱的拜占庭玩家),他可以用工具打開(kāi)本地的數(shù)據(jù)庫(kù),直接查詢Bob的余額。這樣,用合約去防止數(shù)據(jù)泄露的控制邏輯就會(huì)完全被繞過(guò)。就這么簡(jiǎn)單。
另外,區(qū)塊鏈的數(shù)據(jù)不僅與合約相關(guān),還和交易記錄密切相關(guān)。
在發(fā)送交易的時(shí)候,交易參數(shù)會(huì)包含一部分或全部數(shù)據(jù)(如Alice給Bob轉(zhuǎn)賬100),交易會(huì)打包進(jìn)區(qū)塊,最終也寫(xiě)入節(jié)點(diǎn)數(shù)據(jù)庫(kù)里。
對(duì)區(qū)塊和交易數(shù)據(jù)的查詢一般不會(huì)用合約邏輯實(shí)現(xiàn),于是,僅僅在合約里寫(xiě)過(guò)濾邏輯并無(wú)法防止這些數(shù)據(jù)的讀取。拜占庭玩家可以在本地?cái)?shù)據(jù)庫(kù)里遍歷區(qū)塊數(shù)據(jù),獲取交易歷史明細(xì),從頭到尾回放交易流水,得知現(xiàn)在Bob的余額是300。
從整個(gè)技術(shù)棧來(lái)看,拜占庭玩家用工具訪問(wèn)本地?cái)?shù)據(jù)、遍歷區(qū)塊和交易都算是小意思了,他甚至可以修改區(qū)塊鏈系統(tǒng)代碼,從區(qū)塊鏈網(wǎng)絡(luò)接口、程序內(nèi)存、智能合約引擎等層面切入,從協(xié)議包、區(qū)塊、交易流水、合約上下文、狀態(tài)數(shù)據(jù)等環(huán)節(jié)嗅探和攔截到明文數(shù)據(jù),即使數(shù)據(jù)落盤(pán)是加密的,密鑰也在節(jié)點(diǎn)持有人手里,他照樣能解開(kāi)。
所以,從區(qū)塊鏈底層代碼入手去控制讀數(shù)據(jù)的權(quán)限,同樣也是不管用的,畢竟開(kāi)源的代碼,誰(shuí)都可以改,俗話說(shuō):“壞人會(huì)武術(shù),誰(shuí)都擋不住”,而懂技術(shù)的“壞人”更是無(wú)所不能、防不勝防。
總之,區(qū)塊鏈強(qiáng)調(diào)“分享”和“一致性”,只要明文數(shù)據(jù)在鏈上廣播,別人就有無(wú)數(shù)種方法去獲取。無(wú)論是在合約層還是底層代碼,幾乎所有的讀控制邏輯都像窗戶紙一捅就破,像馬其諾防線一樣形同虛設(shè)。
看到這里,有人可能會(huì)問(wèn):讀數(shù)據(jù)如此不設(shè)防,那區(qū)塊鏈上的“寫(xiě)”權(quán)限還有意義嗎?回答是:有的。
回到積分這個(gè)例子,我們?cè)O(shè)定Alice是積分管理員,她才能發(fā)起轉(zhuǎn)移積分的交易,然后Bob也只接受Alice給自己的積分。轉(zhuǎn)移積分的交易需要經(jīng)過(guò)全網(wǎng)共識(shí),所有共識(shí)節(jié)點(diǎn)會(huì)檢查合約里寫(xiě)的規(guī)則,不符合就拒絕簽名,越權(quán)交易無(wú)法得到共識(shí),則數(shù)據(jù)不會(huì)被修改。
這時(shí)即使有少量的拜占庭節(jié)點(diǎn),無(wú)論在本地節(jié)點(diǎn)怎么折騰,也篡改不了全網(wǎng)數(shù)據(jù)。
“寫(xiě)”交易追求共識(shí),所以客戶端發(fā)交易(sendTransaction或sendRawTransaction)時(shí),要打上數(shù)字簽名,區(qū)塊鏈系統(tǒng)驗(yàn)證簽名,確認(rèn)是哪個(gè)外部賬戶發(fā)過(guò)來(lái)的交易,可以進(jìn)行嚴(yán)格地校驗(yàn)和準(zhǔn)確地追溯。
“讀”操作更強(qiáng)調(diào)共享,讀數(shù)據(jù)的操作其實(shí)并不經(jīng)過(guò)共識(shí)流程,在自己的節(jié)點(diǎn)翻翻數(shù)據(jù)就行了。通常區(qū)塊鏈系統(tǒng)在讀接口(call)并不用嚴(yán)格填寫(xiě)發(fā)送者,也無(wú)需打上數(shù)字簽名,所以,在合約的讀方法里判斷外部賬戶,其實(shí)是無(wú)效的。
綜合以上種種分析,可以得出結(jié)論:在鏈上實(shí)現(xiàn)讀控制并不是簡(jiǎn)單的事情。
如果對(duì)讀控制邏輯考慮不足,那么效果將是:你在自己的節(jié)點(diǎn)上讀一下數(shù)據(jù)來(lái)測(cè)試驗(yàn)證,表象看起來(lái)OK,你以為歲月靜好,卻不知道在一個(gè)拜占庭玩家那里,數(shù)據(jù)已經(jīng)被翻得底朝天了。
考慮到多方協(xié)作中的去信任化,追求數(shù)據(jù)共享、公開(kāi)、透明的取向,一般來(lái)說(shuō),如果是關(guān)鍵的、不能泄露的敏感數(shù)據(jù),一定要慎重上鏈,能上鏈的,一定是大家說(shuō)好可以分享的“最大公約數(shù)”。
事實(shí)上很多區(qū)塊鏈系統(tǒng)里的交易和余額等狀態(tài)都是全網(wǎng)可見(jiàn)的,所謂的匿名性或隱私性,只是用公私鑰和地址體系代替了明文賬戶,這個(gè)級(jí)別的“匿名”,在業(yè)務(wù)模型復(fù)雜且強(qiáng)調(diào)全面隱私的金融、政務(wù)等領(lǐng)域并不適用。
那么我們還有什么方法,在兼顧共享、透明、開(kāi)放的同時(shí),適當(dāng)?shù)乜刂茢?shù)據(jù)可見(jiàn)性呢?
第一個(gè)思路是與鏈外治理結(jié)合,約定責(zé)權(quán)利邊界。我在合約、接口層面做好權(quán)限設(shè)計(jì)和實(shí)現(xiàn),保證在我的業(yè)務(wù)系統(tǒng)里不泄露數(shù)據(jù),我的區(qū)塊鏈應(yīng)用層、展示界面、報(bào)表、日志、數(shù)據(jù)庫(kù)等環(huán)節(jié)都不會(huì)被越權(quán)訪問(wèn),消除我內(nèi)部操作風(fēng)險(xiǎn)。
至于別人的節(jié)點(diǎn),我管不著,那是他們的責(zé)任,誰(shuí)泄露濫用數(shù)據(jù),就重罰誰(shuí)(取證、舉證其實(shí)挺難的)。這種邏輯其實(shí)有點(diǎn)“各掃門(mén)前雪”的意思,在這種模式下,我的敏感數(shù)據(jù)還是不能上鏈給到別人。
第二個(gè)思路是引入密碼學(xué)。這里舉幾個(gè)例子。
非對(duì)稱加密:上鏈的數(shù)據(jù)用接受方的公鑰加密,則只有接收方才能用自己的私鑰解開(kāi)。
密碼信封:上鏈數(shù)據(jù)采用某個(gè)口令加密,口令通過(guò)鏈外信道給到接收方,只有知道口令的接收方才能解密。
屬性加密:數(shù)據(jù)采用屬性加密算法進(jìn)行加密,符合指定屬性(如具備管理員屬性)的才能解密。這些方案的考量在于運(yùn)算、傳輸、存儲(chǔ)的開(kāi)銷都會(huì)大一點(diǎn),另外加密的數(shù)據(jù)不支持明文運(yùn)算,難以實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)合約邏輯。還要注意的是,即使加了密,本質(zhì)上數(shù)據(jù)的全部信息還是都上鏈了,隨著時(shí)間推移,計(jì)算能力和算法(如量子密碼)的進(jìn)化,存在被暴力破解的可能性,或者因?yàn)槊荑€泄露/太簡(jiǎn)單被猜到,鏈上的數(shù)據(jù)又無(wú)法撤回,就有被昭告天下的風(fēng)險(xiǎn)。
第三個(gè)思路是僅摘要上鏈,數(shù)據(jù)明文根本就不上鏈。
其實(shí),區(qū)塊鏈的作用并不一定是全面掌握數(shù)據(jù)和執(zhí)行復(fù)雜的業(yè)務(wù)規(guī)則,而是憑借多方見(jiàn)證的公信力,驗(yàn)證數(shù)據(jù)的準(zhǔn)確性、完整性,并起到存證和追溯的作用,事實(shí)上現(xiàn)階段很多區(qū)塊鏈系統(tǒng)主要是這么個(gè)邏輯,客觀上已經(jīng)能起到信任的錨點(diǎn)作用。
如果需要明文數(shù)據(jù),再通過(guò)摘要里的尋址信息去鏈外系統(tǒng)獲取數(shù)據(jù),在這個(gè)環(huán)節(jié)上做精細(xì)的權(quán)限控制,并和鏈上摘要進(jìn)行互驗(yàn)。
但,數(shù)據(jù)不上鏈還是有點(diǎn)不甘心呀,區(qū)塊鏈這么創(chuàng)新的理念,智能合約這么強(qiáng)大的功能,怎么充分發(fā)揮呢?
這就要講到隱私計(jì)算了,包括但不限于零知識(shí)證明、同態(tài)加密、安全多方計(jì)算、聯(lián)邦學(xué)習(xí)等一系列重武器,可以做到隱秘?cái)?shù)據(jù)、身份的同時(shí),對(duì)加密數(shù)據(jù)進(jìn)行加減乘除運(yùn)算、邏輯運(yùn)算、排序、統(tǒng)計(jì)分析,更進(jìn)一步還可以做到“前臺(tái)匿名,后臺(tái)可審計(jì)”的效果,以符合監(jiān)管合規(guī)要求。這就是在區(qū)塊鏈上實(shí)現(xiàn)“可用不可見(jiàn)”的最終奧義。
限于篇幅,這里不展開(kāi)隱私計(jì)算的細(xì)節(jié),可以參考WeDPR隱私保護(hù)相關(guān)的開(kāi)源場(chǎng)景方案,尤其是其中的幾個(gè)場(chǎng)景,如VCL區(qū)塊鏈可驗(yàn)證密文賬本,可以用于解決前面提到的積分案例里的一些隱私問(wèn)題。
WeDPR隱私保護(hù)相關(guān)開(kāi)源場(chǎng)景方案:
https://fintech.webank.com/wedpr/
VCL區(qū)塊鏈可驗(yàn)證密文賬本:
https://sandbox.webank.com/wedpr/confidentialpayment/#/start
結(jié)語(yǔ)
本來(lái)只是想聊聊“怎么寫(xiě)合約讀權(quán)限”這樣一個(gè)小問(wèn)題,結(jié)果變成了長(zhǎng)篇。
其實(shí)面對(duì)區(qū)塊鏈編程和開(kāi)發(fā)時(shí),真的不能像寫(xiě)單機(jī)或集群軟件那樣考慮問(wèn)題,而要充分考量多方參與、去信任環(huán)境下的協(xié)作關(guān)系,在共享、透明、可追溯的基本哲學(xué)之上,關(guān)注隱私保護(hù)訴求,掂量數(shù)據(jù)的重要性和敏感性,再深入到技術(shù)棧,考慮各種算法的功效和成本、綜合現(xiàn)在和未來(lái)的風(fēng)險(xiǎn)和收益以選擇合適策略,這樣才能全面保護(hù)數(shù)據(jù)和隱私,安全地發(fā)展業(yè)務(wù),維護(hù)自身和用戶權(quán)益。