什么是智能合约
智能合约是在以太坊地址上运行的程序。它们由执行的数据和函数组成。
智能合约基础
智能合约包括以下四个部分:
- 数据
- 全局变量
- 函数
- Event和Log
数据
任何合约的数据都必须持久性存储或者存放在内存里。智能合约中修改存储的成本很高,因此数据应该存放在哪里非常重要。
持久性数据
使用状态变量来表示,这些数据永久的存储在区块链上。我们需要声明这些数据的类型,以便合约可以在编译时计算需要多少存储空间。但是读取成本相对较高,初始化和修改存储的成本更高。所以我们应该尽量避免这种存储方式。
// Solidity example
contract Storage {
uint savedData; // State variable
}
如果你学习过面向对象的编程,那么你应该熟悉大多数的数据类型。但是,如果你不熟悉以太坊开发,那么address
类型对你来说应该是比较陌生的。一个address
类型可以存储一个 20 字节的以太坊地址(十六进制表示)
以下是其他数据类型,每种类型的详细说明,请访问Solidity 类型的官方文档。
- boolean
- integer
- fixed point numbers
- fixed-size byte arrays
- dynamically-sized byte arrays
- Rational and integer literals
- String literals
- Hexadecimal literals
- Enums
内存变量
只在合约函数执行的生命周期内存储,不会永久存储在区块链上,因此使用起来要便宜得多。要了解有关 EVM 存储数据的更多信息,请查看Solidity 上的文档
全局变量
除了在合约中定义的变量外,还有一些特殊的全局变量。它们主要用于提供有关区块链、当前交易的信息,或者是常用的函数。
例如:
-
block.chainid (uint)
: 当前区块链 id -
block.timestamp (uint)
: 当前区块的时间戳 -
msg.value (uint)
: 随消息发送的 wei/Ether 数量 -
msg.sender (address)
: 消息的发送者(当前通话) -
blockhash(uint blockNumber)
32字节的返回 值:当 区块的编号(blockNumber) 是 256 个最近的区块之一时返回给定块的哈希值,否则返回零
函数
函数是代码的可执行单元。主要处理每次输入的交易,可以在合约内部调用,也可以在外部调用,可以设置对其他合约的可见性。
函数可见性
- external
- public
- internal
- private
有关每种可见性类型的详细说明,请访问关于函数可见性的solidity 文档
// Solidity example to show different parts of a function
function setUsername(string memory value) public {
userName = value;
}
-
setUsername
函数入参的参数类型是string
, - 函数声明为
public
,任何人都可以调用它。
Event和log
我们可以通过Event与其他应用程序通信,其他应用可以通过以太坊客户端的 RPC 接口订阅和监听这些事件。当交易进行时,智能合约可以发出事件并将日志写入区块链,以便其他应用处理此次交易。详细的解释可以查看Solidity Events
以上,我们已经了解了用 Solidity 编写的智能合约的基础知识。废话说了一大堆,一个关于智能合约的教程,如果不编写任何智能合约,就会显得非常不完整。
下面是以太坊文档中一个用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;
}
}