假设我们有一个契约,它实现了一个可靠的优先级队列,如下所示:
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract PQ {
struct Node {
int256 key;
address value;
}
Node[7] private heapKeyValue;
function insert(int256 key, address addr) public {
.. Implementation ..
}
function get_min() public view returns (int256) {
return heapKeyValue[0].key;
}
function heapify(uint8 idx) internal {
..Implementation..
}
}另一份使用此合同的合同:
contract test_pq {
function test() public returns (int256){
PQ memory pq;
for (uint8 i = 0; i < 10; i++)
pq.insert(i)
return pq.get_min();
}
}那么,在test_pq合同中调用test()函数的燃气成本是多少?直觉上,我认为它的功能状态不会改变任何状态,因此它应该是零气体成本。是这种情况吗?
此外,如果有人能向我解释执行行PQ memory pq时在引擎盖下发生了什么,我将不胜感激。
发布于 2018-06-21 13:00:14
不改变任何状态的函数不消耗气体,除非它们是从合同中调用的。这是正确的原因是,如果一个函数不改变状态,您可以在节点中执行它,而不需要实际执行事务,但事实并非如此,因为如果实现引用的名称可能会更改状态,则test正在调用insert will。
对于行PQ memory pq,这将引发一个可靠的错误,您应该执行PQ pq --这定义了一个可以用来访问PQ方法的对象。
希望这能有所帮助
发布于 2018-06-21 12:55:23
test打电话给PQ.insert。您的问题的答案取决于insert的实现。如果如其名称所示,它在队列中插入一个Node,则状态将发生更改。这意味着,test将不得不在一次超车中被调用,这需要花费天然气。
发布于 2018-06-21 12:56:13
不,test函数会花费你的汽油。只有读取操作不需要任何气体,其理由是任何节点都可以在其存储部分查找它。在test中,运行一个循环,然后pq.insert将i插入到heapKeyValue变量中。这确实花了你的油。
至于PQ memory pq,让我们阅读一下坚实的文档:(更多信息这里)
Ethereum虚拟机有三个可以存储项目的区域。第一个是“存储”,所有的契约状态变量都驻留在其中。每个契约都有自己的存储空间,并且在函数调用之间是持久的,使用起来非常昂贵。第二个是“内存”,这是用来保存临时值的。它在(外部)函数调用之间被擦除,使用起来更便宜。
在默认情况下,局部变量从“存储”中引用,使用关键字"memory“将它们置于”内存“的上下文中,即廉价的临时存储。
https://ethereum.stackexchange.com/questions/51760
复制相似问题