面向資源編程:Flow Cadence智能合約語言的全新範式
2021年11月25日,在第9期 BeWater Live 上,Dapper Labs中國技術負責人唐博皞分享了 《面向資源編程:Flow Cadence智能合約語言的全新範式》
這場深度且系統的分享,核心內容:
1、Flow概覽
2、中央账本與Solidity智能合約面臨的風險和挑战
3、Cadence面向資源的編程範式基礎介紹
- 來自Rust和Move的啓發
- 資源數據
- 存儲形式
- 訪問模型
- 資源數據轉移
4、 Cadence相關工具鏈導覽:
- 开發者工具
- 學習路徑
BeWater
一、Flow概覽
我們先來介紹一下關於flow和我們 Dapper Labs, Dapper Labs 的前世今生大家其實已經非常熟悉非常了解。
現在整個市面上最主流的nft標准,在以太坊包括其他任何二層或者這樣的以太坊鏈上都非常熟悉 erc721 這樣一個NFT標准, Dapper Labs就是 erc721的編寫者,Flow的 CTO 在17年的時候制定了 erc721 的標准,並在當年制作了加密貓,應該說是第一款把以太網打爆的這樣一個 NFT 項目。
加密貓之後,我們其實沉寂了接幾乎兩年的時間,我們在思考的過程中發現了以太坊上種種問題,然後覺得自身的一些對 NFT 未來的暢想無法在以太坊這樣一個網絡上能完成,所以花了兩年的時間進行了非常深邃的研究和开發之後,做出了 Flow。
在2020年的時候上线了Flow鏈,同期在年末的時候也在此基礎上制作了NBA TOP shot。我們完成了在Flow鏈上的,包括最第一次的开發的功能性的完善,同時也將其產品化,也讓 NFT 更早的進入了大衆的視野之中。
Flow 在半年的時間已經達成了非常多的合作。Flow應該是做的是整個 web3 世界中在 web2 世界拓展裏邊做的最好的,我們現在希望以把 web2 世界引入 web3 世界為我們的宗旨來推廣我們的品牌。
Flow在其他的一些產品上也有它非常有特色的東西。
一個比較重要的嘗試是我們的Dapper Wallet,它是以信用卡支付的方式來讓 web2 世界的用戶進行NFT的消費和使用。在這個過程中我們隱藏了全部的加密的技術。當一個消費者玩NBA TS的時候,他根本接觸不到加密或者說區塊鏈相關信息,你就把它當成一個投資品或者說是一個消費品使用就可以了,這也是讓消費者以無門檻的形式進入到區塊鏈世界的一個例子。
然後第二個很大的特色,是我們的Flow本身的區塊鏈,它應該說是目前世界上所有區塊鏈中唯一一個以多功能節點架構設計的區塊鏈模式。它讓可擴展性這件事情變得非常容易。最核心的設計理念是將共識算法和計算節點兩個功能完全分離。
我們一共有4大類的功能性節點:分別為 collection節點,它是負責收集節點信息的;然後共識節點完成一塊區塊的打包;計算節點完成所有交易的計算;驗證節點完成對所有交易結果的驗證。最後將這兩塊信息封裝在一個塊中送去,這件事情是以一種流水线的形式完成的。因為讓每個不同的節點類型,負責了自己獨特的一套功能,所以他非常容易的進行針對性的擴展。目前大多數的區塊鏈,它基本上都是某功能涵蓋了所有的內容,因此就只能往上堆資源,或者說多犧牲某些特性,來提高它的性能。Flow因為它的分離共識和計算節點這樣一套多節點的架構,使這件事情可擴展性變得非常容易。
二、中央账本與Solidity智能合約面臨的風險和挑战
今天其實更多的想講的是後面大部分內容想講的是我們在設計為什么 Flow 的時候為什么沒有選用EVM。因為我們發現了很多中央账本的問題,
首先第一個問題在哪裏?
我們先舉一個例子看看什么是以账本為中心的實現,它存儲的內容始終是在中央账本中的。這裏是一個很簡單的Token合約的實例,他記錄了一個账戶裏邊每個账戶兌了多少錢。他是一個map的形式,將一個balance給記錄下來,同時有一個mint的方法,給這個地址 A receiver 添加了多少錢,這就是一個中央账目的形式。轉账的時候, 我們就將 A 用戶的 msg.sender 就是我交易發送方的金額,在我的中央账本中減去,同時receiver在接收方的中央在账本裏面加上這個錢。
這時候我們再看一下 Solidity 的陷阱在哪,我們在所有的過程中其實沒有強加任何數值上的約束。如果一個黑客用一個代碼,將後面的balance給注釋掉,接收方就永遠接收不到錢了,然後這裏金額在這個合約裏邊其實就永遠消失掉了。從代碼層從語言層上面我們無法阻止這件事情。所以我們其實經常聽到誰又黑了多少錢。
因為在整個 Solidity 設計機制中,只要以中央账本為設計模型那就不可避免的會因為一些黑客的原因或者是代碼輸入的原因,將你這邊的金額扣掉。編譯器不會對這類的語法做任何的錯誤檢查,也不會有任何的機制來阻止這些情況的發生。
還會碰到很多類似的潛在的問題,一方面從心理上這對智能合約的开發人員也有非常大的責任和壓力。另一方面還有很多底層代碼需要處理(盡管 OpenZeppelin 等工具庫解決了一部分)。比如管理數值上下溢出的問題,管理所有權問題,管理多籤問題。這些都是我們在做 EVM 一些生態的時候會碰到的問題。
三、Cadence面向資源的編程範式基礎介紹
1、來自Rust和Move的啓發
18年的時候 Libra 把一個新的概念引入進來:resource概念。它更加的專注於 FT(fungible token)的管理,將資金的轉移做得非常細化。之後19年 substrate 在 currency 的設計結構上也使用了 resource 的設計理念。
Flow 它在整個的設計理念的時候,把 resource 引用到了整個語言層面上的設計,完全基於 resource 來編程。
當然這部分大家如果熟悉 Rust 的話,可能也會比較熟悉,它其實是一種對所有權更加深入的使用。
2、Cadence
下面我們引出 Cadence ,一個面向資源 resource 的智能合約語言,它這邊有一個很獨特的箭頭,是 resource 的一個 instance 所獨有的賦值標記號,表示的是轉移,這個轉移是 resource 最核心的一個賦值的形式。
3、Cadence vs Solidity
資源數據
我們再看看資源類型的一個公共形式。我們這邊的 withdraw 他在調用的時候,創建了一個全新的 vault 資源,而 vault 資源裏具有的金額是我們傳進來的金額,這裏已經減掉了,但是我返回的結果必須是一個全新的 vault ,為什么?因為我們的方法強制指定了你必須返回一個資源,如果沒有返回這樣一個資源,代碼編譯不通過,這就是在代碼層面上,我們其實就保護了我們 withdraw ,你不可以說我只減了錢,不給另外一個人加錢,雖然我現在還沒加,但是我現在已經返回出來了一個固定的資源,固定資源一定是有這個 amount 的錢。至於你這裏邊的錢未來怎么用,外面會有其他代碼來解決。
當我deposit的時候,就必須要傳入一個有金額的這樣一個資源,因為指定類型 balance 新的 from 資源裏面,必須是有這樣一個 balance,它是個強類型的東西。
這時候我的函數方法中沒有返回任何東西,它意味着什么?意味着我們傳進來這個資源必須被銷毀,因為資源在代碼層面上只有兩種可選行為,一是你這個資源返回出去,到函數之外或者保存到用戶的账戶裏;二是銷毀掉。只要這樣一個資源類型,它的定義為資源,就必定會有一個最終的歸屬。如果沒有最終的歸屬,這個合約是無法通過。
我們在資源傳入的臨時資源銷毀之後,整個資源的生命周期就已經結束了,這種設計模式中,一切對資源不正確的使用都無法將該合約正常進行,都會導致編譯器報錯。
存儲形式
再回到剛才的我們非常簡單的例子, Solidity 它在存儲的形式上到底有什么不一樣?我們將 Cadence 裏面的 resource 依然是做一個 vault , vault 是來管理剛才的內容的,我們可以把 resource 想象是一種定義。
當我們創建 vault 之後,我們創建 vault 的實例不是保存在中央账本中的,而是將這個 vault 保存在了用戶的存儲的空間中,存儲的空間它是不是在合約裏面。合約裏只保存了這個定義文件,真正的實例保存在用戶的存儲空間之中。
在 Solidity 中,我們所有的記账模型是以key-value map的形式保存用戶的余額。但是在 Cadence 中我們剛才創建了資源出來之後存到的地方,不是我們的合約,而是 account 裏邊 storage 指定的一個地方,所以資源永久的存在了用戶的账戶之中,它是一種以人為本的账戶模型,讓你真正擁有了自數字資產的所有權,而不是將我數字資產的所有權放在一個別人账戶的記账本裏面的一行記錄,相當於資產真正意義上的屬於了你。
同時在中心化账本裏面,我們非常難統計到一個特定用戶擁有的所有資產信息。用過 Solidity 的人都知道,我要以一個账戶掃描我這個账戶裏面所有的 ERC20 或者是 NFT 是件非常艱難的事情。首先要有一個常見的 ERC20 的合約列表,然通過一些形式對於 ERC20 的合約,對它的中心化账本裏查詢,我才能收集到一個特定用戶的所有資產信息。但是 Cadence 不一樣,Cadence 模型下我們的所有數字資產全都在他账戶自己的空間裏,所以對於开發者來說,我要查用戶的某些數字資產,那就非常容易的能通過查詢該账戶,該账戶下面所有的路徑,所有的資源,然後一個列表直接查詢出來。
訪問模型
對資源的訪問,solidity 需要創建另外一個字段來標記一下它怎么來使用,這是非常中心化账本的模式。
而 Cadence 我剛才也說到就是說存儲的地方是它有一個 Storage ,然後在账戶的空間下一共有三類的存儲模型,分別為storage、public、private 這三類的存儲路徑,其實分別代表着對於資源的保存路徑。storage 保存的是我們原始的資源信息。我們可以將這些資源的接口,一些只讀的接口,軟鏈接到一個叫 public 的空間中,這個空間裏面其實我任意一個账戶都是可以去訪問到的,對於合約來說很多地方都使用了這塊。
還有一部分就是我可能我希望我來控制你账戶裏面的一些錢,他就會把部分的能力以接口的形式做了一個軟鏈接,保存到了 private 空間中。軟鏈接就相當於是一個快捷方式,用這樣的形式將我的部分能力交付給了另外一個人。這樣通過更加直觀的交付部分能力的形式,將我的資源的使用權限借出去。
資源數據的轉移
為什么以太坊或者說其他這種智能合約的交易調一個方法就可以解決,因為他們是中央账本,他們的交易可能就是一個合約中釋放出來的某個方法,這個方法裏邊傳入某些參數執行的一些事情。
但 Cadence 裏摒棄了中央账本的模式,所以我們在對交易的體現上,交易也改造成了一個富邏輯的代碼片段,而不是 Solidity 對於一個函數的簡單執行。同樣的交易本身也是 Cadence 語言的一部分,所有的使用所有的代碼編寫,都需要對資源正確的使用,才能正常執行。
我們可以看到這個例子,這是一個非常典型的將某個人的錢轉給另外一個人的實現方式。在這邊 my vault 裏邊取出來的10塊錢,到了一個臨時的 vault 資源,臨時資源在執行的過程中轉移到了接收方的 deposit 方法。臨時資源進去之後,充到receive的账戶裏面之後就被銷毀了,在整個交易的過程中這個資源正常的被安排到了某個地方,這個交易才能正常執行。如果 deposit 最後返回了一些內容的話,這個交易其實是連編譯都沒法通過的。整個的過程它始終要保持資源的正確才可以使用。這也是Cadence 從始至終貫徹的,對於資源需要非常慎重非常嚴格。
2、Cadence的解決方法
所以我們 Cadence 是怎么解決這些問題的?我們資產轉移的過程永遠是安全的,如果資源沒有被正確的使用,Cadence編譯器將拋出錯誤。
如果接收者沒有 Vault,無論是因為地址錯誤還是該账戶不想接收這些類型的數據,交易將會被回滾。所以 Flow 上不存在 0 地址銷毀。Flow上的資源要銷毀的話,必須在交易中顯示的顯示的destroy。這樣的話就不存在數據因為發送地址拼寫錯誤而丟失。
五、Cadence相關工具鏈導覽
1、开發者工具
這是我們現在有的一些开發工具,我大概可以給大家過一下
第一步入門,playground 是一個非常和友好的面向初學者快速去學習 Cadence 的一個網站。還有一個有比較有趣的叫 CryptoDappy 的視頻,這個是要有一定的基礎的开發者去學習可能會好一點。
-
第二步可能就要進入到我們的本地开發,本地开發的時候就會涉及到我們的命令行工具,我們的模擬器和我們的 VSCode 。模擬器我覺得最值得說的一個點就是他在做其他的合約,或者說其他的鏈的开發的時候,就可能先跑一個測試節點,跑一個測試鏈。然後 Flow 為了方便开發者开發其實就規避了這件事情。
我們直接做了一個本地化的工具直接模擬出了區塊鏈的一些節點內容,它具備大多數區塊鏈相同的功能,當你發消息過去的時候,它會將你發過去交易打包成塊,這樣的話好處就是我們不需要有一個非常大的節點始終在那邊跑着,只需要有一個非常類似於節點的環境跑着,然後當我有需要的時候發一筆交易,那邊給你一個反饋就行了,因為本質上區塊鏈就是一個狀態管理的數據庫。
-
第三步完成了功能測試之後,會要使用的一些工具,包括我們的區塊鏈瀏覽flowscan,包括我們的前端接入庫和後端接入庫。這裏面其實我還要特地要說一下 FCL 這個東西,就是大家接觸以太坊的人都知道,現在並沒有一個非常標准的規範來說我怎么來方便的去接入不同的用戶,作為一個應用方,我想接入這些錢包其實是一個很痛苦的事情。所以Flow設計了一套標准FCL。這套FCL的標准不僅僅定義了前端該怎么接,它同時也定義了錢包該怎么接。
當我的錢包它提供了足夠的API和對於 FCL 兼容的響應請求的內容呈現之後,FCL 就成為了一個連接錢包應用和區塊鏈三位一體連接在中心的一個標准化的框架。在這樣一個框架下,前端應用是不需要關心我後面到底接的是哪個類型的錢包。FCL 定義好了前端的標准,我只要調用 FCL 裏面的特定的一些內容,然後傳一個參數告訴你我要使用哪類型的錢包就行了。
而錢包在接入 FCL 的時候,只要完成了 FCL 標准定義下的那些要求,錢包也能快速的接入。這樣最大的好處有兩件事情。對於應用方來說,應用方不需要關心我到底是要接哪個錢包,未來只要是能適配到 FCL 的都可以用。而對於錢包开發方來說,只要有足夠支持 FCL 的應用,這個應該就可以使用他的錢包。
2、學習路徑圖
以上就是我今天的所有分享內容,謝謝大家。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC
7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC一個引...
悅盈:比特幣68000的空完美落地反彈繼續看跌 以太坊破前高看回撤
一個人的自律中,藏着無限的可能性,你自律的程度,決定着你人生的高度。 人生沒有近路可走,但你走的每...