一文澄清以太坊开发者常见误解:Gas、交易与智能合约等


一文澄清以太坊开发者常见误解:Gas、交易与智能合约等文章插图
免责声明:本文旨在传递更多市场信息 , 不构成任何投资建议 。 文章仅代表作者观点 , 不代表火星财经官方立场 。
小编:记得关注哦
来源:以太坊爱好者
原文标题:一文澄清以太坊开发者常见误解:Gas、交易与智能合约等
撰文:spalladino
翻译 & 校对:闵敏 & 阿剑
最近 , 我偶然读到了一篇题为《程序员关于时区的误解》的文章 , 让我爆笑不已 。 这篇文章让我想到了程序员在其它方面的误解 , 如人名和时间 , 于是我开始寻找有没有关于以太坊的 。 奈何寻觅无果 , 我只得尽自己的绵薄之力 。
关于 Gas 的误解
调用 estimateGas 会返回交易所需消耗的 gas 量
调用 estimateGas 确实会返回一个 gas 耗费量 , 但这是该笔交易在当前状态下被打包会花费的 gas 量 。 而区块链的当前状态可能与你需要该笔交易上链时的状态大相径庭 。 因此 , 当你的交易被有效打包进区块时 , 可能会采用不同的代码路径 , 需要消耗的 gas 量也有可能完全不同 。
如果执行的代码相同 , 我的交易所需消耗的 gas 量也相同 。
不对 。 即使你使用相同的参数来执行相同的指令 , gas 成本也有可能不同 。 例如 , 相比已经有非零值的存储位置 , 如果你要写入新的存储位置 , SSTORE (写入存储操作)的成本会高得多(参见 EIP2200) 。 这就意味着 , 如果你向一个新地址发送两笔 ERC20 代币转账 , 第一笔交易的成本会比第二笔高得多 , 即使二者执行的代码完全相同 。
如果状态完全相同 , 我的交易所需消耗的 gas 量也相同
通常情况下是的 , 除非你很倒霉地碰上了硬分叉 , 导致一些操作重新定价 。 虽然这听起来很复杂 , 但说白了就是 , 你无法针对 dApp 中交易的 gas 上限进行安全的硬编码 , 除非你决心在每次发生硬分叉后都发布 dApp 更新 。
如果代码相同 , 状态也相同 , 且没有发生硬分叉 , 我就可以相信 estimateGas 的返回值了吗?
这下你可以相信 estimateGas 的返回值就是你的交易所需消耗的 gas 量了 , 但是你不知道这笔交易是否会如你所愿的那般进行 。 所谓的 gas 估测 , 就是节点将使用不同的 gas 值来尝试你的交易 , 并返回确保你的交易不会失败的最低 gas 值 。 但是 , 节点只会看你的交易 , 不会看交易的内部调用 。 这就意味着 , 如果你调用的合约代码有一个 try/catch 块 , 导致内部调用发生后无法撤销 , 你获得的 gas 估测值对调用合约来说是够用的 , 但是对被调用合约来说就不够了 。
在多签名钱包中 , 这种情况经常发生:即使是在交易失败的情况下 , 大多数多签钱包会将操作标记为已执行 , 也就是说它们无法撤销最外层的交易(所带来的影响) 。 因此 , 一个原生的 gas 估测返回的值可能对多签代码来说是足够的 , 对你实际想运行的操作来说不一定足够 。 这就是为什么 Gnosis Safe 有一个专门的 gas 估测方法 。
请注意 , 这也就是为什么因为 gas 不够而导致操作失败的情况很难察觉 。 内部调用可能会因为被分配到的 gas 太少而将 gas 耗尽 , 而交易本身可能还有很多 gas 可用 。 这就意味着 , 查看交易的 gas 使用量和 gas 上限并非检测 gas 错误的可靠方式 。
管他呢 , 我每次多发送点 gas 就好了
多数情况下 , 这个方法是管用的 。 但是请记住 , 合约是可以查看它在一笔交易中收到的 gas 的 。 因此 , 可以轻而易举地将合约编写成 , 一旦收到过多 gas , 交易就会失败 。 不过我怀疑的是 , 除了证明这一点外 , 这么做没有任何意义 。
关于交易的误解只要节点接受了交易 , 交易就会被挖出
想得美哦 。 以太坊的网络拥堵会导致 gas 价格波动很大 , 因此你的交易可能会被逐出 mempool (等待被挖出的交易集合) 。 如果 gas 价格飙升 , 你就需要重新发送交易 。
我可以略微提高 gas 价格然后重新提交交易
只要你将 gas 价格提高到与你交互的节点所需的最小量(参见 txpool.pricebump) , 那就没什么问题 , 否则还是会被拒绝 。
矿工总选择 gas 价格最高的交易
并不一定 。 矿工可以随心所欲进行选择 。 他们可能会为了自己的利益而塞入自己的交易 , 甚至可以开一个协议外通道 , 为符合自己要求的用户打包交易 。
但是 , 即使他们依据收益来决定打包优先级 , 如何以最优方式填满区块也是一个背包问题(knapsack problem) 。 由于交易无法被分割成几部分 , 所以 , 在 gas 上限为 10M 的区块中打包两个 5M gas 交易 , 而不是一个 6M gas 的交易 , 可能更为有利可图 , 即使 5M gas 交易的 gas 价格低于 6M gas 交易 。