目录

一、前言

二、View函数节省Gas

1、讲解

2、实战

1.要求

2.代码

三、在内存中声明数组

1、讲解

2、实战

1.要求

2.代码


一、前言

看了一些区块链的教程,论文,在网上刚刚找到了一个项目实战,CryptoZombies。

前面我们讲到了Gas,今天我们再来讲一下如何节约Gas。

如果你想了解更多有关于机器学习、深度学习、区块链、计算机视觉等相关技术的内容,想与更多大佬一起沟通,那就扫描下方二维码加入我们吧!

二、View函数节省Gas

1、讲解

玩家从外部调用一个view函数,是不需要支付一分 gas 的。原因如下:

 view 函数不会真正改变区块链上的任何数据 - 它们只是读取。因此用 view 标记一个函数,意味着告诉 web3.js,运行这个函数只需要查询你的本地以太坊节点,而不需要在区块链上创建一个事务(事务需要运行在每个节点上,因此花费 gas)

所以在所能只读的函数上标记上表示“只读”的“external view 声明,就能减少在 DApp 中 gas 用量。

但是我们要注意一种情况:

如果一个 view 函数在另一个函数的内部被调用,而调用函数与 view 函数的不属于同一个合约,也会产生调用成本这是因为如果主调函数在以太坊创建了一个事务,它仍然需要逐个节点去验证。所以标记为 view 的函数只有在外部调用时才是免费的

2、实战

1.要求

我们来写一个”返回某玩家的整个僵尸军团“的函数。当我们从 web3.js 中调用它,即可显示某一玩家的个人资料页。

1.创建一个名为 getZombiesByOwner 的新函数。它有一个名为 _owner 的 address 类型的参数。

2.将其申明为 external view 函数,这样当玩家从 web3.js 中调用它时,不需要花费任何 gas。

3.函数需要返回一个uint []uint数组)。

2.代码

pragma solidity >=0.5.0 <0.6.0;
import "./zombiefeeding.sol";
contract ZombieHelper is ZombieFeeding {modifier aboveLevel(uint _level, uint _zombieId) {require(zombies[_zombieId].level >= _level);_;}function changeName(uint _zombieId, string calldata _newName) external aboveLevel(2, _zombieId) {require(msg.sender == zombieToOwner[_zombieId]);zombies[_zombieId].name = _newName;}function changeDna(uint _zombieId, uint _newDna) external aboveLevel(20, _zombieId) {require(msg.sender == zombieToOwner[_zombieId]);zombies[_zombieId].dna = _newDna;}// Create your function herefunction getZombiesByOwner(address _owner) external view returns(uint[] memory) {}}

三、在内存中声明数组

1、讲解

在之前,我们已经入门了解过函数修饰符。

Solidity 使用storage(存储)是相当昂贵的,”写入“操作尤其贵。这是因为:

无论是写入还是更改一段数据, 这都将永久性地写入区块链。这需要在全球数千个节点的硬盘上存入这些数据,随着区块链的增长,拷贝份数更多,存储量也就越大。这是需要成本的

为了降低成本,不到万不得已,避免将数据写入存储。当然这也会导致效率低下的编程逻辑 - 比如每次调用一个函数,都需要在 memory(内存) 中重建一个数组,而不是简单地将上次计算的数组给存储下来以便快速查找。

在数组后面加上 memory关键字, 表明这个数组是仅仅在内存中创建,不需要写入外部存储,并且在函数调用结束时它就解散了。与在程序结束时把数据保存进 storage 的做法相比,内存运算可以大大节省gas开销 -- 把这数组放在view里用,完全不用花钱

function getArray() external pure returns(uint[]) {// 初始化一个长度为3的内存数组uint[] memory values = new uint[](3);// 赋值values.push(1);values.push(2);values.push(3);// 返回数组return values;
}

在使用过程中要注意:内存数组 必须 用长度参数(在本例中为3)创建。目前不支持 array.push()之类的方法调整数组大小,在未来的版本可能会支持长度修改。

这个也很好理解,比如在C++中,我们如果不用new关键字创建数组,那么数组长度在定义过程中,必须是一个常量。不能是一个变量。

2、实战

1.要求

定义一个修饰符,通过传入的level参数来限制僵尸使用某些特殊功能。

1.声明一个名为resultuint [] memory' (内存变量数组)。

2.将其设置为一个新的 uint 类型数组。数组的长度为该 _owner 所拥有的僵尸数量,这可通过调用 ownerZombieCount [_ owner] 来获取。

3.函数结束,返回 result 。目前它只是个空数列

2.代码

pragma solidity >=0.5.0 <0.6.0;import "./zombiefeeding.sol";contract ZombieHelper is ZombieFeeding {modifier aboveLevel(uint _level, uint _zombieId) {require(zombies[_zombieId].level >= _level);_;}function changeName(uint _zombieId, string calldata _newName) external aboveLevel(2, _zombieId) {require(msg.sender == zombieToOwner[_zombieId]);zombies[_zombieId].name = _newName;}function changeDna(uint _zombieId, uint _newDna) external aboveLevel(20, _zombieId) {require(msg.sender == zombieToOwner[_zombieId]);zombies[_zombieId].dna = _newDna;}function getZombiesByOwner(address _owner) external view returns(uint[] memory) {// Start hereuint[] memory result = new uint[](ownerZombieCount[_owner]);return result;}}

【CryptoZombies - 2 Solidity 进阶】004 使用view和内存中的数组来节约Gas相关推荐

  1. 【C语言进阶】③探究浮点数在内存中的存储方式

    文章目录 一.例题 二.浮点数在内存中存储方式 2.1国际标准IEEE(电气和电子工程协会)754规定: 2.2实际上,浮点数在内存的存储形式为: 2.3具体M和E是怎么算的呢? 三.题解 3.1刚开 ...

  2. C语言进阶——深度剖析数据在内存中的存储

    文章目录 数据类型的介绍 类型的基本归类 整形在内存中的存储 大小端介绍 一道笔试题 浮点数在内存中的存储 浮点数存储规则 剖析题目 数据类型的介绍 在我们之前的学习当中我们已经介绍了基本的内置类型 ...

  3. Android进阶之自定义View实战(二)九宫格手势解锁实现

    一.引言 在上篇博客Android进阶之自定义View实战(一)仿iOS UISwitch控件实现中我们主要介绍了自定义View的最基本的实现方法.作为自定义View的入门篇,仅仅介绍了Canvas的 ...

  4. 【solidity智能合约基础】节约gas的利器--view和pure

    一.知识概览 view和pure的使用方法:view是只有输入没有输出,pure是单纯的输入和输出.调用这两种函数时,均不消耗燃料.而对内存的状态进行改变时,需要消耗燃料.因此我们称view和pure ...

  5. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

    转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己 ...

  6. 《Android进阶之光》--View体系与自定义View

    No1: View的滑动 1)layout()方法的 public class CustomView extends View{private int lastX;private int lastY; ...

  7. 《OpenCV3编程入门》学习笔记5 Core组件进阶(一)访问图像中的像素

    第5章 Core组件进阶 5.1 访问图像中的像素 5.1.1 图像在内存中的存储方式 1.图像矩阵大小取决于通道数,矩阵中的子列个数与通道数相等. 2.如果内存足够大,可以实现连续存储,有助于提升图 ...

  8. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  9. android代码实现手机加速功能,Android自定义View实现内存清理加速球效果

    Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...

最新文章

  1. django前端引用数据_「基于Python技术的智慧中医商业项目」Django前端网站篇-5.资讯的数据交互...
  2. python account_GitHub - Python3WebSpider/AccountPool: Account Pool
  3. 两道递推公式题的解题报告
  4. 让XP恢复文件权限功能
  5. Java计算一段程序的运行时间
  6. ScheduledExecutorService
  7. javaone_JavaOne 2012 – 2400小时! 一些建议
  8. JEECG_3.7 新版本视频正式发布
  9. go语言的struct
  10. 吴恩达机器学习总结一:初识机器学习
  11. 配置RADIUS服务器
  12. 2019年3月PMP考试技巧及答题技巧介绍
  13. 最新最全MTK联发科手机芯片型号及参数汇总
  14. IDEA 运行 Tomcat 中文乱码的各种问题
  15. koa教程--busboy模块
  16. c语言验证费马大定理,数论概论 第四章 高次幂之和与费马大定理 习题解答(宋二娃的BLOG)...
  17. appium 使用sendkeys 设置6位数交易密码时,发现界面显示位数丢失
  18. 【我的新颖社区社交产品架构构思设想】
  19. CodeForces 964A Splits
  20. scratch和python怎么读_Python如何像scratch一样朗读文字?|python3教程|python入门|python教程...

热门文章

  1. 爬取在线全面小说网小说(字体反爬)
  2. 杂记——12.腾讯会议使用OBS虚拟摄像头实现多屏幕共享的解决方法
  3. 在微信小程序中打开地图选择位置功能
  4. pycharm配置sqlite
  5. 大AI巧用「砌砖」方法:LLM可通过将任务「外包」给专业领域的AI模型来提高其性能...
  6. 一起研究ORB-SLAM(二)---Tracking线程
  7. 《数字图像处理》题库5:计算题 ③
  8. 微信小程序年审与支付规则
  9. 云服务器到手必做的安全配置-windows篇
  10. python hashlib_Python hashlib模块实例使用详解