合约动态 智能合约:关于返回动态数组的问题

 网络   2022-11-01 13:51   52

自从智能合约被引入以后,基于智能合约的系统繁复性推广了良多。它节俭单的投票合约、ERC20代币结束,繁华到像Uniswap、Aragon等繁复的架构。

迩来,我住址的Custom App(开垦处事室)在开垦一款Minter Guru dApp,而我在争论系统架媾和智能合约。根据Minter Guru的观念,咱们必需将尽大概多的逻辑转化到智能合约上。

正在完结read(从CRUD模式)函数时,咱们碰到了前往动静巨细数组的课题,该数组大概蕴含数百以至数千个元素。所以,咱们争论了完结此类函数的限度性。

正在本文中,咱们将议论这些限制、处置它们的方式,和“用智能合约完结Web2后端”方式来构建利用法式的可行性。

为了更好地领会,你应该纯熟以太坊区块链根底学识(或一切其他EVM兼容的区块链,如Polygon或BSC),Solidity以及Hardhat。一切对于若何运行它的例子以及阐明的代码均可以正在咱们的GitHub库中找到。

gas限制

咱们的第一个设法是,外貌上,咱们也许到达gas的限度。

正在EVM中,每个函数挪用都须要gas。因为挪用没有会消费真正的gas,因而咱们也许树立一切gas限制,不过因为EVM完结的最大gas限制等于uint64类别的最大值,因而便是18446744073709551615。

让咱们经过一个简捷的合约例子来反省一下完结这个限制的速率。咱们将利用一个简捷的合约uint256[]保存变量,推送n个值到数组函数以及getter方式。其余,咱们须要两个剧本来摆设合约,并测试所需的gas限制。咱们将利用Hardhat算作咱们的要地收集并与合约施行交互。

消费的gas取决于数组的巨细,由于EVM会将数组数据复制到内存中。所以,咱们将争论gas消费以及数组巨细(以字节为单元)之间的依附联系。为了简捷起见,咱们利用uint256[]数组。对付其他数据类别,以字节为单元的编码数组巨细的算计有所分歧。根据Solidity,Enc(uint256[])=Enc(array.size)(Enc(array[0],…,array[array.size-1]))。所以,数组的字节巨细等于size(uint256)+size(uint256)array.size=32+32array.size。

正在运行这个剧本时,咱们看到for轮回的迭代结束变得极度迟缓。第10次迭代花了10秒以上,第50次花了4分钟以上。

根据某些数组巨细预计的gas

预计的gas依附于数组巨细

正在图表中,咱们也许看到预计的gas与数组巨细呈线性联系,因而让咱们建立外推来预计数组的外貌巨细。咱们一经利用谷歌电子表格以及线性返回告竣了它。

预计gas外推

也许看到,外貌上的uint256数组尺寸限制约莫等于1.8e+17千字节(163709千字节),这理论上是没法完结的。个中施行时光便是一个大课题。

合约动态 智能合约:关于返回动态数组的问题

施行时光

开始,咱们要提到的是,咱们在用Node.js完结的Hardhat收集施行测试,因而它的机能会比正在以太坊节点中利用的Golang完结要差。不过,与EVM完结语言比拟,EVM的妄图对于智能合约功能的完结作用更大。

施行测试的呆板参数:

CPU - 11代Intel®Core™i7-1165G7 @ 2.80GHz × 8

Ram - 16GB

操作系统- Ubuntu 22.04 LTS

磁盘 - 512gb SSD

而今改动咱们的测试剧本来测量施行时光。咱们只须要改革测试剧本中的for轮回来纪录施行时光。上面是代码:

而今咱们也许看到,高施行时光的课题很快就呈现了。对付320 KB的数据,12秒的施行时光太长了,因而时光成为咱们须要克服的主要课题。

分页

没有一种奇异的方式也许正在正当的时光内取得大的数组。不过,假设你的利用法式正在某临时刻没有须要齐全的数组,你也许像正在Web2中那样利用分页模式。然而,假设是这样,则说明生存架构课题,这是智能合约系统或典范Web2利用法式没法束缚的。

分页常常被开垦人员用来限制一个API挪用中前往数据的巨细。这种方式削减了迟延,也削减了为欣赏器以及迁徙利用法式消失的UI元素的数目。

分页的完结席卷以下方法:

正在数组上定义排序

将页码以及页面巨细推广到API方式(本例中的合约函数)。你的新方式应该前往数组的一全体:array[pagesize:min((page+1)size, array.length)]

将数组中元素的总额量推广到反映中,就也许正在客户端上找到页面数目。

而今改动咱们的测试智能合约,以下图所示:

测试剧本。咱们还将节流每个猎取页面挪用的施行时光,以说明它对于一切页面维持没有变。这是代码:

让咱们看看了局。异样,齐全的了局也许正在咱们的保存库中找到。其余,为了削减表的巨细,咱们将只再现get页面挪用的平衡以及最大施行时光:

按页猎取数组的施行时光

因而而今咱们也许正在正当的时光内失去数组的一全体。

最终一个细节:假设想要遍历也许频仍改动状态的数组,也许正在挪用函数时利用流动的区块号。这保险了状态正在每一页挪用中都维持没有变。利用Hardhat合约绑定,也许这样做:

结论

因而,有两个重点:

前往大数组的函数的主要课题是挪用施行时光。

经过分页,咱们也许使挪用时光变得正当,并也许猎取全体数据。假设利用法式的for逻辑也许同时处置数组的一全体,就也许利用该模式。

咱们一经用最简捷的getter逻辑告竣了一切的测试,不过正在你的利用法式中,getter逻辑大概要繁复很多,所以正在妄图架构时,应该严慎地将一切实质转化到智能合约。

正在摆设到主网后,你大概会碰到没法束缚的课题(假设你的合约弗成进级)。假设你感慨你的系统太繁复,没法将其全数放入智能合约中,那么将智能合约与典范的Web2束缚规划相贯串将是理智的挑选。

Source:https://medium.com/better-programming/issues-of-returning-arrays-of-dynamic-size-in-solidity-smart-contracts-dd1e54424235

对于

ChinaDeFi- ChinaDeFi.com 是一个争论启动的DeFi改革构造,同时咱们也是区块链开垦团队。每天从寰球逾越500个优质信息源的近900篇实质中,追寻思虑更具深度、梳理更为系统的实质,以最快的速率同步到中国墟市供给决议协助质料。

Layer 2道友- 接待对于Layer 2感趣味的区块链本领癖好者、争论分解人与Gavin(微信: chinadefi)关连,独特琢磨Layer 2带来的落地机遇。敬请存眷咱们的微信大众号“去焦点化金融社区”。

本文地址:http://yz.ziyouea.com/p/52432.html
版权声明:本站文章来自网络,如有违规侵权请联系我们下架。