热门标签 | 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;}}

 

 


推荐阅读
  • 自然语言处理(NLP)——LDA模型:对电商购物评论进行情感分析
    目录一、2020数学建模美赛C题简介需求评价内容提供数据二、解题思路三、LDA简介四、代码实现1.数据预处理1.1剔除无用信息1.1.1剔除掉不需要的列1.1.2找出无效评论并剔除 ... [详细]
  • 本文探讨了异步编程的发展历程,从最初的AJAX异步回调到现代的Promise、Generator+Co以及Async/Await等技术。文章详细分析了Promise的工作原理及其源码实现,帮助开发者更好地理解和使用这一重要工具。 ... [详细]
  • Vue CLI 基础入门指南
    本文详细介绍了 Vue CLI 的基础使用方法,包括环境搭建、项目创建、常见配置及路由管理等内容,适合初学者快速掌握 Vue 开发环境。 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • 本文介绍了.hbs文件作为Ember.js项目中的视图层,类似于HTML文件的功能,并详细讲解了如何在Ember.js应用中集成Bootstrap框架及其相关组件的方法。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 机器学习实践:逻辑回归与过拟合控制
    本文深入探讨了逻辑回归在机器学习中的应用,并详细解释了如何通过正则化等方法来有效避免模型的过拟合问题。 ... [详细]
  • 机器学习(ML)三之多层感知机
    深度学习主要关注多层模型,现在以多层感知机(multilayerperceptron,MLP)为例,介绍多层神经网络的概念。隐藏层多层感知机在单层神经网络的基础上引入了一到多个隐藏 ... [详细]
  • 探讨了在HTML表单中使用元素代替进行表单提交的方法。 ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • ASP.NET 进度条实现详解
    本文介绍了如何在ASP.NET中使用HTML和JavaScript创建一个动态更新的进度条,并通过Default.aspx页面进行展示。 ... [详细]
  • 本文探讨了使用普通生成函数和指数生成函数解决组合与排列问题的方法,特别是在处理特定路径计数问题时的应用。文章通过详细分析和代码实现,展示了如何高效地计算在给定条件下不相邻相同元素的排列数量。 ... [详细]
  • 本文探讨了如何利用RxJS库在AngularJS应用中实现对用户单击和拖动操作的精确区分,特别是在调整区域大小的场景下。 ... [详细]
  • 计算机学报精选论文概览(2020-2022)
    本文汇总了2020年至2022年间《计算机学报》上发表的若干重要论文,旨在为即将投稿的研究者提供参考。 ... [详细]
  • 本文介绍了如何使用 Google Colab 的免费 GPU 资源进行深度学习应用开发。Google Colab 是一个无需配置即可使用的云端 Jupyter 笔记本环境,支持多种深度学习框架,并且提供免费的 GPU 计算资源。 ... [详细]
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社区 版权所有