摘要:错误检查抛出异常。用于检查内部错误,比如上溢和下溢。由于语言完善的问题,支持状态变量之间的转换,未来可能会取消该限制。注意,只能将变量赋值给状态变量,而不是本地变量。因为我们只能在状态变量中分配内存空间。
错误检查
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 变量。因为我们只能在状态变量中分配内存空间。
delete 初始化变量、删除数组中的内容
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;
未完成,待更新...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/23998.html
摘要:和比特币协议有所不同的是,以太坊的设计十分灵活,极具适应性。超级账本区块链的商业应用超级账本超级账本是基金会下的众多项目中的一个。证书颁发机构负责签发撤 showImg(https://segmentfault.com/img/bV2ge9?w=900&h=385); 从比特币开始 一个故事告诉你比特币的原理及运作机制 这篇文章的定位会比较科普,尽量用类比的方法将比特币的基本原理讲出来...
摘要:舍去小数位在以太坊中账户有两种类型普通账户和智能合约账户。报酬是小额的以太币,想要运行智能合约的人的需要支付报酬来使合约工作。涉及到以太坊智能合约的攻击的问题。 智能合约可以简单的理解为一段可执行的程序片段,具体的代码经过 Solidity 编写之后,发布到区块链上。而以太坊的智能合约也可以理解为一个特殊的交易(包括可执行代码的),被发送出去后会被矿工打包记录在某一个区块中,当需要调用...
摘要:另外只能做状态变量,不能做本地局部变量。语法声明映射类型包括类型包括状态变量报错。可视度指的是,决定函数或者状态变量的可以被哪些智能合约可见和调用。状态变量可见性没有。在中,通过来抽象出状态变量自增的代码,并修饰。 Mapping 映射(Mappings):类似于哈希表。mapping 中任何一个可能的 key 都对应着一个 value,它的默认值是default-value 。底层用...
摘要:原文发表于以太坊智能合约开发第二篇理解以太坊相关概念很多人都说比特币是区块链,以太坊是区块链。它是以太坊智能合约的运行环境。是由以太坊节点提供。以太坊社区把基于智能合约的应用称为去中心化的应用。 原文发表于:以太坊智能合约开发第二篇:理解以太坊相关概念 很多人都说比特币是区块链1.0,以太坊是区块链2.0。在以太坊平台上,可以开发各种各样的去中心化应用,这些应用构成了以太坊的整个生态...
阅读 1237·2021-10-08 10:05
阅读 4050·2021-09-22 15:54
阅读 3068·2021-08-27 16:18
阅读 3076·2019-08-30 15:55
阅读 1386·2019-08-29 12:54
阅读 2710·2019-08-26 11:42
阅读 509·2019-08-26 11:39
阅读 2068·2019-08-26 10:11