【问题标题】:Must all nodes on the blockchain execute every smart contract function cal?区块链上的所有节点都必须执行每个智能合约功能吗?
【发布时间】:2021-08-27 23:51:56
【问题描述】:

我理解为什么以太坊主网上的所有节点都必须执行任何更改合约或链内部状态的智能合约函数调用很重要。 (例如,从一个帐户转移到另一个 ec。)

我想知道的是,如果每个节点都必须执行在任何智能合约上调用的每个函数,即使该函数不会导致状态更改。

例如,如果 ERC721 智能合约有一个函数“getName()”,它只返回 NFT 所代表的艺术品的名称,该名称存储在 NFt 中。假设 joe 连接到网络,并希望在合约上执行 getName()。这是否意味着所有 9,000 个节点最终都会执行 getName(),即使 Joe 只需要执行一次?运行“getName()”的 gas 成本是否补偿了每个节点运行“getName()”的开销?如果这是真的(每个节点都得到报酬),随着更多节点加入池,gas 会变得更加昂贵吗?

gas 价格高的原因之一是因为每个节点必须执行智能合约上调用的每个函数的效率低下,即使是那些对状态没有影响的函数?

如果是这样,在以太坊上执行计算密集但“纯”(无副作用)的功能似乎是一个非常(并且可能是不必要的)昂贵的提议,对吧?

谢谢。为可能幼稚的问题道歉!

【问题讨论】:

    标签: ethereum solidity


    【解决方案1】:

    transaction(可以进行状态更改 - 但不需要)和call(只读,不能进行状态更改)之间存在区别。


    我将从通话开始,因为它更容易。

    当节点执行调用时,它会执行最有可能从存储读取、存储到内存并从内存返回的合约函数。

    例子:

    string name;
    
    function getName() external view returns (string memory) {
        // reads from storage, stores to memory, returns from memory
        return name;
    }
    

    但它不会向其他节点广播任何信息(例如“我刚刚执行了读取操作”)。 IE。其他节点不执行相同的操作。


    一个事务在每个节点上执行一次。

    string name;
    
    function setName(string memory _name) external {
        // reads from memory, stores to storage
        name = _name;
    }
    

    矿工从内存池(等待挖掘的交易列表)中获取交易,在他们的机器上执行它,执行状态更改,并将交易添加到块中(包括预期的状态更改)。

    所有(验证者)节点然后下载新块,执行交易,并在其末端执行相同的状态更改。如果他们发现自己的状态更改与矿工声明的状态更改之间不匹配,他们会将其广播到网络中,并声明一个可能的无效块。


    回答您的问题:

    这是否意味着所有 9,000 个节点最终都会执行 getName(),即使 Joe 只需要执行一次?

    如果 Joe 请求调用,getName() 仅在一个节点(Joe 连接到的节点)上执行。如果他请求一个事务,它会在所有节点上执行。

    运行“getName()”的 gas 成本是否补偿了每个节点运行“getName()”的开销?

    它只补偿收取交易费用的(获胜的)矿工。与它们可以使用相同资源执行的多个“更简单”的交易相比,更大的 tx 费用(ETH 总量,而不是 gas 价格)补偿了机器需要使用的更多资源(主要是 CPU 时间)的使用。

    如果这是真的(每个节点都得到报酬),随着更多节点加入池,gas 会变得更加昂贵吗?

    并非每个节点都能获得报酬,见上文。

    gas 价格高的原因之一是因为每个节点都必须执行智能合约上调用的每个函数的效率低下,即使是那些对状态没有影响的函数?

    这可能主要是出于经济原因 - 供求关系。越多的人希望尽快执行交易并愿意支付更高的 gas 价格,他们就会推高 gas 价格。可能他们只是使用钱包应用推荐的价格,这可能高于平均水平。

    【讨论】:

    • 1/Petr 非常有帮助,谢谢。几个跟进。 1/ 节点是否为执行调用付费?如果智能合约提供的服务计算量大(比如流体动力学问题)但没有改变状态怎么办?如果将服务功能作为调用请求,则单个节点只需承担免费运行该功能的成本。需要gas吗?)。
    • 2/ 另一方面,假设有一个智能合约,它为调用者支付的费用提供了一个计算密集型问题的答案。是否可以以某种方式构造函数,其中辛勤工作由单个节点完成,但费用交易传播到所有节点>
    • 1) 节点不为调用的执行付费。至少不是以通常用于交易的网络本地货币(以太坊网络上的 ETH、BSC 网络上的 BNB 等)的“汽油费”形式。但可能还有另一种付款方式。例如。节点提供商Infura 提供有限的免费计划和更高限制的付费计划。但这些限制仅适用于一些请求,因此它们可能会根据一些平均计算成本来计算限制。
    • 2) 我没有在公共网络上看到这种方法,并且由于所有节点都被认为是平等的,因此在公共网络上很可能是不可能的。可以使用专用网络(例如Hyperledger Fabric)进行设置,并使用一组规则定义节点 A 上的执行和节点 B 上的验证,或者根本不进行验证。
    猜你喜欢
    • 2020-06-09
    • 2018-04-02
    • 2021-03-13
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多