以太坊智能合约学习笔记(二)
错误检查
-
throw
: 抛出异常。已被废弃。 -
revert()
: 抛出异常,并回滚到调用前的状态。 -
require(bool)
:require(false)
抛出异常,并回滚到调用前的状态,并返回剩余的 gas。用于检查有效条件,比如检查函数输入和返回、检查调用者(require(msg.sender == owner)
)。 -
assert(bool)
: 。assert(false)
抛出异常,并回滚到调用前的状态,并消耗掉所有的 gas。用于检查内部错误(internal errors),比如上溢和下溢。可以利用消耗掉所有的 gas的特性,防止或者惩罚恶意攻击。
if(true){
// 抛出异常,不往下走
throw;
}if(true){
// 抛出异常,不往下走
revert();
}// 抛出异常,不往下走
require(false);
// 抛出异常,不往下走
assert(false);
数组 数组(Arrays):相同类型的元素的集合所组成的数据结构。
数组类型:
- 固定长度数组。
uint[5] dynamicArr
- 动态长度数组。
uint[] fixedArr
-
length
。 固定长度数组为声明时的长度,动态长度数组为数组中含有多少元素。 -
push
。往动态长度数组中增加一个元素,固定长度数组没有该方法。
// 声明
uint[] dynamicArr;
uint[3] fixedArr;
// 创建数组
uint[] dynamicArr = new uint[](7);
// 赋值长度为 7 的动态长度数组
uint[3] fixedArr = new uint[3]();
// 报错
uint[3] fixedArr = [1, 2, 3];
// 赋值长度为 3 的固定长度数组// 成员赋值
dynamicArr[0] = 1;
fixedArr[0] = 1;
fixedArr[3] = 1;
// 报错// push 新元素
dynamicArr.push(1);
// 正确
fixedArr.push(1);
// 报错。fixedArr 没有 push 属性。// 访问元素
dynamicArr[1];
// 0
fixedArr[1];
// 2// 获取数组长度
dynamicArr.length;
// push 新元素后,长度为 7+1。
fixedArr.length // 3// 改变数组长度
dynamicArr.length = dynamicArr.length - 1;
// 正确
fixedArr.length = fixedArr.length - 1;
// 报错。不能改变固定长度数组的长度// 遍历数组
for(uint i;
i < dynamicArr.length;
i++){}
for(uint i;
i < fixedArr.length;
i++){}
// 固定长度数组转换为动态长度数组。由于语言完善的问题,支持状态变量之间的转换,未来可能会取消该限制。
uint[] x = [1, 3, 4];
// 正确。
uint[] memory x = [1, 3, 4];
// 报错。固定长度 memory 的数组,不能转换为动态长度 memory 的数组。
结构体 结构体(Structs): 结构体是一些元素的集合。合法元素类型包括:值类型、数组和映射等,不包括:结构体。
// 声明
struc Employee{ // 大写 E
address id;
uint salary;
uint lastPayDay;
}// 创建结构体
Employee employee = Employee(0x1, 0, 0);
// 访问成员
employee.id
数据存储
- storage 持久性
- memory 临时空间
- calldata 类似 memory,执行完后被抹除
- 传递引用 reference(EVM 上的内存地址)。 storage = storage
- 拷贝
memory a = storage ,b 在 memory 内存中重新开辟一个空间给 employee 类型,并且将 employee 这个值拷贝到 memory 内存空间中。将 memory 内存地址赋值给 memory 变量。所以 memory 变量内存地址并不是指向 storage 内存地址,而是一个 memory 变量的全新的地址。同样的将 memory 赋值给 storage 变量,也会进行一个拷贝。注意,只能将 memory 变量赋值给状态变量,而不是本地 storage 变量。因为我们只能在状态变量中分配内存空间。
http://www.tryblockchain.org/...
@黄敏之-助教; EVM的定义就是0值等同于回收,把一个storage设为0是消耗负值的gas
文章图片
实验结果: remove约等于remove2,同时远远小于remove3和4。且执行完remove12后下次remove34的gas消耗大大增加。这个很有意思。1和2做的都是释放内存的操作,所以有负gas的福利;释放内存后如果要再赋值,需要重新申请内存,所以这样会消耗更多的gas。
delete owner
delete arr 初始化arr length =0
delete arr[i] 初始化 arr 的某个元素,但此时 arr[i]还占据空间,length 也没有变。// 因此需要以下两步,真正的删除元素
arr[i] = arr[arr.length - 1]
arr.lenght -= 1;
【以太坊智能合约学习笔记(二)】未完成,待更新...
推荐阅读
- 人工智能|干货!人体姿态估计与运动预测
- 以太坊中的计量单位及相互转换
- 区块链开发平台(以太坊)
- 从前沿科技到现实应用,人脸识别智能门禁加速走进智慧社区
- 众泰T500智能互联双加载,让汽车生活更有趣
- 历史上的今天|【历史上的今天】2 月 16 日(世界上第一个 BBS 诞生;中国计算机教育开端;IBM 机器人赢得智能竞赛)
- 【兔兔*亲子】八大智能启蒙之第三周记录
- 基于stm32智能风扇|基于stm32智能风扇_一款基于STM32的智能灭火机器人设计
- stm32|基于STM32和freeRTOS智能门锁设计方案
- 浅析(成人情趣用品智能无人自动售货机是新零售的下一个风口吗())