跳至主要內容
本頁面使用機器翻譯自英語,可能包含錯誤或不清楚的語言。如需最準確的信息,請參閱英文原文。由於更新頻繁,部分內容可能與英文原文有出入。請加入我們在 Crowdin 上的努力,幫助我們改進本頁面的翻譯。 (Crowdin translation page, Contributing guide)

Solidity - 智能合約語言

本章只介紹高級概念、開發過程和用 Solidity 編寫的示例,因為 Solidity 在其官方網站上已有詳盡的文檔說明。 有關語言規範或實現,請參閱下面的 參考文獻。 本章內容基於 [參考文獻](#參考文獻)中列出的多個網站。

堅固和卡婭

Solidity是一種高級、靜態類型化、面向合約的語言,用於在以太坊平臺上實現智能合約。 雖然 Solidity 最初是為以太坊設計的,但它在編寫智能合約方面具有足夠的通用性;因此,它也可用於其他區塊鏈平臺,如 Kaia。

Kaia 正式兼容倫敦以太坊虛擬機(EVM)版本。 不保證向後兼容 Kaia 上的其他 EVM 版本。 因此,強烈建議使用 Istanbul 目標選項編譯 Solidity 代碼。 請參閱 如何設置 Solc 的 EVM 版本

備註

v1.7.0 協議升級 - 不兼容的更改,包括伊斯坦布爾硬分叉項目和 Kaia 自己的項目。 如果是 Kairos 網絡,則從區塊編號 "#75,373,312 "開始啟用,如果是主網絡,則從區塊編號 "#86,816,005 "開始啟用。

v1.7.3 協議升級 - 包括倫敦***硬分叉產生的基本費用在內的不兼容變更。 如果是 Kairos 網絡,則從區塊編號 "#80,295,291 "開始啟用,如果是主網絡,則從區塊編號 "#86,816,005 "開始啟用。

v1.8.0 協議升級 - 包括倫敦***硬分叉產生的基本費用在內的不兼容變更。 如果是 Kairos 網絡,則從區塊編號 "#86,513,895 "開始啟用,如果是主網,則從區塊編號 "#86,816,005 "開始啟用。

在為Kaia開發智能合約時,可以使用Remix (一種基於瀏覽器的 IDE)和Truffle (一種開發框架)等開發工具。 Kaia 團隊將努力保持以太坊開發工具與 Kaia 開發工具之間的兼容性,但在必要時可能會選擇向 Kaia 智能合約開發人員提供這些工具的增強版或更新版。

使用 Remix 或 Truffle 開發智能合約非常方便,但 Solidity 編譯器也可在本地使用,只需按照下面網頁中的說明構建或安裝即可:

請注意,有兩種命令行 Solidity 編譯器:

  • solc:全功能編譯器
    • 包含在 Solidity 文檔中
  • solcjs:用於 solc 的 Javascript 綁定

其他有助於入門 Solidity 的資料包括以下內容:

如何編寫智能合約

本節以 Solidity 源代碼為例,讓讀者瞭解智能合約的外觀以及如何編寫合約。 請注意,此處包含的代碼僅供解釋之用,並不用於生產目的。 在代碼中,"(require) "表示任何 Solidity 源文件都需要該行,而"(optional) "則表示不一定需要該行。 符號 Ln: 並非 Solidity 代碼的一部分,在此加入只是為了顯示行號。 請不要在實際使用的源代碼中使用這些符號。


L01: pragma solidity 0.5.12; // (required) version pragma
L02:
L03: import "filename"; // (optional) importing other source files
L04:
L05: // (optional) smart contract definition
L06: contract UserStorage {
L07: mapping(address => uint) userData; // state variable
L08:
L09: function set(uint x) public {
L10: userData[msg.sender] = x;
L11: }
L12:
L13: function get() public view returns (uint) {
L14: return userData[msg.sender];
L15: }
L16:
L17: function getUserData(address user) public view returns (uint) {
L18: return userData[user];
L19: }
L20: }

上述代碼不言自明,因此熟悉其他編程語言的人可以跳過本節的解釋,直接跳到下一節。 不過,對於那些不清楚代碼作用的人,或者對於 Solidity 是第一種編程語言的人,我們會在下面附上源代碼的簡短說明:

  • 代碼中以雙斜線開頭的部分是註釋,而不是代碼;它們用於註釋和解釋代碼。 編譯器會忽略註釋。
  • L01 "中的 "pragma "語句表示編譯器的最小版本。
  • L03中的import 語句從"filename`"導入所有全局符號。 文件名 "應為實際文件名。
  • L05 - L20 定義了一個名為 UserStorage 的智能合約。 關鍵字 contract 位於合約名稱之前,聲明代碼代表一個智能合約。 Solidity 中的契約類似於面嚮對象語言中的類。 每個合約可包含狀態變量、函數、函數修改器、事件、結構類型和枚舉類型的聲明。 此外,合同還可以繼承其他合同。 示例代碼包含一個合同定義,但一個 Solidity 文件可能包含多個合同定義。
  • L07中,userData是映射類型的狀態變量。 狀態變量永久保存在合約存儲器中。 狀態變量 userData 維護著 addressuint 值之間的映射。 地址 "類型保存一個 20 字節的地址(Kaia 使用的 20 字節地址與以太坊類似)。
  • L09 定義了一個公共函數 set,用於在 userData 中保存信息發送者的 x 值。 變量 "msg.sender "是 Solidity 中定義的一個特殊變量,表示消息(即當前呼叫)發送者的地址。 關鍵字 "public "表示該函數是合約接口的一部分,可在外部或內部調用。
  • L13中的函數get 和 L17 中的函數 getUserData 是用 view 聲明的,這意味著函數承諾不修改任何狀態變量。 它們的聲明包括 returns (uint),這意味著它們返回一個 uint 值。

有關 Solidity 語言語法和語義的更多信息,請參閱 Solidity 文檔

如何編譯、部署和執行

編譯 Solidity 代碼的一種方法是使用命令行編譯器 solc。 這種編譯器可以產生各種輸出,從簡單的二進制文件和彙編到抽象語法樹(parse tree\ )。 假設上面的代碼保存在 UserStorage.sol(上面顯示的源文件中不包括 L03),編譯文件 UserStorage.sol的一些示例如下。


$ solc --bin UserStorage.sol

  • 該命令將以二進制_即_字節碼_的形式打印編譯輸出。

solc -o output --bin --ast --asm UserStorage.sol

  • 編譯器會生成二進制文件、抽象語法樹和彙編代碼,並將它們作為單獨的文件存放在 "輸出 "目錄下。

solc --optimize --bin UserStorage.sol

  • 為提高性能,可在編譯過程中使用 --optimize 標記激活優化器。

下面列出了一些用於編譯、部署和執行智能合約的資源。

注:本部分內容今後將進行更新。

調試智能合約

由於缺乏成熟的調試工具,調試 Solidity 代碼比調試用其他編程語言編寫的代碼更加困難。 下面,我們列出了一些用於 Solidity 調試的資源。

注:本部分內容今後將進行更新。

智能合約最佳實踐

要消除智能合約中的安全問題和代碼質量問題,必須學習並遵循 Solidity 編程的最佳實踐。 在此,我們展示了 Solidity 最佳實踐的參考資料。

注:本部分內容今後將進行更新。

參考資料

讓這個頁面變得更好