知名創投 a16z Crypto 團隊與 MystenLabs 共同創辦人兼 CTO 、Move 語言之父 Sam Blackshear 進行了深度對話,共同探討為何 Move 是未來智能合約的重要方向。本文源於 Sui World DAO,由 Blockbeats 編譯整理。
(前情提要:Move系公鏈內鬥!Sui 技術長怒批:Aptos 耍手段打壓 Sui)
(背景補充:Aptos vs. Sui:一場Move上的L1公鏈對決!從融資、技術、生態詳談兩者差異)
去年 a16z 等一眾機構力捧以 Sui 為代表的 Move 公鏈,讓 Move 語言在 Meta Diem 的廢墟上大熱歸來;與此同時,從 Sui Move 出現那一刻起,不看好的聲音也一直存在:
如果僅僅是因為 Move 語言有可能比 Solidity 或其它開發語言更優秀,我們就一定需要一個新的智能合約語言,並樂此不疲地從頭開始搭建一個新 Layer1 嗎?
近日,a16z Crypto 團隊與 MystenLabs 的共同創辦人兼 CTO 、Move 語言之父 Sam Blackshear 進行了一次主題為《Programming Languages & Crypto》的 Podcast 對話,探討了為何 Move 是未來智能合約的重要方向。
在該集 Podcast 中,a16z Crypto 與 Sam Blackshear 從傳統編程語言與智能合約編程之間的差異和相似之處到辯論區塊鏈的獨特限制和機遇,展開討論了 Move 語言的設計思想、面向對象和資產的編程、安全性,以及分享了形式化驗證、治理和社區工具、跨平台適應性等話題。
主要分享內容包括:
1、編程語言與智能合約歷史
從傳統編程、到智能合約編程,再到 Move 編程。Move 是最早的關於如何設計語言以適應類型系統、靜態類型和編譯時檢查等問題的語言。
2、Move 智能合約的創新
EVM 過度適配了平台的實現細節,這些實現細節是為以太坊設計的。開發者最終不得不繼承以太坊做出的許多設計決策,包括一些讓以太坊難以擴展的錯誤。
Move 在設計時,沒有將任何區塊鏈特有的東西加入到核心語言中。源程式碼語言層面的創新將會相當重要,Move 最終能夠提供的是程式碼驗證器和 VM 級別的保護,以免受其他程序員的攻擊。
3、Sui Move 的設計思想
Move 是一種可執行的字節碼語言,用於執行用戶交易和智能合約。在 Sui Move 中,驗證者可以更有效地進行並行化,這使得存儲、執行都變得更容易,而不必將這些東西編碼到協議級別,並讓用戶和程序員來考慮。
4、安全性
在智能合約世界中,我們處於一個約束狀態。我們編寫非常少量的代碼,而且必須完美無缺,安全性必須是最首先要考慮的事情。Move 安全性是既要防止程序員自我攻擊,還要盡可能為他們提供正確的原語,以便他們能夠防禦攻擊。
5、面向對象和資產
Move 被設計為一種面向對象和資產的智能合約編程語言,之所以被設計成這樣,是因為大多數 Web2 面向對象的編程語言就是這樣。在 Sui Move 中,將事物的中心點放在對像上,高度激勵能夠盡可能精確地表示細粒度訪問。Sui Move 全局存儲的結構是一個從對象 ID 到對象 ID 的映射。
6、安全性對比
Move 通過構造消除了重入和智能合約編程中缺失的權限檢查問題。Move 中,對象所有權信息實際上存儲在對像元數據中,這不是程序員可以控制的東西。Move Prover 就是為了防止語言編寫智能合約的錯誤而設計,可以避免開發者犯很多基本的錯誤。
7、智能合約語言的治理
最初,Move 是在 Facebook 開發的,沒有真正的治理。我們非常謹慎地擴展語言。簡潔性是最主要的東西,但我們會積極地擴展它。Sam Blackshear 有一個非常具體的願望,比如 Move 被設計為一種跨平台語言,其中一些鏈EDM 的基本功能仍應適用,並且覆蓋了智能合約開發能手和 Web2 新人,極具靈活性。
8、給開發者的學習建議
閱讀大量代碼,這是了解語言的最佳方式。樂意分享和深入探討,並找到那些真正喜歡和他人分享你的代碼,一起構建開源社區的人們。任何可以讓你的工作變得更輕鬆的工具,你都應該學習它的工作原理。
以下為 Podcast 全文,全文約 25000 字,閱讀時間約 30 分鐘。
主持人 Sonal Chokshi 介紹
歡迎來到 Web 3.0,這裡是 a16z Crypto 團隊製作的關於建立下一代網路的節目。我是您的主持人 Sonal Chokshi。
本節目旨在為尋求了解和深入探討加密和 Web 3.0 相關事物的任何人提供幫助,無論是開發人員、創作者、建築師、企業領袖還是政策制定者。我們現在開始全新一季的節目。今天的節目主要討論編程語言和加密貨幣,既適用於現有的智能合約程序員,也適用於其他尋求進入這個領域的開發人員。
對於那些對編程語言的演變和出現感到好奇的人來說,這也是一個不錯的選擇。
我們今天的特別嘉賓是 MystenLabs 的共同創辦人兼 CTO Sam Blackshear ,該公司正在為 Web 3.0 的去中心化未來打下基礎。Sam 在編程語言方面有著資深的歷史,從他的博士學位到在 Facebook 工作,再到創建並成為Move 和開源編程語言的作者,用於構建智能合約。我們將更多地談論這個話題。
在整個節目中,我們還邀請到 a16z Crypto 的智能合約研究工程師 Noah,他和另一位夥伴最近為以太坊開發了名為 Helios 的輕量級客戶端並贏得了具有挑戰性的 gas 優化。
最後我們還邀請到 a16z Crypto 的工程師負責人Eddy Lazzarin ,在此之前,Eddy 在 Netflix 從事軟體工程,在Facebook 從事數據工程和數據科學。需要提醒的是,以下內容均不構成投資、商業、法律或稅務建議。
編程與智能合約的歷史
主持人Sonal Chokshi:
我們將從傳統編程的歷史開始,第一個發言的是 Noah,接著是 Sam Blackshear 和 Eddy。
a16z Crypto Noah:
我們想了解編程歷史如何影響智能合約編程的歷史,因為我覺得有三個東西,傳統編程、智能合約編程,還有Move 語言。這三件事都有它們自己的歷史,對吧?
Sui CTO Sam Blackshear:
沒錯,我喜歡這種框架。人們用語言來設計語法或讓人感到開心,這是對的,但它不僅僅是這些。所以我很喜歡這種大局觀的框架。
a16z Crypto Eddy Lazzarin:
就在這個基礎上,傳統編程有著過去二三十年來的各種趨勢。傳統編程語言已經發生了變化,有一些熱門話題來來去去。曾經有很長一段時間,動態編程語言和非常寬鬆的類型檢查是非常受歡迎的。通常認為,跳進去,忘記類型,忘記所有技術細節,只是編寫代碼是更符合人體工程學的方式。
Sui CTO Sam Blackshear:
但最近,人們開始更深入地思考類型系統、靜態類型和編譯時檢查等問題,以便在程序運行之前盡可能了解程序的所有細節。這些趨勢不斷變化。然而,對於智能合約編程來說,由於它是如此新穎,我們還沒有看到智能合約編程中這種類型的歷史,這是非常不同的。
我認為 Move 語言是我們所看到的最早的關於如何設計語言以適應這一點(類型系統、靜態類型和編譯時檢查等問題)的證據。我很想了解我們期望會發生哪些變化,例如靜態和動態類型等智能合約編程中可能出現的話題?這些話題可能還沒有出現,因為目前只有一種語言,即 Solidity。
主持人 Sonal Chokshi:
那麼,這又與轉向智能合約編程有什麼聯繫呢?再次請 Sam 回答?
Sui CTO Sam Blackshear:
在這個智能合約空間中,隨著 EVM 作為智能合約語言的第一批進入者,存在著不同的趨勢。人們不知道想用智能合約做什麼?我們如何編寫它們或任何這些類型的事情因此,我認為靈活性更加重要,以嘗試了解需要發現使用情況的專家的類型。我感覺現在我們已經知道了,或者至少我們對構建塊有一些了解。
智能合約的趨勢是極其領域特定的,你為資產定義模板,定義轉移資產的策略,檢查訪問控制和權限。
這就是基本的,你不會用智能合約語言編寫編譯器或操作系統或任何這些類型的事情。因此,它們非常非常好,它們與通用編程語言相比的優勢。
我認為人們低估了即使 ERC-20 標準發生在EVM 可以編程的很久之後,EVM 甚至被認為是編寫以太坊程序的基本構建塊之一。我只是沒有看到任何顯而易見的證據,證明最基本的東西在此之前是明確的。
所以你是對的,現在你可以把類型當作理所當然的事情。我認為類型和這些東西的繞過,是可以承受一定技術債務的。如果規模很小,你只想快速移動,而且代碼可以扔掉,那麼這種技術債務是完全可以接受的。但有趣的是,你把它用公司或創業公司的規模來描述,小公司在快速成長,每個人都能理解整個代碼庫,這種技術債務是可以容忍的。
但是,當它非常非常大時,有大量的人更改代碼,他們不知道正在構建的新對象和系統的後果。將其放入類型系統中,使您以明確、直接的方式編寫代碼時遇到障礙,而不是意外地創建後來有人會撞上的玻璃圍欄。
例如,就像你們談到的,能夠防止複制,能夠設置資產的最大供應量。這些約束非常重要,無論項目的規模如何,都需要保持。它們是維護項目的健全和安全非常重要的約束條件。了解這些界限意味著您現在可以創建編程語言,以允許您強制執行它們。這就是我如何看待 Move 語言的方式。
隨著我們了解到需要做正確的事情所需的約束類型,我們現在有能力將它們包含在語言本身中。因此,我確實認為它與類型有些相似,就像你所說的那樣。
你提到類型對於程序的健全性和安全性非常重要。你們說動態類型可能適用於小型項目,但隨著項目的增長,應該使用靜態類型。我有點不同意,我認為完全靜態的類型可能更適合。這可能是一個新穎的看法。它是為了程序員的健全性。我見過最可怕的事情是,當我按下我的快捷鍵「control k」時,它會告訴我函數簽名是什麼。當我寫Python 時,這讓我感到恐懼。我看著函數簽名,只看到參數的名稱。我就像,你到底想要我做什麼呢?
a16z Noah:
我不敢相信人們會接受那種寫出代碼後就永遠不會再看一眼的寫法。
a16z Eddy Lazzarin:
他們接受的是默認假設,即他們可以在心中記住系統的要求。
a16z Noah:
但是即使是 100 行的程序,我也覺得無法默認這一點。
Sam Blackshear :
它可以運行,但它並不完美。
a16z Eddy Lazzarin:
我認為你們說的對。而且我認為這種心態已經演變了。以前,類型系統是用來保護程序員免受同事傷害的。當你的創業公司變得太大時,它就很有用了。但現在它更像是在保護我自己。
在智能合約的環境下,它是在保護我免受攻擊者的攻擊。這是真正的不同之處,因為在普通程序中,你不會在攻擊者受到類型系統的約束時部署程序。攻擊者可以使用其他語言編寫機器代碼。你只需要保護你自己的防火牆就行了。但在這裡,我編寫這個很好的類型對象,它將流入攻擊者的代碼並保持其完整性。類型系統必須保證我的安全。
就像你說的那樣,這是一個很棒的工具,它給你帶來了不同的需求,你需要強制執行它們,比如防止複制。這不是你在普通類型系統中需要考慮的問題,或者防止刪除或確保你按某種方式使用或銷毀某個值。這些都是因為我們正在研究智能合約並試圖為這些用例提供有意義的類型系統,因此我們最終會將這些東西加入move 中,也可能會加入未來的智能合約語言中。
主持人Sonal Chokshi:
實際上,伙伴們,讓我們更多地談談傳統編程和智能合約編程之間的其他差異。但在我們進一步討論之前,你們能不能快速介紹一下智能合約程序員可以使用的語言呢?我認為我們需要了解一下大局,因為我想了解一下現狀,比如 Solidity、Viper 等。知道哪些內容能夠讓我們更快地入門。
Sui CTO Sam Blackshear :
是的,我想基本的情況是,如果你想編寫智能合約,你幾乎總是會使用 solidity。除非你恰好在幾個其他較小的生態系統之一。
如果你在 Polkadot 生態系統中,你會使用 ink!(Sui World 注:ink! 是由Parity 開發的智能合約語言,用於在 Rust 中編寫智能合約並編譯為 Wasm 程式碼),它是一個現有的編程語言。如果你在StarkNet 生態系統中,你使用 Cairo(Sui World 注:Cairo 是STARK 證明系統的其中一個編程語言)。
但是大部分情況下,如果我要給出建議,讓你學習如何編寫智能合約,我會建議你學習一些 Solidity,然後學習EVM。你可能還想使用 Viper,唯一的缺點是 Viper 是較新的,可能更容易出現漏洞。我記得幾年前,在驗證存款合約時,他們發現了 Viper 編譯器中的一堆漏洞。發現這些漏洞的人現在在 16z 工作,他是 Day June,他是一個形式驗證專家。
因為 Day June 是形式驗證專家,所以現在在 a16z 工作。而現實情況是,你需要學習一些內容,你需要學習一些語言。
你甚至需要深入了解 EVM,如果你想成為一個真正優秀的智能合約工程師,你需要了解 EVM 到一個荒謬的程度,以至於你可以說出每個操作的 gas 成本,他們能夠告訴你確切的與 gas 成本有關的代碼。這就是我們目前生活的世界。
a16z Eddy Lazzarin:
也許有一點值得一提的是,作為一名軟件工程師,你總可以了解你正在運行代碼的機器。有很多需要了解的關於編程環境的知識。但是在智能合約編程中,環境非常豐富、非常複雜。有很多上下文需要了解,這幾乎與語言本身無關。這就是在你周圍發生的事情,周圍有哪些對象,不同的代碼如何被調用。這是一件非常奇怪的事。
主持人Sonal Chokshi:
那麼,最接近學習 Solidity 的人是懂 JavaScript 的人,這是真的嗎?
Sui CTO Sam Blackshear :
大家都說是 JavaScript,因為它使用「function」這個關鍵詞,就像 JavaScript 也用到了。但不幸的是,它們並不是非常相似。
a16z Eddy Lazzarin:
從語法上看,Solidity 確實繼承了很多 JavaScript 的特性。如果你瞇著眼睛或情緒不好,可能會覺得相似,但實際上完全不同。虛擬機環境差異巨大,所以共同點很少。
主持人Sonal Chokshi:
有什麼相似的編程語言嗎?
a16z Noah:
是的,我認為沒有直接相似的編程語言。如果你熟悉 Was(Sui World 注:WebAssembly Studio,一款在線工具,用於將C/C++ 和Rust 代碼編譯為WASM 格式。 ),並試圖在一個需要高度隔離的環境中寫代碼(比如Surplus),這可能是最接近的了,這些代碼要獨立執行,但又需要一定程度的通信。但它仍然不是很相似,思維方式完全不同,表面上的相似可能會有危險。
a16z Eddy Lazzarin:
也許相關的是編程語言歷史上的一些重大錯誤。我不知道在區塊鏈方面是否有一些走下了錯誤道路的惡劣歷史。我們是否走了一些可怕的道路?
主持人Sonal Chokshi:
這是個好問題。
Sui CTO Sam Blackshear :
這是個好問題。1977 年,C 語言發布,也是Standard ML 發布的年份。Standard ML 具有極大的影響力。現在,有OCaml 語言、Rust 語言都受到其極大的影響,Move 語言也受到其影響。但這些思想已經存在了很長時間。我想很多人都在思考一個替代的未來,在那個未來中,C 語言沒有成為主流,而是Standard ML 的思想被廣泛接受,如強類型、內置安全性。
主持人Sonal Chokshi:
那麼,這種計算機技術的發展趨勢是什麼呢?我並不是說這是一個錯誤,但是我認為像Standard ML 這樣的語言即使在今天看起來也非常現代化。想像一下那個另類的宇宙是一個有趣的事情,當我第一次發現時就被震撼了。
a16z Eddy Lazzarin:
好奇心作祟,為什麼你認為像C 語言以及類似的語言,它們如此直白、如此命令式?它們在相對較低層次上思考計算機,作為編程語言它們並沒有做很多事情,這就是我對C 語言的看法,為什麼我們走了這條路?
Sui CTO Sam Blackshear :
我認為當時的硬件限制迫使你使用C 語言,如果你想要編寫高效的程序,或者推動計算機的邊界,我認為如果你向前推進硬件,你會選擇另一條道路。但是我認為,函數式編程很難,它在很多方面都是反直覺的。我不是說C 語言不難,但我覺得它更容易入門。然後你意識到,我已經做了非常複雜的事情,或者說很難推理,但是為時已晚。這是個好點子,函數式語言確實有更陡峭的學習曲線,但是一旦你掌握了,你會意識到,我可以很好地獨立地思考我的代碼,事情很好地解決了。
a16z Eddy Lazzarin:
我認為如果你很多地思考計算機是如何在硬件層面上工作的,那麼像C 語言這樣的語言就更直接了。但如果你對編程語言不是很了解,那麼C 語言就更容易入門。但是如果你非常了解編程語言,那麼我認為ML 和函數式編程這些類型的語言有更多的東西值得去探索。
Sui CTO Sam Blackshear :
這是一個大局觀的答案。但我想說的是有關小規模的「計算機語言錯誤」的問題。
a16z Noah:
所以,我對此有些猶豫,因為我一直聽說函數式編程有多棒,但是我發現有點難以理解。但我一直想知道的問題是,如果函數式編程真的那麼好,為什麼它從未能夠克服當前編程語言的網絡效應呢?它的這種局面令我驚訝。
但我想補充的一點,我認為函數式編程給我們帶來的巨大貢獻是,我們使用的所有命令式語言都是藉用的。但最好的是,就像你剛才說的,Rust 受標準電子郵件的影響很大,但Rust 基本上是一種命令式語言,對吧?但它擁有所有從凝視他們而來的奇妙的仙塵。
Sui CTO Sam Blackshear :
總的來說,我認為真正的問題是,從1977 年開始,命令式語言的影響力太大了。然後是PRFP,正如你所說,它不是最偉大的,它有自己的偉大想法,孤立地看,每個人都有自己的問題。我們現在只看到像Rust 這樣的真正的混血兒漂亮地嫁給他們。它真的改變了景觀。
所我想提的一件事是,就是Tony Hoare 稱之為節點引用的十億美元錯誤。雖然他當時可能是想誇張一下,但顯然這個錯誤帶來的代價比不犯這個錯誤更加昂貴。
a16z Eddy Lazzarin:
不,這可能只是下限。
智能合約的創新發展
a16z Noah:
我其實很好奇你沒怎麼談虛擬機層和編程語言層的創新,以及它們如何影響智能合約的發展。
Sui CTO Sam Blackshear :
這是個很好的問題。我認為人們沒有充分考慮這些區別,比如虛擬機層和編程語言層的區別。實際上,除了EVM 和新的虛擬機層,還有很多創新,比如Viper 等源代碼語言。這些東西在很多方面都比Solidity 更好,也很有趣。
我認為,如果Move 能夠成為我們期望的Web 3.0 的法律標準,那麼虛擬機層的創新將會是緩慢而漸進的。因為核心是固定的,我們只會添加新的東西,而不會徹底重新設計。
但是,我認為源代碼語言層面的創新將會相當重要。現在,我們只有一種源代碼語言,但它與字節碼格式緊密相連。但是,隨著越來越多的客戶使用智能合約,並強調安全性,我可以想像將會有很多不同的源代碼語言需要嘗試,這是一個有趣的研究領域。也許你可以先寫下你之前的事實,然後在程序中為你綜合他們的信息,或者對限制的建議。
也許你可以從編寫你的Move 以前的事實開始,然後通過合成程序為你填充程序,或提出限制的建議。
比如,你可能在一個非常特定的遊戲上下文中編寫Move,這個遊戲看起來像場景層次結構。也許它是用Python 庫編寫的,但是編譯成Move 的字節碼。也許你像Solana 或其他平台一樣,正在考慮整合Move,但不想整合虛擬機,而是通過將Move 的字節碼編譯為Salina 的字節碼格式,然後在開發者級別使用Move 源代碼語言。
我認為有很多不同的方法,就像JVM(Java Virtual Machine)一樣。JVM 是一個美妙的通用虛擬機,最初只支持Java。但它經過了時間的考驗,並且現在你有Scala、Groovy 和其他一些有趣的方式來使用這些原語來設計不同的編程體驗,非常符合人們想做的事情。
所以,我有一種偏見的看法,認為Viper 可以給你很多在源代碼語言層面進行實驗的空間。
a16z Eddy Lazzarin:
你對所有替代EVM 字節碼語言的看法如何?比如有FE、Iron 和Viper 等,這些有趣的努力旨在為EVM 構建更智能、更複雜的語言,你對此持樂觀態度嗎?
Sui CTO Sam Blackshear :
所以這些都是編譯成EVM 字節碼的不同源代碼語言。
a16z Eddy Lazzarin:
對,編譯成EVM 字節碼。
Sui CTO Sam Blackshear :
我們在Facebook 開始設計Move 時,看到其他源代碼語言構建EVM 的情況時,我們研究了Solidity 和Viper,這是在我們開始構建EVM 的時候。我們最終得出的結論是,讓人們編寫安全的智能合約最困難的問題是EVM 的底層性質,以及如何讓類型化的值在可信邊界上流動,以及動態決策等等這些問題,這些都是EVM 的特性。
如果你構建一個更好的源代碼語言,你可以讓開發者更難搞砸。也許他們可以進行更高級的驗證,但最終,Move 能夠提供的,而且我們認為很重要的是,代碼驗證器和VM 級別的保護,以免受其他程序員的攻擊。
源代碼語言不能給你這個,必須將其內置到VM 中,無論你在EVM 上迭代完美源代碼語言多少次,我認為Solidity 很棒,我們也可以做得更好,但我認為,如果你沒有這些基本的保護措施內置到VM 中,你得到的結果最終會不如一些其他路徑。我不是因為我認為Half 很酷而感到尷尬,而是因為我認為最終狀態不如其他路徑那麼吸引人。
我認為早期智能合約語言,特別是EVM,過度適配了平台的實現細節,這些實現細節是為以太坊設計的,內部包括了關於交易結構的指令,賬戶結構的指令,使用特定類型的密碼學等等。
我認為這使得在一個不像以太坊那樣的鏈上使用EVM 變得非常困難,你最終不得不繼承以太坊做出的許多設計決策,也許在某些情況下,還要繼承一些讓以太坊難以擴展的錯誤。
在設計Move 時,我們非常清醒地意識到不要將任何區塊鏈特有的東西加入到核心語言中,盡可能地讓它與具體的區塊鏈無關。
這樣你就可以拿著Move,在一個具有瘋狂交易結構的工作量證明鏈上使用它,這個鏈可能是在瑞典這樣做,而另一個鏈在澳大利亞是這樣做的。這樣,你就不必押注在某個特定的鏈上成為一個Move 開發者。你可以將你的技能跨越各種不同的鏈使用,包括未來的鏈。我們認為這對於一個智能合約語言的生存至關重要,因為一個語言最大的資產就是它的社區。而通過使你的技能跨平台,而不是過度適配於一種語言,你可以擴大社區的規模,從而更好地實現成功。然後,一個大的社區是使得在工具上投入大量資金、在公共庫上投入大量資金以及所有你真正需要一個語言成為大牌並取得成功的東西變得可能。
這是我們從一開始就嘗試做的事情,現在看到了多個真正不同的Move 鏈,它們在如何整合語言方面非常不同。
a16z Eddy Lazzarin:
在我看來,這是node.js 底層的主題,對吧?
主持人Sonal Chokshi:
是的。
a16z Eddy Lazzarin:
有很多人知道JavaScript,他們想做很多事情。他們想共享各種庫。現有的代碼可以啟動服務器端的JavaScript 實例,這使得node 變得有用。這意味著有各種各樣的開發者可能不做後端編程,但可以開始進入並將其作為自己的領域。
Sui CTO Sam Blackshear :
我認為這個對比很好。另外,我們想要談談關於編程語言治理的問題,因為Node 顯然有一些非常引人注目的治理分歧和分裂,每個編程語言社區都有許多引人注目的治理分歧和發展方向。我曾經報導過Node,它是我最喜歡的之一。但我想確保我們完成這個主題。還有別的要說的嗎?我覺得你是我們廣播節目中的居民老古板,我很喜歡。
a16z Noah:
所以我有一個反面觀點,或者說我有一個很酷的想法。我一直在想,為什麼沒有人建立一個Move 的OP Rollup,那將會非常酷,考慮到OP 的Rollup 人們是在以太坊上實現的,他們使用MetaMask 和ECDSA 簽名,但似乎並沒有使用與我們相同的簽名格式,比如Move 似乎沒有使用ECDSA。
Sui CTO Sam Blackshear :
是的,我們支持以太坊的EdDSA 和ECDSA 簽名格式。
a16z Noah:
很完美,但我的觀點是,你可以構建一些非常有趣的東西。但是,當我試圖學習Move 時,我一直在盯著甜點和演員狗。我很困惑。
Sui CTO Sam Blackshear :
確實是一個問題,對吧?當有人開始學習Move 時,他們可能會很困惑:我正在學習智能合約語言,但區塊鏈在哪裡?如果你試圖為兩個平台編寫代碼,它們之間的差異也會產生問題。所以我認為我們仍在努力解決的挑戰是,選擇一個平台,選擇一個甜點,選擇一個Optus,深入學習它,然後你會發現你的技能和代碼可以很容易地轉移到另一個平台上。我認為這裡存在一些固有的問題,還有一些文檔問題需要解決,以使這一切更加容易。
a16z Eddy Lazzarin:
也許類比一下,取決於你是否認為SQL 是一種可移植的技能。有很多SQL 方言。有一個反SQL,沒人真正知道它是什麼,但他們能學會SQL,如果你稍微瞇眼睛,你可以使用任何數據庫,可能會對特定的函數名稱或特定的類型有些困惑,但大致是相同的形狀。我認為這使得SQL 很強大和耐用。這就是為什麼它仍然是數據的共通語的一部分的原因。也許這就是Move 的未來。我認為我們可以做得更好一些。
Sui CTO Sam Blackshear :
我認為在跨平台方面,這是一個很好的目標,非常應用程序特定。這就是正確的語言來談論表格和談論數據庫。這是一個無可爭議的事實,這就是為什麼每個人都使用它。所以,如果Move 能成為區塊鏈中的SQL,我會很高興的。
智能合約編程的獨特事物
主持人Sonal Chokshi:
我們已經圍繞著傳統與智能合約編程、特定約束和差異以及甚至一些Tread 和智能合約編程之間的相似之處來回討論了。有沒有關於智能合約編程的獨特事物,我們沒有涵蓋?
a16z Eddy Lazzarin:
在智能合約上下文中,另一個非常重要的事情是資源使用,如Solidity 中的Gas Metering。雖然在很多情況下,計算資源是相對豐富的,計算成本也是非常重要的。但是在智能合約上下文之外或區塊鏈上下文之外,這意味著它僅被涉及和考慮得更少。我認為在語言中有關你消耗的資源的概念可能是智能合約編程的一個有趣的資源。
Sui CTO Sam Blackshear :
這是我們非常關注的事情,我們在EVM 中構建了Gas Metering,正如你所說,這與傳統編程語言非常不同。
我認為今後的趨勢是Gas Meeting 會變得越來越粗粒度,更多地防止如資源濫用之類的嚴重問題,而不是真正地為每個指令精打細算。
我實際上認為像Gas Golfing(Sui World 注:Gas Golfing 指的是在一系列智能合約的跳轉交互中,開發者編寫最節省gas 代碼的挑戰)這樣的東西雖然非常有趣,但實際上對編碼風格和安全性都有很大的傷害。
諷刺的是,我們之所以只知道按指令收費的模型,可能是因為如果你有一個龐大的虛擬機,運行10 萬條指令和運行50 萬條指令的差別在實際測量運行時間時微不足道。
所以,我們為什麼要按指令收費呢?因此,我認為我們會看到一種趨勢,就是如何使這更加粗粒度。
每當我看到所有這些不安全的塊和Solidity 代碼中的大量內聯彙編時,這讓我想起我們現在處於多麼早期的階段,因為這不是智能合約開發人員應該考慮的編程挑戰,這不是一個成熟的開發生態系統的標誌。但我們正在朝著這個方向發展。我同意我們要考慮極限情況。選擇正確的算法、選擇正確的數據結構、選擇正確的一般方法,這是大多數軟件工程的情況,都是很重要的。但關於準確計算每條指令的成本的瑣碎問題可能太過繁瑣了。
主持人Sonal Chokshi:
我們談到了優化gas,類型、資產和安全性。還有哪些限制是需要考慮的?
Sui CTO Sam Blackshear :
這是一個類似於gas 的線程,但我想到的具體子集是狀態。這對我來說是一個大問題。當我考慮gas 操作時,我喜歡進行極端的gas 優化。
但是,當我們處理持有真實資金的實際智能合約時,我的一般建議是,除非你可以費盡心思地使用略少於之前使用的狀態,否則你應該做出合理的組織。那是唯一一次我會使用大型彙編塊的情況,如果你可以做出一些愚蠢的事情來使用更少的狀態,因為這就像一個永遠的資源,我們應該將它放在僅高於執行或調用數據的位置。
a16z Eddy Lazzarin:
我完全同意這個觀點,因為我認為這是根本性的昂貴的問題。如果一個平台允許每個合約都觸及任何一塊狀態,那麼它將很難實現並行化。而像Squeeze 以及其他一些新的區塊鏈平台所採用的方法是,顯式地限定交易可以訪問的狀態,至少讓我知道一些。這樣在高層面上平台就能夠更容易地將交易實現並行化,包括執行和共識。因此,這是一些程序員必須思考的問題:在訪問狀態時盡可能地快,不要觸及不需要的狀態,這樣驗證者才能更有效地實現並行化,實現更多的區塊空間。
a16z Noah:
這是否會打開一種世界,即即使在非角色扮演的情況下,不是所有驗證者都需要下載全部狀態?如果你能很容易地將狀態分離開來,讓驗證者僅服務於它能處理的事務,這是否可以實現?
Sui CTO Sam Blackshear :
我認為這確實有可能實現這樣的世界。這也為不同的方法開闢了一條道路。
讓我回顧一下,從程序員的角度來看,能夠跨不同的交易觸及整個世界是非常有價值的。但是,我們不能過於強調這個優點,以至於必須通過Rollup 或者跨多個交易來實現,因為這會降低安全性,讓用戶注意到。
我認為區塊鏈的價值來自於這樣的抽象:有一個賬本,所有有價值的狀態都在這個賬本上,我可以一次性觸及它們。從程序員的角度來看,這是區塊鏈的價值所在。問題在於:如何在幕後讓事情更有效地進行?如何讓它變得更加稀疏,使得驗證者可以更有效地進行並行化?在Sui 中,一個驗證者可以有多個工作人員,每個工作人員負責一部分狀態。但從程序員的角度、甚至從其他驗證者的角度來看,它看起來就像是一個邏輯實體,它可以完成一切工作。
這使得存儲、執行都變得更容易,而不必將這些東西編碼到協議級別,並讓用戶和程序員來考慮。
智能合約編程思維方式上的改變
主持人Sonal Chokshi:
我們剛才討論了一些與智能合約編程相關的獨特之處。還有哪些思維方式上的改變?我們已經談到了一些,像Eddie 提到的,一個巨大的轉變是,在編程的世界中,至少自從計算機的早期,我們處於豐富的世界,但在這個世界中,我們處於限制的世界。那是一個思維方式的例子。還有哪些思維方式的轉變?特別是對於你們每個人來說,作為你們接觸智能合約編程的程序員,有什麼讓你們感到驚訝,或者教會了你們,或者讓你們對某些事情有了不同的看法?
a16z Eddy Lazzarin:
也許一個有點傻的例子是,我還記得幾年前我第一次學到ERC-20 Token的餘額不是你的賬戶擁有的東西。你的地址沒有Token餘額。代替它的是,有一個Token合約,記錄著哪個地址有多少餘額。當你想要向某人轉移Token時,你不是發送給他們一些Token。相反,你需要到合約中進行所有這些低級別的操作,改變你的地址和他們的地址所持有的餘額。你有權限操作和改變那個合約。這是一種非常反直覺的方式,在EVM 和Slippery 中這是第一次讓我注意到的關於Move 的一個有趣的思維方式轉變。這是有趣的思維方式轉變,因為我們經常聽到的英文單詞不一定與編程模型相對應。
Sui CTO Sam Blackshear :
我想要補充一點,這與你在實際操作時有關。在正常的世界中,我們非常關注開發人員的生產力,因為工程師的工作是編寫大量代碼,讓這些代碼只有幾個錯誤,並且這些錯誤不會太嚴重。而在智能合約世界中,你的工作是編寫非常少量的代碼,而且必須完美無缺。它必須在所有可能的方面都是完美的。否則,你將失去數億其他人的錢。這是一種完全不同的思維方式的轉變。花費兩個月的時間盯著1000 行代碼,並嘗試想出如何使其更好、更重要的是,如何使其完美,然後審核人員也要做同樣的工作,判斷它是否完美。
主持人Sonal Chokshi:
這是一個大的思維轉變。在編程的世界裡,至少自計算機的早期以來,我們一直處於豐富的世界,但在這個世界中,我們處於一個約束的世界。
a16z Eddy Lazzarin:
另一個思維轉變是,在ERC 20 Token的世界裡,你的地址沒有代Token餘額。你不能發送Token,你必須去訪問Token合約,在Token合約中查找地址對應的Token餘額,然後通過修改地址和余額來完成Token轉移。這是一種比較反直覺的思考方式,但在EVM 和Move 中,這是非常重要的思維轉變。
Sui CTO Sam Blackshear :
在智能合約編程中,你的工作是編寫一小段代碼,並且必須是完美的,因為這個代碼可能涉及到數億人的資金安全。你必須仔細審查代碼,確保代碼的正確性。
另外,升級智能合約的難度比升級移動應用或網站更高,因為在智能合約中,代碼是不可變的。在智能合約編程中,你必須考慮如何支持安全的升級和信任,使其看起來更像傳統生態系統。
但是智能合約編程中,你需要擁有一個對抗性的思維方式,這對於來自其他領域的人可能很陌生。這是因為在智能合約中的部署模型,你不僅需要考慮你的應用的預期使用情況,還要考慮非預期的使用情況。因為在傳統編程中,有方法可以隱藏自己,限制為一個小型API,或使用防火牆來限制攻擊者的操作等。
但智能合約的整個意義在於,你所做的可以與你從未想像過的代碼進行交互,並且可以安全地實現。因此,你需要考慮這種情況下的優點和缺點。這絕對是相對於傳統編程的一個思維方式的轉變。
主持人Sonal Chokshi:
這是一個非常重要的問題,也是我們討論如何編寫智能合約和使用智能合約編程語言時應該優先考慮的問題嗎?
Sui CTO Sam Blackshear :
是的,絕對是。這實際上是我最喜歡談論的事情。這讓我非常害怕,智能合約語言設計者需要考慮的問題是安全性。這是主要焦點,甚至可能是唯一的焦點,直到我們解決了這個問題。
我認為,智能合約安全對於更廣泛的加密貨幣採用來說是一種存在性威脅。我這麼說的原因是,您可以看一下以太坊和solidity,以及最流行的平台EVM 和Solidity。您可以看看編寫此代碼的早期程序員,他們非常高素質,真正理解底層區塊鏈,非常注重安全。他們知道自己在做什麼。我認為,他們非常認真地編寫管理數億美元和數十億美元的代碼的責任。
但是,如果您看一下任何地方的智能合約安全記錄,都非常糟糕,這不是這些人的錯。我認為這是一個非常困難的問題。並且我認為語言使其更加困難。所以,如果您看看我最喜歡的網站rakt.news,您可以查看排行榜或查看價值數千萬或數億美元的這十個黑客,這些黑客非常慣常,每週或每月發生一次,具體取決於規模。同時,智能合約開發者社區非常小,只有約5000 名全職EVM 程序員,這與傳統開發者社區相比非常非常小。
因此,如果您相信我們擁有的人是最硬核且最注重安全的人員,但開發實踐和安全記錄是不可持續的,那麼我認為您的結論是,沒有任何方式可以使這個空間在沒有使安全問題變得更糟的情況下繼續增長,這可能意味著它根本不會增長,或者像那些想進入Web3 的大型金融機構或公司一樣,他們正在看著自己是否必須僱用智能合約開發者?我會被黑客攻擊數千萬美元並感到緊張。隨著時間的推移,這種情況只會變得更糟。他們可能會保持觀望。因此,作為試圖設計新智能合約語言的人,安全性必須是您首先要考慮的事情。
主持人Sonal Chokshi:
你們其實已經在不失去資產的背景下暗示了這一點,但是你們更具體地是什麼意思呢,因為它非常重要?
Sui CTO Sam Blackshear :
我所說的安全性是指我們既要防止程序員自我腳踏,還要盡可能為他們提供正確的原語,以便他們能夠防禦攻擊,因為智能合約是一個設置,您的代碼部署在一個攻擊者旁邊,攻擊者可以直接調用您的代碼,可以直接與其鏈接。您的代碼是開源的,或者至少字節碼是開源的。
這是目前我們所見過的最具對抗性的編程環境,出錯的代價也是最高的。因此,我認為如果你在討論智能合約編程設計,那麼安全性必須始終放在首位。一旦我們解決了安全問題,我們可以考慮其他更具表現力的因素,但這是我的有些乏味,但我認為非常重要的答案。
a16z Eddy Lazzarin:
哪些特性能夠影響安全性?有什麼例子能夠體現這一點呢?
Sui CTO Sam Blackshear :
我認為最重要的是封裝,具體來說,是封裝的各個子特性。當您編寫代碼時,您無法預測攻擊者會嘗試什麼,因此需要能夠在沒有預見到攻擊者會做什麼的情況下進行推理。所以,您需要一個強大的類型系統,不僅在源代碼級別,而且在字節碼級別都需要,這樣您在編寫源代碼時獲得的保證將在您將代碼發佈到區塊鏈上、其他人依賴它並與它進行交互時繼續保持。
我們觀察到,在其他領域中流行的某些特性在智能合約編程中本質上是不適合的,比如動態分派。
在傳統的編程中,像接口和動態分派這樣的東西是關鍵的抽像機制,是無處不在的。您可以定義一個接口,然後其他人使用不同的邏輯重寫該接口,然後您可以針對該接口進行編程,一切都非常好。但是我們有一個俏皮的說法:「在代碼是法律的世界裡,接口是犯罪行為。」
a16z Noah:
這是個玩笑話,讓我們停下來一分鐘。在代碼是法律的世界裡,接口是犯罪行為。
主持人Sonal Chokshi:
在您繼續之前,您能否再解釋一下這句話?我不想太快地跳過它。
Sui CTO Sam Blackshear :
是的,完全正確。這裡的想法是,接口不定義行為,它定義了預期行為。比如,當你閱讀接口的規範、參數名稱甚至類型時,它告訴你想要完成什麼。但是並不能保證它就一定會發生。
所以,如果你編寫的代碼是用來保護某些東西的,但實際上你留下了一個空白支票供攻擊者、其他人填寫。這在契約法中似乎是一種犯罪。這是一個未明確規定的合同。我非常喜歡這個特性,它在傳統的編程語言中很受歡迎。但我們認為,在智能合約中,這導致了許多不同的問題。例如,重新進入需要動態調度。例如,如果您取消了動態調度,則根本沒有重新進入。像以太坊中的毒藥Token這樣的事情發生了,因為您重寫了轉移函數,而每個人都知道直觀地說,它只是用來轉移資金,也許不會做其他任何事情。但現在你讓它做一些超出預期的事情,比如竊取錢財。這就是一個特性的例子,如果將其刪除,那麼對代碼進行推理並進行適當的封裝就變得更加容易了,因為每次看到一個調用點時,您都知道它將確切地做什麼,您不必擔心其他人以後會做出令您驚訝的事情。
a16z Eddy Lazzarin:
確切地說,我認為這個類比就像如果你定義一個關於椅子的接口,它有四條腿和一個座位,你描述的是它的具體層面,而不是行為層面,你沒有描述可能是隱含或默認的關於椅子的其他事情,比如它具有某種結構完整性,它有特定的材料,它是以某種方式放置的。
a16z Eddy Lazzarin:
可能被規避,這意味著接口只是一組任意的描述,不能捕捉您想要強制執行的安全約束。
a16z Noah:
這正是定義。
a16z Eddy Lazzarin:
在錯誤的層面定義事物。我很好奇。
Sui CTO Sam Blackshear :
但是,您如何在接口之外很好地進行模塊化?如果接口是一種犯罪,我可能是一個罪犯,因為我的最喜歡構建複雜的智能合約的方式之一是喜歡有不同的合約,具有不同的目的。而且,特別是在非常複雜的系統中,您有一個基於模塊的基礎,其中模塊遵守某種接口,然後主要合同可以知道如何調用不同的模塊。這些模塊通常通過治理方式獲得許可,如何獲得超級表達的即插即用的模塊性?沒有標準化接口?如何獲得繼承?
a16z Eddy Lazzarin:
這些與接口有關的所有事情都喜歡嗎?
Sui CTO Sam Blackshear :
這正是要問的正確問題。他們可以整天反對這一點,但是如何提供一些使您編寫有用代碼的東西?就像如果不允許您走出房子之類的事情一樣,沒有犯罪。但是我們做到這一點的方式是,接口和繼承並不是唯一的方式,我傾向於以組合為思考方式。我們提供了幾種組合原語,不需要動態調度程序接口。
其中之一是泛型。我們有運行時遺傳,看起來很像您所擁有的。Clr(Sui World 注:common language runtime, 公共語言運行庫)讓我給出一個非常具體的例子,否則這很快就會變得抽象。
像您的ERC-20 之類的東西, 這顯然是一項根本重要的加密標準。如果您的平台,您的語言無法做到這一點,那麼它將沒有什麼用處。在像Move 這樣的語言中,您定義了一個稱為t 的類型點,其中t 是一個泛型類型參數,然後實現了coin 的函數,例如有一個函數用於將2 個點連接在一起。這適用於所有coin 類型。這不是某個人想要覆蓋的東西。您定義拆分。
當你想讓某人定制Token的行為時,使用所謂的能力模式,例如對於Token,你可能想要定制的一件事情是總供應量是多少,或者更根本的是它的政策是什麼?你可以這樣表達:好的,你有類型為「t」的點結構體,然後有不同的t 的實例化,例如美元、英鎊或其他的貨幣類型。對於你想要定制的東西,你在能力層面上提供它,創建一個Token的函數。你說,這是我的Token的類型參數,然後它會給你一個叫做「資金寶庫能力」的東西。然後有其他的邏輯確保只有持有t 的寶庫能力的人才能鑄造和銷毀t 類型的Token。你可以拿到這個寶庫能力,將它鎖定在一個不同的合約中,強制執行總供應量的限制。你可以將它放在某個地方,比如說只在周二評論,但不在周四評論。你倒置了控制流,這就允許你進行任意的組合。這是一個技巧的例子,但這個技巧可以在幾乎所有地方使用,如果你想要讓行為以某種方式工作,你需要硬編碼。這聽起來不好,但你實現特定的兩種方法,然後你為你想允許的東西定義這些能力。
a16z Eddy Lazzarin:
你認為能力是你可以添加到一個看起來像是傳統程序員的接口的約束嗎?
Sui CTO Sam Blackshear :
是的,我認為大多數這些接口模式可以非常直接地變體。這有點難以編譯,但是你可以說,這是這個接口想要做的事情的等效能力模式。
主持人Sonal Chokshi:
順便問一下,Sam,你覺得這樣滿意嗎?請隨意表示異議,有點衝突感是好事。
Sui CTO Sam Blackshear :
我覺得這樣還算滿意,因為我認為如果你可以有具有內在能力的模塊或者結構體,而這些模塊可以被餵入具有非常預定義行為的模塊中,你最終可以得到完全相同的行為,就像模塊可以做到的那樣。模塊接受抽象的結構體,那個結構體在那個模塊中被定義,然後這個結構體裡面有一個內在的能力。這實際上非常好用,因為你可以得到非常好的權限樣式註冊表,它們幾乎自然地從這裡產生,就像什麼叫做DS-Off 註冊表就是這樣,是吧?
a16z Noah:
完全正確。這些能力是可以擴展表示你被允許做的事情。因此這有很多其他的好處。比如說,你想知道我的賬戶能做什麼,你看看我有哪些能力就行了。然後,你可以做程序分析,看看如果我有一個寶庫能力,那麼我可以調用哪些函數,還有其他一些類似的東西。
面向對象和麵向資產的編程
a16z Eddy Lazzarin:
所以我可能有點提前談到證明器,但是這些能力對類型系統可見嗎?在對程序進行靜態分析的時候,這些能力在程序的哪個時候是可見的?如果我寫了一些特定實例化的代碼,其中有能力,那麼在我運行它之前,能夠很早地發現我違反了能力嗎?
a16z Noah:
是的,這些能力是對類型系統可見的,並且在程序的靜態分析階段就可見了。如果我寫了一個具有能力的特定實例化的類型的代碼,那麼非常早就可以發現我是否違反了能力,不需要在虛擬機上運行它。
Sui CTO Sam Blackshear :
讓我簡單回答一下這個問題,然後再提供一些背景信息,它們對編譯器可見,並且是類型系統的一部分。這是我們非常重要的一個利用點。但我想稍微講一下Move 可移動性系統中的結構體,以及它如何捲入到類似於審計的能力等級中。如果這不會分散注意力的話。
在Move 中,你有結構體類型和類似於其他語言的結構體,它們可以有字段,可以是基本類型的字段,也可以是其他結構體。而更加有趣,也許更加不同的是,這些結構體具有能力。如果你熟悉Rust,那麼能力有點像標記交易。它們聲明了你在結構體上允許進行的內置操作。
同樣重要的是,如果你沒有能力,你就不能做那些事情。比較簡單的一個能力是非常重要的,那就是複制的能力。如果你有一個Token類型或者非同質化Token之類的東西,在計算機中,它只是一些比特,但你不希望允許別人隨意複製這個東西。
在Move 中,如果你沒有聲明你的結構體具有復制的能力,那麼你就不能使用我們相當於「man copy」的操作。
所以像整數和字符串這樣的東西都有復制。但如果你不想讓你的類型具有復制的能力,那麼你就不給它。然後還有其他的能力,比如丟棄,這被稱為drop 能力。這就涉及到了有趣的線性類型的東西,如果你想要丟棄某些東西,比如把它放到作用域之外,或者覆蓋掉它,那麼你就給它drop 能力。但如果你不給drop,那麼消除它的唯一方法就是定義該類型的模塊所期望的任何策略。
公共語言運行庫(common language runtime,CLR) 舉個具體的例子,如果你想為你的Token保持一個總供應量,你就不給你的Token drop 能力。然後除了在聲明它的模塊中定義的burn 函數,沒有其他方式可以擺脫它,這個函數可以更新總供應量。這些都是你可以使用的技巧。還有幾個與存儲有關的能力,比如它是否可以存儲在全局存儲中,我不會詳細講述,因為它們對這個問題不太相關。但基本上,能力已經融入到審計程序中,審計程序了解類型系統,知道如何利用類型系統來解決問題。如果我編寫一個說明,說只有一個這樣的東西,那麼審計程序可以利用這個來證明這個屬性。因此,能力和類型系統的保證是相輔相成的。
a16z Noah:
當你提到drop 時,我就想談談我最喜歡的東西。你能不能談一下熱土豆模式是什麼?如果還有其他類似的酷東西,它是我最喜歡的奇怪事情之一,是從Move 中產生的。
Sui CTO Sam Blackshear :
這確實是一個奇怪的東西。這與能力非常密切相關。通常在編程語言中,你對於何時可以消除你的值沒有太多的控制,可能你有一個析構函數來說明你的值何時會消失。但是有時析構函數的保證比較弱,或者你不能簡單地說類似於「你不能刪除我的類型」。這聽起來像是一個奇怪的限制,但它實際上非常有力,特別是在沒有動態分派的情況下。
我先舉一個熱土豆的例子,然後我們可以深入了解閃電貸之類的東西。如果你在以太坊上進行閃電貸,這是一個標準,你可以重載它,基本上你公開一個回調函數,就像一個閃電貸合約,你給我錢,我的回調函數然後取回錢之類的,而在Move 中,你這樣做的方式是有人去閃電貸合約,他們說,「嘿,給我53 塊,但他們也給你所謂的熱土豆對象。
熱土豆對像是一個結構體,它沒有能力。它沒有復制,所以你不能複制它。它沒有全局存儲的能力,你不能像將它放在一個合約中一樣將其藏起來。它也沒有drop 能力,所以你無法將其丟棄。因此,唯一的擺脫它的方法是將它傳回閃電貸合約。讓你傳回它的閃電貸合約的代碼,強制你還款。如果你不還,它的程序將在運行時失敗,甚至不會通過類型檢查。因此,這是利用有趣的能力控制你的值的破壞,作為一個程序員,可以在任何時候強加任意的不變量,以決定何時可以銷毀這些對象。這些看起來很像API 調用模式非常明確。另一個非常明顯的例子是,如果你想要強制某人在調用unlock 之後調用lock,但在兩者之間可以做任何想做的事情,你也可以用這種方法實現。
a16z Eddy Lazzarin:
當我第一次聽到「燙手山芋」模式時,我想到了像「mute texas」這樣的鎖的有趣用途,這些鎖僅出於人體工程學目的,利用了類型系統,以強制特定對象的使用方式,幾乎是商業邏輯級別的要求。我認為這是非常聰明的,感覺非常現代化,是編程語言中人體工程學的高質量使用方式,而這種方式在傳統的編程語言中甚至還不是很常見,但在智能合約環境中顯然非常有價值,因為在這裡有更多的邏輯要求,要考慮可能涉及的價值和安全性。
Sui CTO Sam Blackshear :
在我們討論任何具體的例子之前,您能否快速概述一下我們的對象系統的高級概述?對像是什麼,誰擁有它們?對像如何擁有其他對象,模塊如何與它們一起工作?
a16z Noah:
是的,完全正確。這是關於Move 語言的一個方言,特別是Sui Move。這個東西的基礎是全局存儲的不同結構,而不是我們曾經使用的原始Move 方言的全局存儲方案。原始的Move 全局存儲方案非常類似於以太坊使用的公司模型。
在Sui Move 中,我們希望將事物的中心點放在對像上,高度激勵能夠盡可能精確地表示細粒度訪問。這有助於你做很多事情,我們不會在這個播客上詳細介紹,比如更有效地處理事務,告訴錢包用戶事務將要做什麼等等。
所以在Sui Move 中,全局存儲的結構是一個從對象ID 到對象ID 的映射。然後對像只是具有一個稱為鍵(key)的能力的Move 結構。它說:「嘿,我可以作為鍵。」它可以出現在全局對像池中。然後每個對象必須具有一個全局唯一的ID。然後你可以為你的模塊編寫入口點函數,它們可以直接將對像作為輸入。如果你在寫一個事務,這個WeRunTime 就會有對象ID。如果你寫的是事務,WeRunTime 就能夠使用這些ID 來將ID 解析為對象,並將其插入函數中。
這種面向對象和麵向資產的編程體驗非常棒。它比我們在原始Move 版本中的做法直接得多。你還提到了父對象和子對像以及對象層次結構。這非常有用,但你仍然希望能夠像表示大型集合這樣的東西。
比如,我正在構建一個類似於DNS 的註冊表,我希望有數百萬個條目。我們有一個對像大小限制,一個對象可以是幾兆字節,但不能更大。但是如果你有像DNS 這樣的東西,它應該是任意大的。我們表示它的方式是使用父子對象關係,我們基本上有一種方式將一個對象視為異構映射。然後你可以添加具有動態選擇字段的鍵。這在某種程度上非常類似於JavaScript。我們可以說,這個對像有一個映射在裡面,然後我可以在這個映射裡放一些東西。或者你可以說,當我定義這個對象時,它有十個字段,但我實際上想在後來添加一個新字段,我將升級我的合同。我想在事後添加一個新字段。
我們表示它的方式是使用這些父對象和子對象關係,每個子對像都與一個鍵值相關聯,可以是任意的Move 值,例如字符串或u64,或任何你想要的其他值。
a16z Noah:
是的,與父對象的概念有關,我認為讓它真正成為我的「靈光一閃」的事情實際上是幾個月前我花時間深入研究Sui Move,並從寫一個只有一個對象的程序一直到重新實現了大部分Uniswap V2 風格的卡牌組合。我做的一個小項目真正讓我意識到擁有對象的對像是如此有價值。這個項目只有三個對象,鎖、金子和一個空的障礙物。有一個很基本的模塊,你可以想像它可以創建由鑰匙對象擁有的金子。然後唯一的取出金子的方法是有一個函數,它需要鎖和鑰匙,並顯然銷毀鎖,把金子給你,然後銷毀你的鑰匙。這種方式非常有趣,通過這種方式,你可以描述對象之間的關係,並以非常細粒度的方式描述權限。
Sui CTO Sam Blackshear :
這也正是我們所考慮的。我喜歡你描述三個不同對象的嵌套方式,因為這種方式在深入到更深層次時變得更加強大。這使得作為程序員更容易結構化,以確保我可以到達第二層,然後可以觸及第三層,但我不能直接從第一層到達第三層。我認為這也使得對於從智能合約空間之外的程序員來說更容易理解,比如這些人非常熟悉編寫對象樹、DOM 對象樹,如果你是遊戲程序員,一切都是場景層次結構,其中有一個角色,他們有一個庫存,然後庫存裡可能有一些小東西。你可以非常直接地在Move 中編碼這些內容,然後類型系統允許你以非常直接和安全的方式設置這種訪問控制。我認為這是一種非常實際的編程體驗,它真正反映了關於現實世界的直覺,或者如何描述某些東西,然後直接轉化為相關的代碼。
Move 與Solidity 的安全性對比
主持人Sonal Chokshi:
順便說一下,在來到Wired 雜誌之前,我曾經在施樂公園呆了6 天,這讓我想起了一點關於面向對象編程的歷史。你剛才說的超級有趣,因為他們發明了Smalltalk,這是許多今天面向對象框架的早期前身。無論如何,有沒有其他的話題想討論?
a16z Noah:
我只有一個普遍性的問題,但實際上,有沒有在EVM 世界中發生的黑客事件等等,你認為如果使用Move,由於類型系統的緣故,這些事件就不會發生在第一次。
Sui CTO Sam Blackshear :
在EVM 世界中,我們已經提到了動態分配和重入,Move 通過構造消除了重入,任何與重入相關的問題都會消失,我認為人們做得很好。現在,我認為它避免了反應和查看。
a16z Eddy Lazzarin:
但是你能解釋一下,為什麼Move 會讓這些問題不可能發生嗎?
Sui CTO Sam Blackshear :
重入,對吧?發生了什麼?你寫了一些代碼,調用了某個函數。問題在於,有人提供了一個你最初沒有預料到的函數實現。為了實現這一點,函數調用必須是動態的。它必須調用代碼,這基本上是由調用者提供的函數指針,可能是攻擊者。如果你沒有任何動態函數調用,如果你總是知道一個函數調用的目標,那麼這根本就不可能發生,就像你調用的任何東西,你可能不知道代碼做了什麼,但是你知道它是什麼,你可以測試它,你可以驗證它,所有的東西都在那裡。所以從根本上說,別人不可能提供讓你的模塊行為變得出乎你意料的代碼,因為這只是一個靜態的函數調用。太酷了。
a16z Eddy Lazzarin:
因此,這就消除了可重入攻擊,這在Solidity 開發中一直是一個永恆的問題。
Sui CTO Sam Blackshear :
是的,我認為Move 基本上消除了智能合約編程中缺失的權限檢查問題。有很多時候你在寫一些代碼時需要顯式地傳遞所有的賬戶,並且你必須說,我是否有權做這件事。你寫了一個簡單的代碼,但是卻忘記了檢查發送者是否是某個人,或者是否這個人可以訪問它。我認為這些問題經常發生。
所以在Move 中,對象所有權信息實際上存儲在對像元數據中。這不是程序員可以控制的東西。
當你查看這些對象時,它們會說:「我由這個地址擁有」,或者「我由這個其他對象擁有」,或者「我是共享對象」或者「我是不可變對象」。程序員不能忘記檢查它的所有者,因為運行時會在執行傳入這個Sui 對象的代碼之前進行檢查。運行時會說:「我看到了這個交易中心,我看到了他們想要使用的所有對象。我正在檢查他們是否實際擁有這些對象,或者它們擁有一個可以中轉擁有它們的對象,以便他們有權使用它們。
我們要求程序員進行的許多權限檢查最終都在We Run Time 中發生,這些檢查是不可能忘記的。我認為這非常重要,因為最難保護的是程序員沒有告訴你的規範。這些規範很容易被忘記,使用靜態分析或其他方法很難捕捉到它們,因為你總是需要一些人來確定哪些規範很重要。
主持人Sonal Chokshi:
順便說一句,在遠期或近期的長期規劃方面,當人們以這種方式更多地合作時,企業規模會發生什麼,我認為這將非常有趣,因為它顯然是分佈式的,不僅僅是一個公司,有時人們會合作。但我的意思是,當你考慮現在的老舊方式,你有像開發人員和所有這些最佳實踐和所有這些方法。然後你有這些非常不同的思維方式來做事情,我們還沒有完全在這個世界中將所有這些正式化,這還為時過早,但我非常好奇這種事情會是什麼樣子。
a16z Noah:
現在EVM 的工具很好用,那麼Move 的工具怎麼樣呢?還需要進行哪些重大改變嗎?
Sui CTO Sam Blackshear :
我認為我們的工具還處於很早期的階段。我們正在開發一個包管理器,可以跨鏈使用,像Create.io 或npm 一樣。Move 的模型系統非常適合這種事情,我們正在努力實現這個目標。這個包管理器可以讓開發者輕鬆分享他們的代碼,這在Solidity 中很難做到,因為在Solidity 中,只能通過複製粘貼的方式來分享代碼。
我們還在最初的時候就專注於正確性工具的研發,我們有很多這樣的工具,但我認為我們還有很多事情要做,使它們更易用。我們有一個單元測試框架,我們可以直接在Move 中編寫測試。我們也開發了Move prover,用來輔助我們做形式化驗證。
Move Prover 的重要性
主持人Sonal Chokshi:
能否簡單談一下形式化驗證以及為什麼Move Prover 很重要?
Sui CTO Sam Blackshear :
形式化驗證很具有挑戰性,通常需要專家或者博士來使用。我們正在努力將它推廣到每一個日常開發者,而不需要專業知識。
目前還不清楚這個目標能否實現,但我們看到了一些很有前途的項目。比如,最近有人將一個智能合約的所有規範提交到了一張文件中,之後只需要為新函數寫規範,這就使得形式化驗證變得非常容易。不過,形式化驗證還有很多需要改進的地方,包括提高易用性和功能強大程度。
還有像fuzzer 這樣的工具,雖然不如形式化驗證好用,但對於一些重要的正確性檢查非常有幫助,特別是當你需要寫一些非常複雜的代碼時。我們也有一些學術界的庫在研發這些工具。除此之外,我們也正在研究如何讓編寫程序變得更容易,比如支持更多集成開發環境、程序合成和人工智能等。
主持人Sonal Chokshi:
如何使用Move Prover?如果我想試試它怎麼辦?
Sui CTO Sam Blackshear :
首先你需要拿到你已經測試過的程序。驗證不是測試的補充。然後你可以編寫一些很難測試或很難檢查的內容。這可能是一些簡單的函數前後條件。比如說,如果我的函數輸入滿足這個條件,那麼輸出應該滿足那個條件。你還可以編寫數據不變量,比如你有一個計數器,你想證明它總是在增加,你可以編寫一個規範,將其附加到計數器結構中,以檢查它是否成立。
然後它會查看所有的函數,並確保這些規範都成立。還有更高級的用法,比如全局存儲和變量。你可能想說,這個對象始終只有一個,或者這個對像有兩個,然後有三個。以及這個對象的字段和那個對象的字段之間的關係。這些規範很大程度上取決於應用程序。
Move 語言可以避免很多基本的錯誤,但對於你作為程序員來說,總會有一些特定於你的應用程序的正確性條件。規範語言使編寫這些條件變得容易,可以在編寫代碼之後或某些情況下甚至在編寫代碼之前編寫它們,並確保它們在所有可能的程序執行和所有可能的函數調用中都成立。
因此,現在,規範語言與編譯器集成,因此您可以在任何這些模式下提取它並嘗試使用它。它還與構建系統集成。您只需要執行move build -prove,它就會檢查這些規範。
a16z Noah:
酷!Prover 能理解Sui 對像模型和Sui 交易系統嗎?比如,我能否證明關於跨交易的一些可能修改全局狀態的內容?
Sui CTO Sam Blackshear :
它還沒有完全理解,但它並不需要完全理解。例如,如果你想證明計數器始終在增加,這是一個Sui 對象,但是它不需要完全理解Sui 就可以證明。即使在核心Move 的prover 中,它也真正考慮對象和全局存儲的層面,而不是像交易這樣的概念。因此,今天它確實只能考慮函數和事務的層面,這也能夠正常工作。但我想我們將來可能會在Sui 方面做更多的事情,特別是關於父子關係和異構對象映射。
編程語言的治理
主持人Sonal Chokshi:
我們可以談談編程語言的治理嗎?編程語言的演進有著悠久的歷史,但是在區塊鍊和加密貨幣的背景下,治理話題顯然更加重要,因為有許多其他方面需要考慮,如分權、開源、分佈式社區、令牌和經濟學資產等,這有時作為激勵計劃的一部分參與其中。
a16z Eddy Lazzarin:
特別是因為它們是開源的,能在許多不同的上下文中使用,它們被視為公共物品,但它們不同,需要設計和細節的關注。編程語言應該如何發展?今天有很多編程語言似乎都有不同的治理方式,如我所想到的前兩個是C++委員會和WG21 委員會,還有一些非常複雜的名稱。
然後像Python,Guido 是它的生命之恩人,擁有benevolent dictator for life。那麼,您認為什麼是現代化的編程語言治理方式?特別是在加密貨幣領域,這是一種獨特的情況,因為這些編程語言可能與層一相連,這是一種依賴於編程語言的不同類型的東西,它是一種公共物品,但是它有利益相關者,它有大量的資本附加值,有許多價值正在傳遞。也許有一些編程語言的治理模式更適合區塊鏈。我對思考編程語言應該如何治理或更好地說,移動如何發展,考慮到所有巨大的利益相關者和設計語言保護其安全性質的重要性非常感興趣。
Sui CTO Sam Blackshear :
嗯,我不會認為我的見解適用於其他編程語言。但對於Move 來說,我有一個非常具體的看法,就是這種跨平台的願望。Move 被設計為一種跨平台語言,其中一些鏈EDM 的基本功能仍應適用,並且覆蓋了智能合約開發能手和Web2 新人,極具靈活性。
除了對程序員和平台設計者的好處外,治理是另一個原因,幾乎所有區塊鏈語言中的有爭議的決定,例如:我們應該增加這個限制嗎?或者我們應該支持這種簽名方案嗎?或者我們是否應該擁有這個庫?我們試圖將其設置在適配器層,即構建在語言形式之上的平台,而核心語言非常簡潔。簡潔性是我們語言的關鍵設計原則之一,非常不依賴於區塊鏈。
因此,如果我們要與社區的利益相關者進行辯論,它不會像「我們應該增加gas 限制」這樣的問題。而是像「我們應該擁有電子郵件」這樣的問題,這是一個更純粹的設計問題,可以受到來自一個或多個Move 平台的問題或用例的影響,但不太可能朝著對某個利益相關者有利而對其他人不利的方向發展。到目前為止,這種模式一直運作得很好,但我們還需要看看未來會發生什麼。
基本上,Move 語言的治理方式是,最初,Move 是在Facebook 開發的,沒有真正的治理。它只是我們使用它的方式,雖然我們有這些設計原則。
現在,團隊分散了一些,我們有很多來自不同機構的成員。有些人在我們這裡,有些人在其它地方。有一些來自學術界、安全社區的第三方貢獻者,還有一些Move 鏈的星際幣等其他機構。我們每個星期四都會開會。
我們會討論Move 的設計問題,我們非常謹慎地擴展語言。簡潔性是主要的東西,但我們會積極地擴展它。
比如,添加這個東西會使在Move 之上的這些層次的實驗更容易進行。一旦我們看到這些實驗的結果,或者每個人似乎都在做同樣的事情,那麼我們就會將其移到核心語言中。因此,我們對治理的答案是:盡可能避免治理,通過讓有爭議的事情發生在Move 之上的層次,以及將簡潔性作為核心原則之一,使我們在僅當每個程序員都需要某個東西時,才添加新的內容。
主持人Sonal Chokshi:
你們作為程序員,對於另一面的事情,比如Noah,你們真的在乎嗎?比如說你選擇使用什麼工具,怎樣參與?你們在意社區或者編程語言的治理嗎?還是只在乎你們獲取所需的工具?
a16z Noah:
我認為在一定程度上是有關係的,比如你想使用一個被很多人使用的語言,這樣你就可以得到更多的貢獻者,對吧?你也想要一個不會被拋棄的語言,對吧?那些應該是主要的考慮因素。
但是,我並不在意Python 是由獨裁統治還是委員會治理,只要能夠達成目標就好。儘管我認為很多人不在意,但是有很多爭論表明由委員會治理已經破壞了很多編程語言,我想。
主持人Sonal Chokshi:
是啊,我一直覺得很有趣。
Sui CTO Sam Blackshear :
我認為這很重要。我有一些技術上的設想,比如跨平台的程序和資源,以及這些東西應該有的大致想法。但是這是一個社區項目。很多貢獻者為設計的很多方面做出了貢獻,我並不是Move 或任何其他東西的獨裁者。但是,我認為我的角色是策展人,確保每個人都在同一頁面,並確保在想法湧現時,我們根據這些原則進行評估,這些想法可以來自任何人。
但是最重要的是我們有共同的願景。每種語言都略有不同。我認為它們固有地反映了它們的用途、創建者和社區的個性等等因素。所以肯定不會有一種適用於所有的規則。
主持人Sonal Chokshi:
對,完全沒問題,這很有道理。
Sam 怎麼進入Move 的
所以在我們結束前的最後幾個問題裡,我突然意識到我們從來沒有聽過Sam 怎麼來到Move 的。我主要感興趣的不僅僅是因為我想听你的故事,我相信它很棒,但我更感興趣的是你是如何通過思考去解決問題的。所以你能快速分享一下這個過程嗎?當然可以。
Sui CTO Sam Blackshear :
我開始作為一名編程語言研究員來進行職業生涯。我從事靜態分析和程序驗證的工作,這意味著我花了很多時間看真實的程序,尋找漏洞,並嘗試弄清楚程序員經常犯的錯誤類型是什麼,以及導致這些錯誤的原因是什麼。是語言的基本問題使得某些類型的錯誤過於容易?是他們使用的框架的問題?還是僅僅是有關人類心理學,使得某些類型的錯誤比其他錯誤更容易被發現?
基本上,在我的博士期間,我花了很多時間研究真實的程序,查找漏洞,然後構建這些工具,試圖在不運行代碼的情況下查看代碼並嘗試在之前捕捉這些錯誤。而這種事情在一般情況下是無法解決的。你在進行靜態分析時,總是在與停機問題作鬥爭,但在實踐中,你可以無限地接近完美的結果,而不是在理論中得出平均結果。所以我花了很多時間做這件事,看了所有經典類型的漏洞,如空引用、緩衝區溢出、安全問題等等。我真的很享受這個工作,但是很難找到這些例子和很多人真正關心的數據集。
但是在我博士的最後階段,我在Facebook 實習。這是在2013 年到2014 年左右,他們正在從Web 世界向移動世界過渡,並且發現當我將漏洞發佈到移動應用中時,它會在那裡存在兩週,而在Web 中,我可以立即修復它。當我加入後,Android 上的分裂問題是造成問題最嚴重的問題,因為這會導致無法修復的漏洞。他們在靜態分析技術上進行了大量投資。他們從我的領域收購了一個研究小組,我有機會與他們一起工作,並繼續我真正喜歡的工作。但是,與其結束於單個程序的漏洞修復,我開始思考如何設計一種語言來使這種漏洞更難以產生。我對語言設計和程序安全方面的興趣越來越大,開始產生一些關於如何構建更安全的語言的想法。後來,我在2018 年加入了Libra 項目,這是一個構建基於區塊鏈的全球支付網絡的項目,我被徵用為編程語言方面的專家。這個項目需要一個新的編程語言,因此我開始著手構建Move 語言,並使用我之前的經驗來解決一些語言設計上的挑戰,例如如何確保Move 智能合約的安全性和正確性。
主持人Sonal Chokshi:
所以Libra 也被重命名為diem,這是今天很多人可能知道的。還有一個快速的提醒,你的博士論文的實際主題是什麼?
Sui CTO Sam Blackshear :
我的博士論文主要研究目標導向的靜態分析。通常,在進行靜態分析時,你會查看整個程序並構建有關程序的事實數據庫,然後通過獲取該事實數據庫來查找漏洞。這種方法很有效,但對於非常大的程序而言,不太容易擴展,因為你必須查看整個程序並做所有事情。而你可能有一個非常具體的問題,只關注程序中的一個特定部分。例如,如果你正在運行分析器,並且在CI 中報告漏洞,你真的想要報告在該pull request 中發生的漏洞。對程序中的其餘部分不是很關心。
在我的博士論文中,我研究了目標導向的靜態分析。這意味著我希望靜態分析的效率可以隨著我關心的特定屬性的複雜性而擴展,而不是隨著輸入程序的大小而擴展。如果這個屬性非常簡單,只需要進行簡單的推理就可以確定其安全性或漏洞性,我希望它非常快。或者如果這需要查看整個程序進行推理,則相應地會更慢。這是一件有用的事情,因為靜態分析的一個主要問題就是非常慢,特別是當你在運行像巨大的幾百萬行程序時。我在這個靜態分析子領域中研究了一個新的理論,稱為抽象解釋,旨在使抽象解釋更具目標導向性和屬性導向性,從而提高效率和精度。
主持人Sonal Chokshi:
非常有趣。你提到你在背景中也對心理學很感興趣,當你設計你的博士研究以及現在的工作時,你可以快速介紹一下程序員的心理學嗎?因為你沒有滿足我的好奇心。
Sui CTO Sam Blackshear :
當我在2018 年來到Libra 時,我們基本上需要在Libra 中建立智能合約,你需要想出這意味著什麼。你不能在真空中進行推理,就像語言基本上是問題解決工具一樣。所以我看了很多Solidity 和智能合約代碼。我想知道程序員用這些東西做什麼?語言在哪裡幫助了他們?在哪裡妨礙了他們?這個問題的主要結論是基本上所有這些程序都在試圖做同一件事。
他們試圖談論資產,試圖轉移它們,試圖定義它們。但是代碼編寫的方式總是如此間接。這就像一種粗暴的設計練習,你試圖談論這件事,但是沒有詞彙來表達它。這就是心理學的元素,我可以閱讀程序並思考,這個人在想什麼?在他們的頭腦中,相對於他們實際編寫的代碼?這個翻譯層中的障礙是什麼?語言如何通過提供正確的抽象來幫助他們?這些問題沒有客觀的答案。這就像我也是程序員,我會怎樣編寫這段代碼?或者我會發現什麼直觀而什麼困惑?
所以基本上,決定創建Move 而不是在EVM 上構建或使用現有語言是因為,正如我們之前所說,這種智能合約需求與其他任何東西都非常不同,使用現有語言沒有所需的抽像或特徵是沒有意義的。
如果你在EVM 中使用Solidity 之類的東西,這是這個領域的第一次嘗試。因此,它沒有合理地預測出人們將要嘗試做什麼。所以我認為我們有所有這些第二移動者的優勢。我們了解人們想做什麼,什麼效果好,什麼效果不好。我們應該利用這一點來打造一個新的語言。說服人們需要構建一個新的編程語言是一個有趣的旅程,我們可以在另一個時間討論,但是有人告訴你你應該說不。很多人對Facebook 是否有這種嘗試的願景持有合理的懷疑態度。
主持人Sonal Chokshi:
有趣的是,感覺這幾乎是你能夠回應的唯一地方,而且甚至更好的是,你們現在可以將其帶離Facebook 並繼續前進。實際上,對於它的誕生和發展來說,這幾乎是理想的條件。事實上,這對於它們兩者都是一個很好的機會。
Sui CTO Sam Blackshear :
完全是意外之喜。
主持人Sonal Chokshi:
那就很好了解了。
給智能合約編程語言開發者的建議
最後一個小問題,如果你們有一個建議想要給那些想要了解智能合約編程語言或已經在這個領域的人,如果你們可以用兩秒鐘的時間給一個建議,你們會說什麼?
Sui CTO Sam Blackshear :
閱讀大量代碼,了解代碼的目的以及底層代碼實際上是如何做到這一點,它做得好和不好在哪裡。
主持人Sonal Chokshi:
為什麼?簡單地說?
Sui CTO Sam Blackshear :
我認為這是了解語言的最佳方式,它是一個很抽象的東西。但是,如果你從某個東西開始,只是試圖弄清楚如何做到這一點,我認為這是一條更具體的路線,也很容易從中進行概括。好的。
主持人Sonal Chokshi:
艾迪,你有什麼建議嗎?
a16z Eddy Lazzarin:
這是個好問題。我完全同意Sam 說的。我還想補充一點,因為我們還處在早期階段,人們都喜歡分享一些有趣的東西,比如在區塊鏈上編程有多麼瘋狂。有很多人非常樂意分享,樂意深入探討。每次我在任何一個大型的社交群或者任何一個論壇上有問題的時候,人們總是樂於和我分享。所以我會建議大家找到那些你真正喜歡和他人分享你的代碼,一起構建開源社區的人們。
a16z Noah:
我的建議是,如果你有任何工作流程中經常使用的工具,無論是編譯器、測試工具還是其他任何可以讓你的工作變得更輕鬆的工具,你都應該學習它的工作原理。並且,每當你發現一個bug,就去修復它。成為開源軟件的好管理員。
主持人Sonal Chokshi:
你們說得非常好。再次感謝Sam、Noah 和Eddie 參加本期Web3@ACM 的節目。非常感謝你們。不管怎樣,祝你們有美好的一天,再見。
📍相關報導📍
佈局新興公鏈 Sui 空投》如何申請「SuiNS 域名、註冊錢包」(教學懶人包)