首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >契约互动

契约互动
EN

Ethereum用户
提问于 2018-06-21 11:50:46
回答 3查看 171关注 0票数 0

假设我们有一个契约,它实现了一个可靠的优先级队列,如下所示:

代码语言:javascript
复制
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..
}
}

另一份使用此合同的合同:

代码语言:javascript
复制
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时在引擎盖下发生了什么,我将不胜感激。

EN

回答 3

Ethereum用户

回答已采纳

发布于 2018-06-21 13:00:14

不改变任何状态的函数不消耗气体,除非它们是从合同中调用的。这是正确的原因是,如果一个函数不改变状态,您可以在节点中执行它,而不需要实际执行事务,但事实并非如此,因为如果实现引用的名称可能会更改状态,则test正在调用insert will。

对于行PQ memory pq,这将引发一个可靠的错误,您应该执行PQ pq --这定义了一个可以用来访问PQ方法的对象。

希望这能有所帮助

票数 1
EN

Ethereum用户

发布于 2018-06-21 12:55:23

test打电话给PQ.insert。您的问题的答案取决于insert的实现。如果如其名称所示,它在队列中插入一个Node,则状态将发生更改。这意味着,test将不得不在一次超车中被调用,这需要花费天然气。

票数 1
EN

Ethereum用户

发布于 2018-06-21 12:56:13

不,test函数会花费你的汽油。只有读取操作不需要任何气体,其理由是任何节点都可以在其存储部分查找它。在test中,运行一个循环,然后pq.inserti插入到heapKeyValue变量中。这确实花了你的油。

至于PQ memory pq,让我们阅读一下坚实的文档:(更多信息这里)

Ethereum虚拟机有三个可以存储项目的区域。第一个是“存储”,所有的契约状态变量都驻留在其中。每个契约都有自己的存储空间,并且在函数调用之间是持久的,使用起来非常昂贵。第二个是“内存”,这是用来保存临时值的。它在(外部)函数调用之间被擦除,使用起来更便宜。

在默认情况下,局部变量从“存储”中引用,使用关键字"memory“将它们置于”内存“的上下文中,即廉价的临时存储。

票数 1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/51760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档