热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【CryptoZombies2Solidity进阶】004使用view和内存中的数组来节约Gas

目录一、前言二、View函数节省Gas1、讲解2、实战1.要求2.代码三、在内存中声明数组1、讲解2、实战1.要求2.代码一、前言看了一些区块链的教程&#x

目录

一、前言

二、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 >&#61;0.5.0 <0.6.0;
import "./zombiefeeding.sol";
contract ZombieHelper is ZombieFeeding {modifier aboveLevel(uint _level, uint _zombieId) {require(zombies[_zombieId].level >&#61; _level);_;}function changeName(uint _zombieId, string calldata _newName) external aboveLevel(2, _zombieId) {require(msg.sender &#61;&#61; zombieToOwner[_zombieId]);zombies[_zombieId].name &#61; _newName;}function changeDna(uint _zombieId, uint _newDna) external aboveLevel(20, _zombieId) {require(msg.sender &#61;&#61; zombieToOwner[_zombieId]);zombies[_zombieId].dna &#61; _newDna;}// Create your function herefunction getZombiesByOwner(address _owner) external view returns(uint[] memory) {}}

三、在内存中声明数组

1、讲解

在之前&#xff0c;我们已经入门了解过函数修饰符。

Solidity 使用storage(存储)是相当昂贵的&#xff0c;”写入“操作尤其贵。这是因为&#xff1a;

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

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

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

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

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

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

 

2、实战


1.要求

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

1.声明一个名为resultuint [] memory&#39; &#xff08;内存变量数组&#xff09;。

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

3.函数结束&#xff0c;返回 result 。目前它只是个空数列


2.代码

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

 

 


推荐阅读
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 2022年的风口:你看不起的行业,真的很挣钱!
    本文介绍了2022年的风口,探讨了一份稳定的副业收入对于普通人增加收入的重要性,以及如何抓住风口来实现赚钱的目标。文章指出,拼命工作并不一定能让人有钱,而是需要顺应时代的方向。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
author-avatar
手机用户2602917233
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有