Solidity语言简介
solidity语言是一种可以编写智能合约的高级语言,当然编写智能合约不止这一种,但是学习以太坊最好还是学会这一种语言就差不多了。在以太坊平台上,solidiy编写的智能合约会运行在以太坊虚拟机EVM之上,变成字节码运行。
新手入门建议使用官方IDE开发工具Remix。
结构
solidity语言中的合约结构和面向对象编程的类相似。一个合约就几乎是一个类,结构基本一致。包括声明变量(如状态变量,函数,函数修改器,事件),合约继承等。
contract SimpleContract{
unit SomeData; // 状态变量
function(){
// 函数
}
address public creater; // 创建者地址
function SimpleContract() {
creater = msg.sender; // 在构造函数中记录合约创建者
}
modifier onlyCreater() {
// 函数修改器
require(msg.sender == creater);
_;
}
function abort() onlyCreater(){
// 使用函数修改器
}
event Deposit(address _from, uint _amount); // 事件
function Donate() payable(){
Deposit(msg.sender, msg.value); // 触发事件
}
}
- 状态变量:永久存储在合约账户中的值,用于保存合约状态。一经写入智能合约,部署到区块链之上,后不可修改 。
- 函数:结构类似js函数。
- 函数修改器:可用于修改函数的行为,在函数执行前或执行后插入其他逻辑。比如在函数执行前进行参数检查等。
- 事件:是以太坊日志协议的高层次抽象,用于记录合约执行过程中发生的各种事件以及状态变化。
变量类型
1. 值类型
跟C++ 极为相似。简要说明。
- 布尔类型。 true false,支持 ! && || == !=
- 枚举类型。enum SomeEnum { one, two, three }
- 整数类型。int uint,uint为无符号整数。变量支持通过后缀指明变量使用多少位进行存储,后缀范围是8~256之内8的整数倍。如int8 int16... int256, 默认为int256 uint256。
- address地址类型。智能合约独有的变量类型,长度为20字节,和以太坊账户地址长度一致。原本属于合约的基类,拥有一些成员方法和变量。从solidity0.5.0版本开始,合约不再继承自address地址类型,但仍然可以通过显式类型转换将合约转换为地址类型。
重点介绍address的一些方法和变量。
1. <address>.balance 账户余额
2. <address>.transfer(uint256 amount) 转账,失败会抛出异常,终止代码
3. <address>.send(uint256 amount) return (bool) 转账,失败会返回false
4. <address>.call(...) return (bool)
5. <address>.callcode(....) return (bool)
6. <address>.delegate(...) return (bool)
4 5 6 与合约进行交互。
4 接收任何长度类型的参数,每个参数被填充为32字节并拼接在一起。
6 与4的区别是 6仅执行diamagnetic,而诸如转账存储,余额等其他方面都是使用当前合约数据,这是为了用另外一个合约的代码。
5 属于早期接口,权限较低,无法访问msg.sender, msg.value等变量。
2. 引用类型
- 数组:T[k]类型为T长度为k的定长数组,T[ ] 则声明了一个动态数组
- 成员变量和函数:
- bytes和string,一种特殊的数组。bytes属于任意长度的字节数据,string用于表示任意长度的UTF8字符数据。
- push方法,数组尾部添加新元素,返回新数组长度。
- length 数组长度,账户存储中的数组长度可以修改,而内存中的数组创建后length成员已经确定了无法修改。外部调用无法返回一个动态数组的长度,做法是需要将返回的内容放在一个长度足够的定长数组。
- 成员变量和函数:
- 结构体。与C极为相似。
struct{
address add;
uint amount;
}
3. 映射:映射是一种键值对映射关系的存储结构。我们使用 mapping(KeyType => ValueType)来声明一个映射。
键类型KeyTpye可以是除了映射,动态数组,智能合约,枚举类型,结构体以外的任何类型。
值类型ValueType可以是任意类型,包括映射本身。
映射可以看作一个散列表,键输入散列,得到值。映射不存储键的值,而是存储其Keccak-256散列值。
3. 类型转换
显示类型转换和隐式类型转换。
uint16 a = uint16(b) 显式转换。
uint16 a = 0x11111111 32位隐式转为16位。
4. 运算符
需要注意一个新的运算符 delete
uint a[3]; 若a[2] = 2, delete a[2] 之后, a[2] = 0;
delete a 则表示将数组变为长度为0的空数组。
5. 类型推断
var a = "asad" 推断 a的类型为string,用法跟js中的var,C++中的auto一致。
内置单位、全局变量和函数
1. 货币单位
2. 时间单位
3. 区块和交易属性。
4. 异常处理函数
5. 数学加密函数
6. 合约相关的变量和函数。
选择控制结构
循环,条件语句与C++完全一致。
函数
调用同一合约的函数,内部调用
调用其他合约实例的方法,属于外部调用。
命名调用 !!!
函数可用性:external, public, internal, private
特殊函数
constant, 只读
fallback函数, 不接收参数,无返回值。
待更新。。。