英文:
How can I test gas usage in a Solidity smart contract with an array of 1 million items using a testing library?
问题
我需要测试,在智能合约中对包含1,000,000项的数组使用二分查找将会使用多少气体。是否可以使用任何测试库或框架来进行测试?我已经尝试了Hardhat,但它对于填充数组来说太慢了。我不确定Forge/Foundry,但是否有任何测试这个功能的方法?
我已经尝试使用Hardhat来填充数组,直接调用智能合约,但速度太慢了。找到一种测试这个功能的方法将会很好。
真实情况是:
这些项将逐步推送,每一步都是一个不同的交易,当达到1,000,000项时,它会找到一个特定的项。
英文:
I need to test, how much gas will be used to use binary search on array of 1,000,000 items in a smart contract. Is it possible to do that using any testing library or framework. I have used hardhat, which is too slow for populating the array. I am not sure about forge/foundry, but is there any way of testing that?
I have tried to populate the array with hardhat,
directly making calls to smart contract , but it is too slow. It would be nice to find some way of testing that functionality.
The real case is:
The items will be pushed step by step, each step is a different transaction, and when it reaches to 1,000,000 , it find one specific item.
答案1
得分: 1
Sure, here are the translated parts:
(1) 附加批量添加功能:
在您的智能合同中添加一个新功能,允许您批量添加项目。例如,每次添加50个或更多,具体取决于您需要发送的参数大小和燃气限制。
仅在测试目的中使用此功能,并确保在部署之前删除该功能(如果确实是您的用例)。
这种方法将帮助您在较少的交易中填充所需的100万个项目。
但只要您的批量添加功能的工作方式与逐个添加功能在智能合同存储中的持久性方式相兼容,您的后续搜索功能将给出相同的燃气估算。
(2) 现有部署+ Hardhat分叉
如果您已经在实际数据中部署了这个智能合同,拥有100万个对象的真实数据,您可以跳过填充步骤,只需连接到已部署的智能合同。
但是,您将需要使用Hardhat的网络分叉功能,
结合hardhat-ethers
的getImpersonatedSigner()
功能,
以便能够对其进行任何(有意义的)测试。
这是如何工作的:HardhatVM(这是一个模拟的EVM实现,完全在localhost
上运行,因此非常快)
被告知在特定块号(类似于网络的临时分叉)下复制特定EVM网络的状态。
使用这种方法,您将能够对目标智能合同编写测试,当然,假设数据布局和访问与您的方法兼容。
(3) 在测试时设置块燃气限制
如OP在评论中提到,
对于测试VM,您可以设置块燃气限制的任何值。
例如,对于配置HardhatVM,可以使用networks.hardhat.blockGasLimit
:
{
// ...
networks: {
hardhat: {
blockGasLimit: 1000000000
},
}
// ...
}
这可以用于在初始设置阶段设置更高的津贴。
英文:
If you add some sample code to your question,
that might help get you a more specific answer.
Right now, I can give you more general advice.
(1) Additional batch-add function:
Add a new function to your smart contract that allows you to add items in batches. E.g. 50 or more at a time, depending on the size of the parameters you need to send in and gas limits.
Use this only for testing purposes, and ensure that the function is removed before deployment if that is indeed your use case.
This approach will help you populate the required 1 million items in a fewer number of transactions.
However, as long as the way your batch addition function works is compatible with your one-at-a-time addition function in terms of how it is persisted in smart contract storage, your subsequent search function will give you the same gas estimate.
(2) Existing deployment + hardhat forking
If you already have this smart contract deployed in the wild with real data of 1 million objects, you can may be able to skip the population step, and just connect to the already-deployed smart contract.
However, you will need to use Hardhat's network forking feature,
in combination with hardhat-ethers
's getImpersonatedSigner()
function
in order to be able to write any (meaningful) tests against it.
How this works is that HardhatVM (which is a simulated EVM implementation, that runs 100% on localhost
, and therefore very fast)
is told to replicate the state of a particular EVM network at a specific block number (similar to a temporary fork of the network).
Using this approach, you'll be able to write your tests against the target smart contract, of course, assuming that data layout and access is compatible with your approach.
(3) Set the block gas limit when testing
As mentioned by the OP in comments,
for test VMs you can set any value for the block gas limit.
For example networks.hardhat.blockGasLimit
to configure HardhatVM
{
// ...
networks: {
hardhat: {
blockGasLimit: 1000000000
},
}
// ...
}
This can be used to set a higher allowance in the initial set up phase.
答案2
得分: 0
你可以使用 web3 Python 库。试试以下代码:
web3.eth.estimate_gas(transaction)
英文:
You can use the web3 python library.
Try using:
web3.eth.estimate_gas(transaction)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论