什么是智能合約
智能合約是在以太坊地址上運(yùn)行的程序。它們由執(zhí)行的數(shù)據(jù)和函數(shù)組成。
智能合約基礎(chǔ)
智能合約包括以下四個(gè)部分:
- 數(shù)據(jù)
- 全局變量
- 函數(shù)
- Event和Log
數(shù)據(jù)
任何合約的數(shù)據(jù)都必須持久性存儲(chǔ)或者存放在內(nèi)存里。智能合約中修改存儲(chǔ)的成本很高,因此數(shù)據(jù)應(yīng)該存放在哪里非常重要。
持久性數(shù)據(jù)
使用狀態(tài)變量來表示,這些數(shù)據(jù)永久的存儲(chǔ)在區(qū)塊鏈上。我們需要聲明這些數(shù)據(jù)的類型,以便合約可以在編譯時(shí)計(jì)算需要多少存儲(chǔ)空間。但是讀取成本相對(duì)較高,初始化和修改存儲(chǔ)的成本更高。所以我們應(yīng)該盡量避免這種存儲(chǔ)方式。
// Solidity example
contract Storage {
uint savedData; // State variable
}
如果你學(xué)習(xí)過面向?qū)ο蟮木幊?,那么你?yīng)該熟悉大多數(shù)的數(shù)據(jù)類型。但是,如果你不熟悉以太坊開發(fā),那么address類型對(duì)你來說應(yīng)該是比較陌生的。一個(gè)address類型可以存儲(chǔ)一個(gè) 20 字節(jié)的以太坊地址(十六進(jìn)制表示)
以下是其他數(shù)據(jù)類型,每種類型的詳細(xì)說明,請(qǐng)?jiān)L問Solidity 類型的官方文檔。
- boolean
- integer
- fixed point numbers
- fixed-size byte arrays
- dynamically-sized byte arrays
- Rational and integer literals
- String literals
- Hexadecimal literals
- Enums
內(nèi)存變量
只在合約函數(shù)執(zhí)行的生命周期內(nèi)存儲(chǔ),不會(huì)永久存儲(chǔ)在區(qū)塊鏈上,因此使用起來要便宜得多。要了解有關(guān) EVM 存儲(chǔ)數(shù)據(jù)的更多信息,請(qǐng)查看Solidity 上的文檔
全局變量
除了在合約中定義的變量外,還有一些特殊的全局變量。它們主要用于提供有關(guān)區(qū)塊鏈、當(dāng)前交易的信息,或者是常用的函數(shù)。
例如:
-
block.chainid (uint): 當(dāng)前區(qū)塊鏈 id -
block.timestamp (uint): 當(dāng)前區(qū)塊的時(shí)間戳 -
msg.value (uint): 隨消息發(fā)送的 wei/Ether 數(shù)量 -
msg.sender (address): 消息的發(fā)送者(當(dāng)前通話) -
blockhash(uint blockNumber)32字節(jié)的返回 值:當(dāng) 區(qū)塊的編號(hào)(blockNumber) 是 256 個(gè)最近的區(qū)塊之一時(shí)返回給定塊的哈希值,否則返回零
函數(shù)
函數(shù)是代碼的可執(zhí)行單元。主要處理每次輸入的交易,可以在合約內(nèi)部調(diào)用,也可以在外部調(diào)用,可以設(shè)置對(duì)其他合約的可見性。
函數(shù)可見性
- external
- public
- internal
- private
有關(guān)每種可見性類型的詳細(xì)說明,請(qǐng)?jiān)L問關(guān)于函數(shù)可見性的solidity 文檔
// Solidity example to show different parts of a function
function setUsername(string memory value) public {
userName = value;
}
-
setUsername函數(shù)入?yún)⒌膮?shù)類型是string, - 函數(shù)聲明為
public,任何人都可以調(diào)用它。
Event和log
我們可以通過Event與其他應(yīng)用程序通信,其他應(yīng)用可以通過以太坊客戶端的 RPC 接口訂閱和監(jiān)聽這些事件。當(dāng)交易進(jìn)行時(shí),智能合約可以發(fā)出事件并將日志寫入?yún)^(qū)塊鏈,以便其他應(yīng)用處理此次交易。詳細(xì)的解釋可以查看Solidity Events
以上,我們已經(jīng)了解了用 Solidity 編寫的智能合約的基礎(chǔ)知識(shí)。廢話說了一大堆,一個(gè)關(guān)于智能合約的教程,如果不編寫任何智能合約,就會(huì)顯得非常不完整。
下面是以太坊文檔中一個(gè)用solidity編寫的非常簡單的智能合約的例子。
//SPDX-License-Identifier: Unlicense
// Specifies the version of Solidity, using semantic versioning.
// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity ^0.8.4;
// Defines a contract named `HelloWorld`.
// A contract is a collection of functions and data (its state).
// Once deployed, a contract resides at a specific address on the Ethereum blockchain.
// Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
// Declares a state variable `message` of type `string`.
// State variables are variables whose values are permanently stored in contract storage.
// The keyword `public` makes variables accessible from outside a contract
// and creates a function that other contracts or clients can call to access the value.
string public message;
// Similar to many class-based object-oriented languages, a constructor is
// a special function that is only executed upon contract creation.
// Constructors are used to initialize the contract's data.
// Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
// Accepts a string argument `initMessage` and sets the value
// into the contract's `message` storage variable).
message = initMessage;
}
// A public function that accepts a string argument
// and updates the `message` storage variable.
function update(string memory newMessage) public {
message = newMessage;
}
}