前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Gas 优化:Solidity 中的使用动态值数组

Gas 优化:Solidity 中的使用动态值数组

作者头像
Tiny熊
发布于 2021-12-13 06:39:49
发布于 2021-12-13 06:39:49
4K00
代码可运行
举报
运行总次数:0
代码可运行
  • 译文出自:登链翻译计划[1]
  • 译者:aisiji[2]
  • 校对:Tiny 熊[3]

在 Solidity 中,动态值数组是否比引用数组效率更高吗?

Photo by Nick Kwan[4] on Unsplash[5]

背景

在 Datona 实验室的 Solidity 智能数据访问合约(S-DAC)模板的开发和测试过程中,我们经常需要处理一些像用户ID这样数据小但未知长度的数据。理想情况下,这些数据存储在一个小数值的动态值数组中。

在这篇文章的例子中,我们研究了在 Solidity 中使用动态值数组是否比引用数组或类似解决方案在处理这些小数值时更高效。

讨论

当我们有一个由已知的小数值的小数组(长度小)组成的数据时,我们可以在 Solidity 中使用一个数值数组(Value Arrays),在这篇文章[6]中,我们提供并测量了 Solidity 数值数组。得出的结论是,在多数情况下使用数值数组都可以减少存储空间和gas消耗。

得出这个结论是因为Solidity在以太坊虚拟机(EVM)上运行时有 非常大的256位(32字节)机器字长[7]。基于这个特点,再加上处理引用数组时的高gas消耗,让我们考虑使用数值数组。

既然我们可以为固定值数组操作提供自己的库,同样是否也适用于动态值数组呢?

让我们比较一下动态值数组与固定长度值数组以及 Solidity 自己的固定长度数组和动态数组。

我们也将比较两个结构体,一个结构体包含一个数组长度和一个固定数组,另一个结构体包含一个数值数组。

可能的动态值数组

在 Solidity 中,只有 storage 类型有动态数组。memory 类型的数组必须有固定长度,并且不允许使用push()来附加元素。

我们以 Solidity 库形式为动态值数组提供代码,我们能提供push()(和pop())同时用于 storagememory 数组。

动态值数组需要记录并操作数组的当前长度。在下面的代码中,我们将数组长度在存储在256位(32字节)机器码值的最高位。

动态值数组

下面是一些与 Solidity 可用类型匹配的动态值数组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Dynamic Value Arrays(动态值数组)

Type           Type Name   Description

uint128[](1 "")   uint128d1   one 128bit element value
uint64[](3 "")    uint64d3    three 64bit element values
uint32[](7 "")    uint32d7    seven 32bit element values
uint16[](15 "")   uint16d15   fifteen 16bit element values
uint8[](31 "")    uint8d31    thirty-one 8bit element values

上述我提出的类型名称,它们在会本文中使用,但你可能会有一个更好的命名方式。

下面我们将详细地研究uint8d31

更多动态值数组

很明显,有更多可能的数值数组。假设我们保留最高位的256位来存最大的动态数组长度,X(位数的值)乘以Y(元素个数)必须小于或者等于256减去容纳数组长度的位数(L):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
More Dynamic Value Arrays

Type           Type Name  Len  Description

uintX[](Y "")     uintXdY     L   X * Y <= 256 - L
uint255[](1 "")   uint255d1   1   one 248bit element value
uint126[](2 "")   uint126a2   2   two 124bit element values
uint84[](3 "")    uint84d3    2   three 82bit element values
uint63[](4 "")    uint63d4    3   four 62bit element values
uint50[](5 "")    uint50d5    3   five 51bit element values
uint42[](6 "")    uint42d6    3   six 42bit element values
uint36[](7 "")    uint36d7    3   seven 36bit element values
uint31[](8 "")    uint31d8    4   eight 31bit element values
uint28[](9 "")    uint28d9    4   nine 28bit element values
uint25[](10 "")   uint25d10   4   ten 25bit element values
uint22[](11 "")   uint22d11   4   eleven 22bit element values
uint21[](12 "")   uint21d12   4   twelve 21bit element values
uint19[](13 "")   uint19d13   4   thirteen 19bit element values
uint18[](14 "")   uint18d14   4   fourteen 18bit element values
uint16[](15 "")   uint16d15   4   as above
uint15[](16 "")   uint15d16   5   sixteen 15bit element values
uint14[](17 "")   uint14d17   5   seventeen 14bit element values
uint13[](19 "")   uint13d19   5   nineteen 13bit element values
uint12[](20 "")   uint12d20   5   twenty 12bit element values
uint11[](22 "")   uint11d22   5   twenty-two 11bit element values
uint10[](25 "")   uint10d25   5   twenty-five 10bit element values
uint9[](27 "")    uint9d27    5   twenty-seven 9bit element values
uint8[](31 "")    uint8d31    5   as above
uint7[](35 "")    uint7d35    6   thirty-five 7bit element values
uint6[](41 "")    uint6d41    6   forty-one 6bit element values
uint5[](50 "")    uint5d50    6   fifty 5bit element values
uint4[](62 "")    uint4d62    6   sixty-two 4bit element values
uint3[](83 "")    uint3d83    7   eighty-three 3bit element values
uint2[](124 "")   uint2d124   7   one-hundred & twenty-four 2bit EVs
uint1[](248 "")   uint1d248   8   two-hundred & forty-eight 1bit EVs

不同的项目需要特定的数组类型,并且同一个项目可能需要多种数组类型。例如,uint8d31用于用户ID,uint5d50用于用户角色。

注意uint1d248数值数组。它让我们可以有效地将多达248个1位的元素(代表布尔值)编码到1个 EVM 字中。而Solidity相同作用的 bool[248] ,在内存中消耗多 248 倍的空间,在存储(storage)中则多8倍。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
在 Solidity中使用值数组以降低 gas 消耗
我们Datona Labs在开发和测试Solidity数据访问合约(S-DAC:Smart-Data-Access-Contract)模板过程中,经常需要使用只有很小数值的小数组(数组元素个数少)。在本示例中,研究了使用值数组(Value Array)是否比引用数组(Reference Array)更高效。
Tiny熊
2020/08/27
2K0
在 Solidity中使用值数组以降低 gas 消耗
solidity定长数组和动态数组
其中第二种情况未声明数组内容时,可通过直接通过push向数组中添加值,或初始化一个数组然后再赋值。
程序新视界
2019/08/14
2.8K0
智能合约语言 Solidity 教程系列5 - 数组介绍
Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么
Tiny熊
2018/07/23
8700
智能合约语言 Solidity 教程系列5 - 数组介绍
如何在 Solidity 中对数组进行去重
Solidity 是一种面向以太坊平台的智能合约编程语言,具有类似 JavaScript 和 C++ 的语法结构。它是专门为在区块链上编写自执行合约而设计的,支持复杂的业务逻辑和去中心化应用(dApps)的开发。随着区块链技术的快速发展,Solidity 已成为构建去中心化金融(DeFi)、NFT 市场以及其他区块链应用的首选语言(其实主要是以太坊用户多罢了)。
天地一小儒
2024/08/29
4780
六、数组及其操作《2022 solidity8.+ 版本教程到实战》
在 solidity 中,数组分为定长数组和动态数据,这两者的定义上跟 golang 很相似;其定长数组在创建好后不能设置超过数组长度的值,也就是不能push;而动态数组允许 push,还有一点很有意思的是,在删除数组某个元素后,删除的数组中的某个位置的值是还原成了当前类型数组的类型默认值。
1_bit
2022/10/04
3240
Solidity:常用数据结构
在 Solidity 中,有各种各样的数据结构可用于组织和处理信息。以下是一些最常用的数据结构。
孟斯特
2024/05/28
1660
Solidity:常用数据结构
[译]在Solidity中如何优化Gas第一部分:变量
Gas优化是开发以太坊智能合约所面临的一个独特挑战。要想成功,我们需要学习solidity如何在幕后处理变量和函数。
Tiny熊
2020/09/29
1K0
跟我学 Solidity :引用变量
欢迎阅读跟我学习 Solidity系列中的另一篇文章。在上一篇文章[4],中,我们了解了数据位置的工作方式以及何时可以使用以下三个位置:memory,storage和calldata。
Tiny熊
2020/12/15
1.8K0
2025-01-16:执行操作可获得的最大总奖励Ⅱ。用go语言,给定一个整数数组 rewardValues,长度为 n,表示奖励
2025-01-16:执行操作可获得的最大总奖励Ⅱ。用go语言,给定一个整数数组 rewardValues,长度为 n,表示奖励的数值。
福大大架构师每日一题
2025/01/16
880
2025-01-16:执行操作可获得的最大总奖励Ⅱ。用go语言,给定一个整数数组 rewardValues,长度为 n,表示奖励
快速学习-Solidity 深入理解
函数的值类型有两类:- 内部(internal)函数和 外部(external) 函数
cwl_java
2020/04/16
1.3K0
合约私有数据泄漏的安全问题分析及演示
每个智能合约都有自己的存储来反映合约的状态,这些存储都与智能合约的地址进行绑定。在不同的函数调用中,这些存储中的值都是保持不变的。
Tiny熊
2022/11/07
6050
合约私有数据泄漏的安全问题分析及演示
Solidity 智能合约开发 - 基础:基础语法 基础数据类型、以及用法和示例
用于标识一个函数不会修改合约的状态,即它只能读取数据而不能修改数据。这意味着在调用视图函数时,不会产生任何交易费用,并且不会改变合约的状态。例如:
苏泽
2024/03/16
3580
第三十课 以太坊智能合约solidity如何节省GAS费?
在以太坊上,代码即法律,交易即金钱。每一笔智能合约的运行,都要根据复杂度消耗一笔GAS费(ETH)。那么,智能合约solidity语言的编写,不仅要考虑安全,也要考虑语言的优化,以便高效便宜了。 本文将从以下一些方面分析如何节约GAS的编程总结: 1)如何在REMIX编译器上分析GAS/GAS LIMIT等信息 2) 如何优化节省GAS费用的方法
辉哥
2018/11/26
5K0
第三十课 以太坊智能合约solidity如何节省GAS费?
智能合约gas评估与优化方法小结
以太坊上存储256 bit数据大约消耗20k Gas、如此换算,仅1 GB存储资源要花费32,000ETH,大约要花费超过1亿美元。且不说当前身为贵族链Gas费很有可能继续水涨船高,放在早些年其Gas消耗也不是一笔小数目。因此,以太坊Gas优化是Dapp开发一直难绕的问题,也是Solidity开发者的必备技能。
davy the bot
2024/04/08
1K0
Solidity语法详解 - 类型介绍1
现在的Solidity中文文档,要么翻译的太烂,要么太旧,决定重新翻译下。 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 Solidity教程会是一系列文章,本文是第一篇:介绍Solidity的变量类型。 本文前半部分是参考Solidity官方文档(当前最新版本:0.4.20)进行翻译,后半部分是结合实际合约代码实例说明类型的使用(仅针对专栏订阅用户)。 类型 Solidity是一种静态类型语言,意味着每个变量(
Tiny熊
2018/06/21
1.6K0
Solidity 简易教程
Solidity 的代码都包裹在合约里面. 一份合约就是以太应币应用的基本模块, 所有的变量和函数都属于一份合约, 它是你所有应用的起点.
goodspeed
2020/12/22
6600
逆向 EVM - 解析原始Calldata数据
你可能想知道如何破译和读取 evm 的 calldata,然后试图读取以太坊智能合约的交易 calldata,EVM(和其他 L1 分叉)以特定的方式对静态和动态类型的 calldata 进行编码和解码,在某种程度上让数据变得很困惑,起码最初是这样的。
Tiny熊
2023/01/09
1.6K0
逆向 EVM - 解析原始Calldata数据
变量覆盖概述
在智能合约语言 Solidity当中,存在Storage(存储器)和Memory(内存)两个不同的概念,Storage变量是指永久存储在区块链中的变量,Memory变量是临时的,这些变量在外部调用结束后会被移除。
Al1ex
2021/07/21
1K0
变量覆盖概述
solidity开发3-类型1
M的取值范围为8的倍数且为:[8, 256], N的取值范围为:[0, 80]。 fixed/ufixed:则是fixed128x18/ufixed128x18
SecondWorld
2022/05/06
4160
智能合约:solidity语法(一)
在 solidity 里面 uint 默认表示 uint256,其他的还有 uint8、uint16、uint32...
yichen
2020/05/20
1.4K0
相关推荐
在 Solidity中使用值数组以降低 gas 消耗
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验