跳至主要內容
Change page

智慧型合約結構

頁面最後更新: 2026年4月15日

智慧型合約是在以太坊地址運作的程式。 由可以在接收交易後執行的資料與函數組成。 此為智慧型合約組成的概覽。

先決條件

請務必先閱讀關於 智能合約 的內容。 此文件假設你已熟悉 JavaScript 或 Python 等程式語言。

資料

任何合約資料都必須指派到一個位置:storagememory。 修改智慧型合約的存儲很麻煩,所以必須謹慎思考要將資料儲存至何處。

Storage

永久資料也稱為存儲,並由狀態變數表示。 這些值會永久儲存於區塊鏈上。 你需要聲明一個類型,以便於合約在編譯時可以追蹤在區塊鏈上需要多少存儲空間。

// Solidity 範例
contract SimpleStorage {
    uint storedData; // 狀態變數
    // ...
}
# Vyper 範例
storedData: int128

如果已編寫過物件導向程式語言,應該會熟悉大多數類型。 但是,如果你是剛接觸以太坊開發的新手,應該會對 address 感到陌生。

address 類型可以儲存一個以太坊地址,相當於 20 個位元組或 160 位元。 它會以十六進制的形式傳回,前綴是 0x。

其他類型包含:

  • 布林值
  • 整數
  • 定點數
  • 固定規模的位元組陣列
  • 動態大小的位元組陣列
  • 有理數與整數常值
  • 字串常值
  • 十六進位常值
  • 列舉

如需更多說明,請參閱文件:

記憶體

僅在合約函數的執行生命週期儲存的值稱為記憶體變數。 由於這些變數不是永久儲存在區塊鏈上,所以使用成本要低得多。

Solidity 文件 (opens in a new tab)中,深入了解 EVM 如何儲存資料 (儲存體、記憶體與堆疊)。

環境變數

除了在自已的合約上定義的變數外,還有一些特殊的全域變數。 它們主要用於提供有關區塊鏈或目前交易的資訊。

範例:

屬性狀態變數描述
block.timestampuint256目前區塊時期的時間戳
msg.senderaddress訊息發送者(目前調用)

函數

用最簡單的術語來說,函數可以取得資訊或者設定資訊來回應傳入的交易。

有兩種函數調用方式:

  • internal – 這些不會建立 EVM 呼叫
    • 內部函數和狀態變數只能在內部存取 (即從目前合約或衍生自它的合約中存取)
  • external – 這些會建立 EVM 呼叫
    • 外部函數是合約介面的一部分,這表示可以從其他合約與透過交易調用。 外部函數 f 無法在內部呼叫 (即 f() 無法運作,但 this.f() 可以)。

它們也可以是 publicprivate

  • public 函數可以從合約內部或透過訊息從外部呼叫
  • private 函數只有在定義它們的合約中才可見,在衍生合約中則不可見

函數和狀態變數都可以被定義為 Public 或 Private

以下是更新合約狀態變數的函數:

// Solidity 範例
function update_name(string value) public {
    dapp_name = value;
}
  • 類型為 string 的參數 value 會傳遞至函數:update_name
  • 它被宣告為 public,代表任何人都可以存取
  • 它未被宣告為 view,因此可以修改合約狀態

檢視函數

這些函數保證不會修改合約資料的狀態。 常見範例為「getter」函數,例如,你可能用此接收使用者的餘額。

// Solidity 範例
function balanceOf(address _owner) public view returns (uint256 _balance) {
    return ownerPizzaCount[_owner];
}
dappName: public(string)

@view
@public
def readName() -> string:
  return dappName

以下情況被視為修改狀態:

  1. 寫入狀態變數。
  2. 發出事件 (opens in a new tab)
  3. 建立其他合約 (opens in a new tab)
  4. 使用 selfdestruct
  5. 透過調用傳送以太幣。
  6. 呼叫任何未標示為 viewpure 的函數。
  7. 使用低階調用。
  8. 使用包含特定作業碼的行內組譯。

建構函數

constructor 函數只會在合約首次部署時執行一次。 與許多以類別為基礎的程式語言中的 constructor 類似,這些函數通常會將狀態變數初始化為其指定值。

# Vyper 範例

@external
def __init__(_beneficiary: address, _bidding_time: uint256):
    self.beneficiary = _beneficiary
    self.auctionStart = block.timestamp
    self.auctionEnd = self.auctionStart + _bidding_time

內建函數

除了自己合約上定義的變數與函數外,還有一些特殊的內建函數。 最明顯的例子:

  • address.send() – Solidity
  • send(address) – Vyper

這讓合約可以給其他帳戶傳送以太幣。

撰寫函數

你的函數需要:

  • 參數變數及其類型(若接受參數)
  • 聲明為 internal/external
  • 聲明為 pure/view/payable
  • 傳回類型(若傳回值)

完整的合約看起來可能如上所示。 此處的 constructor 函數為 dapp_name 變數提供了一個初始值。

事件與日誌

事件讓你的智慧型合約能夠與你的前端或其他訂閱應用程式進行通訊。 一旦交易被驗證並新增到區塊中,智慧型合約就可以發出事件和記錄訊息,然後前端就能夠處理和利用這些資訊。

附註範例

以下是一些用 Solidity 編寫的範例。 如果你想試用這些程式碼,可以在 Remix (opens in a new tab) 中與其互動。

Hello world

代幣

獨特的數位資產

延伸閱讀

請參閱 Solidity 和 Vyper 文件,獲得智慧型合約更完整的概觀:

這篇文章對您有幫助嗎?