Solidity是EVM虚拟机的一种智能合约语言,本文的学习路线主要是参考 https://cryptozombies.io/ 的学习进行的总结回顾
合约
基本结构与节本数据类型
变量
- 全局变量
- 会持久化到区块中
- 局部变量
- 仅仅在内存中执行
时间变量
- now
- seconds
- minutes
- hours
- days
- weeks
- years
1 | uint lastUpdated; |
随机数
- 用 keccak256 来制造随机数
- 其他参考资料:https://ethereum.stackexchange.com/questions/191/how-can-i-securely-generate-a-random-number-in-my-smart-contract
1 | // 生成一个0到100的随机数: |
maps
和普通代码编程的map并无区别,存储键值对
1 | mapping (address => uint) public accountBalance; |
数学运算
- 加法:
x + y
- 减法:
x - y
- 乘法:
x * y
- 除法:
x / y
- 取模:
x % y
- 乘方:
x ** y
数组
- 公共数组:Solidity 会自动创建 getter 方法
1
Person[] public people;
类型转换
- keccak256:内部SHA3散列函数
- uint8(a)
Storage与Memory
- Storage 永久存储在区块链中的变量
Memory 存储在内存中的变量
- 状态变量(在函数之外声明的变量)默认为“存储”形式,并永久写入区块链;
- 而在函数内部声明的变量是“内存”型的,它们函数调用结束后消失。
1 | contract SandwichFactory { |
控制结构
- if
- for
1 | function getEvens() pure external returns(uint[]) { |
函数
属性
- 私有:private
- 公共:public
- 返回值
- 内部:internal:
- internal 和 private 类似,不过, 如果某个合约继承自其父合约,这个合约即可以访问父合约中定义的“内部”函数。
- 外部:external
- external与public 类似,只不过这些函数只能在合约之外调用。
- 多返回值
1 | function multipleReturns() internal returns(uint a, uint b, uint c) { |
- 结构体传参
1 | function _doStuff(Zombie storage _zombie) internal { |
修饰符
- pure:不读取应用里的状态
view:只读取数据,不更改数据
1
2
3
4function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
return rand % dnaModulus;
}可以带参数
1 | // 存储用户年龄的映射 |
- payable
msg.value表示查看向合约中发送了多少以太的方法。
1 | contract OnlineStore { |
- 提现
this.balance 存储了现有的eth1
2
3
4
5contract GetPaid is Ownable {
function withdraw() external onlyOwner {
owner.transfer(this.balance);
}
}
- TIPS.
- 不能有相同名称的修饰符和函数。
包的导入
- 引入文件
1 | import "./someothercontract.sol"; |
结构体
与普通的结构体并无区别
1 | struct Person { |
接口与事件
事件
- 事件 是合约和区块链通讯的一种机制。你的前端应用“监听”某些事件,并做出反应。
事件创建
事件通知
1 | pragma solidity ^0.4.19; |
接口
- 定义接口
- 使用接口
1 | //假设原合约为: |
合约交互
msg.sender
- 指的是当前调用者(或智能合约)的 address。
Require
- 使得函数在执行过程中,当不满足某些条件时抛出错误,并停止执行
1 | require(keccak256(_name) == keccak256("Vitalik")); |
继承
继承
- 与普通面向对象语言的继承一样
1 | ontract Doge { |
多重继承
- 使用多重继承的时候,你只需要用逗号 , 来隔开几个你想要继承的合约
1 | contract SatoshiNakamoto is NickSzabo, HalFinney { |
合约库
Ownable 合约
1 | /** |
- 构造函数:function Ownable(),初始化函数
- 函数修饰符:modifier onlyOwner(),用来修饰其它已有函数
- 执行时先执行修饰符中的内容,到
_
部分后开始执行原有函数的内容
- 执行时先执行修饰符中的内容,到
1 | contract MyContract is Ownable { |
ERC721 标准
1 | contract ERC721 { |
safeMath
1 | library SafeMath { |
1 | using SafeMath for uint256; |
Gas的节省套路
- 如果一个 struct 中有多个 uint,则尽可能使用较小的 uint, Solidity 会将这些 uint 打包在一起,从而占用较少的存储空间
1 | struct NormalStruct { |
- view 函数不花费gas
- 使用内存数组解决gas