您现在的位置是:主页 > news > 模板网站开发营销/软件开发app制作公司

模板网站开发营销/软件开发app制作公司

admin2025/6/7 19:29:25news

简介模板网站开发营销,软件开发app制作公司,网站开发工程师是做什么的,郑州做网站好的公目录 一、前言 二、For循环 1、引入 2、For循环 3、实战 1.要求 2.代码 一、前言 看了一些区块链的教程,论文,在网上刚刚找到了一个项目实战,CryptoZombies。 前面我们讲到了Gas,今天我们再来讲一下如何节约Gas。 如果你…

模板网站开发营销,软件开发app制作公司,网站开发工程师是做什么的,郑州做网站好的公目录 一、前言 二、For循环 1、引入 2、For循环 3、实战 1.要求 2.代码 一、前言 看了一些区块链的教程,论文,在网上刚刚找到了一个项目实战,CryptoZombies。 前面我们讲到了Gas,今天我们再来讲一下如何节约Gas。 如果你…

目录

一、前言

二、For循环

1、引入

2、For循环

3、实战

1.要求

2.代码


一、前言

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

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

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

二、For循环

1、引入

为了实现 getZombiesByOwner 函数,一种解决方案是在 ZombieFactory 中存入”主人“和”僵尸军团“的映射。

mapping (address => uint[]) public ownerToZombies

然后每次创建新的僵尸的时候,就需要执行ownerToZombies [owner] .push(zombieId) 将其添加到主人的僵尸数组中。而 getZombiesByOwner 函数也非常简单:

function getZombiesByOwner(address _owner) external view returns (uint[]) {return ownerToZombies[_owner];
}

这种做法确实很简单,很直接,但是它存在问题:

如果我们需要一个函数来把一头僵尸转移到另一个主人名下(我们一定会在后面的课程中实现的),又会发生什么?

这次更换主人的操作需要实现:

1.将僵尸push到新主人的 ownerToZombies 数组中。

2.从旧主的 ownerToZombies 数组中移除僵尸。

3.将旧主僵尸数组中“换主僵尸”之后的的每头僵尸都往前挪一位,把挪走“换主僵尸”后留下的“空槽”填上。

4.将数组长度减1。

但是第三步实在是太贵了!因为每挪动一头僵尸,我们都要执行一次写操作。如果一个主人有20头僵尸,而第一头被挪走了,那为了保持数组的顺序,我们得做19个写操作。由于写入存储是 Solidity 中最费 gas 的操作之一,使得换主函数的每次调用都非常昂贵。更糟糕的是,每次调用的时候花费的 gas 都不同!具体还取决于用户在原主军团中的僵尸头数,以及移走的僵尸所在的位置。以至于用户都不知道应该支付多少 gas。

有人说,我们也可以把数组中最后一个僵尸往前挪来填补空槽,并将数组长度减少一。但这样每做一笔交易,都会改变僵尸军团的秩序。

由于从外部调用一个 view 函数是免费的,我们也可以在 getZombiesByOwner 函数中用一个for循环遍历整个僵尸数组,把属于某个主人的僵尸挑出来构建出僵尸数组。那么我们的 transfer 函数将会便宜得多,因为我们不需要挪动存储里的僵尸数组重新排序,总体上这个方法会更便宜,虽然有点反直觉。

2、For循环

为了实现上面的功能,我们要用到for循环。for循环对于大家来说,如果学过其他编程语言,就相当熟悉了。

我们看一个简单的示例:

function getEvens() pure external returns(uint[]) {uint[] memory evens = new uint[](5);// 在新数组中记录序列号uint counter = 0;// 在循环从1迭代到10:for (uint i = 1; i <= 10; i++) {// 如果 `i` 是偶数...if (i % 2 == 0) {// 把它加入偶数数组evens[counter] = i;//索引加一, 指向下一个空的‘even’counter++;}}return evens;
}

这个函数将返回一个形为 [2,4,6,8,10] 的数组。

3、实战

1.要求

我们在 getZombiesByOwner 函数中通过一条 for 循环来遍历 DApp 中所有的僵尸, 将给定的‘用户id'与每头僵尸的‘主人’进行比较,并在函数返回之前将它们推送到我们的result 数组中。

1.声明一个变量 counter,属性为 uint,设其值为 0 。我们用这个变量作为 result 数组的索引。

2.声明一个 for 循环, 从 uint i = 0 到 i <zombies.length。它将遍历数组中的每一头僵尸。

3.在每一轮 for 循环中,用一个 if 语句来检查 zombieToOwner [i] 是否等于 _owner。这会比较两个地址是否匹配。

4.在 if 语句中:

  (1)通过将 result [counter] 设置为 i,将僵尸ID添加到 result 数组中。

  (2)将counter加1。

这样 - 这个函数能返回 _owner 所拥有的僵尸数组,不花一分钱 gas。

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) {uint[] memory result = new uint[](ownerZombieCount[_owner]);// Start hereuint counter = 0;for(uint i = 0; i < zombies.length; i++) {if(zombieToOwner[i] == _owner) {result[counter] = i;counter++;}}return result;}}