智能合约的代码结构
废话不多说,先来一个智能合约的例子:
pragma solidity ^0.4.4;
/*
pragma:版本声明
Solidity:开发语言
0.4.4:当前合约的版本,0.4代表主版本,4代表修复bug的升级版本
^:代表向上兼容,0.4.4 ~ 0.4.9可以对我们当前的代码进行编译
*/
contract Person {
uint _age;
uint _height;
address _owner; // 合约的拥有者
constructor () public{
_age = 29;
_height = 180;
_owner = msg.sender;
}
function owner() public constant returns (address){
return _owner;
}
function getAge() public constant returns(uint) {
return _age;
}
function getHeight() public constant returns(uint) {
return _height;
}
function setAge(uint age) public {
_age = age;
}
function setHeight(uint height) public {
_height = height;
}
function kill() public {
if(_owner == msg.sender){
selfdestruct(_owner); // 摧毁拥有者的合约
}
}
}
注释1:Contract
- Contract是一个内置的对象,上面的语法就类似于class Person(子类) extends Contract(父类),意味着Person继承于Contract。
- 对象内有其构造函数constructor,用以对实例进行初始化。
- 当合约部署的时候,就是产生一个合约的实例,来自同一个地址的相同合约只能部署一次,只有一个专有的合约地址。
注释2:状态变量
- _age , _height都是状态变量,在Contract中就相当于其属性变量;
- 在 Solidity 中,有两个地方可以存储变量 ——
storage
以及memory
。 Storage
变量是指永久存储在区块链中的变量。Memory
变量则是临时的,当外部函数对某合约调用完成时,内存型变量即被移除。- 状态变量(在函数之外声明的变量)默认为“storage”形式,并永久写入区块链;而在函数内部声明的变量默认是“memory”型的,它们函数调用结束后消失。
-
Storage 拿到的是引用/句柄/指针, memory 拿到的是一份拷贝。
注释3:函数和状态变量的可见性
因为Solidity有两种函数调用:
- 内部调用:不创建一个真实的EVM调用(也称为“消息调用”);
- 外部的调用:要创建一个真实的EMV调用,
在智能合约中,函数和状态变量的可见性可以分为四种, public , private , internal 和 external ,函数默认可见性是 public ,状态变量的默认可见性是 internal 。
-
public - (任意访问,作为合约接口)可以通过内部调用或通过消息调用。对公共状态变量而言,会有的自动访问限制符的函数生成。
-
private - (仅当前合约内)私有函数和状态变量仅仅在定义该合约中可见, 在派生的合约中不可见。
-
internal - (仅当前合约及所继承的合约)
这些函数和状态变量只能内部访问(即在当前合约或由它派生的合约),而不使用(关键字)this 。 -
external - (仅外部访问,也是合约接口)它们可以从其他合约调用, 也可以通过事务调用。外部函数f不能被内部调用(在内部也只能用外部访问方式访问,即 f()不执行,但this.f()执行)。
注释4:函数的限制访问
-
在Solidity中 constant 、 view 、 pure 三个函数修饰词的作用是告诉编译器,函数不改变/不读取状态变量,这样函数执行就可以不消耗gas了,因为不需要矿工来验证。
-
在Solidity v4.17之前,只有constant,后续版本将constant拆成了view和pure。view的作用和constant一模一样,可以读取状态变量但是不能改;pure则更为严格,pure修饰的函数不能改也不能读状态变量,只能操作函数内部变量,否则编译通不过。
注释5:msg.sender 和 selfdestruct()
在Contract中有一些全局变量和函数,在我们编写智能合约的过程中可以直接调用,比如上面的 msg.sender 和 selfdestruct() 。
msg的所有成员包括:
- msg.sender :储存消息的发送者,即部署智能合约的账户地址
- msg.value :发送的消息的数量
- msg.gas :剩余的gas
- msg.data:完整的calldata
- msg.sig :呼叫数据的前4个字节
合约相关的方法:
- selfdestruct ( address recipient ) :摧毁目前的合同,将资金送到给定的地址
- suicide ( address recipient ):同上,是别名
- this:指当前合约,明确转换为地址
全部的全局变量和函数有很多,包括:
- Ether单元
- 时间单位
- 块相关
- msg相关
- tx相关
- 当前时间戳
- 错误处理
- 数学和加密功能
- 地址相关
- 合约相关
具体有哪些全局变量可见第二节。