斯帕拉迪诺
闵敏健译
最近,我看到一篇题为“程序员对时区的误解”的文章,这篇文章让我笑了。这篇文章让我想起了程序员在其他方面的误解,比如人名和时间,所以我开始寻找关于以太坊的信息。然而,我别无选择,只能尽力。
对天然气的误解
调用estimategas返回交易消耗的天然气金额
调用estimategas确实返回天然气消耗量,但这是将交易打包为当前状态所需的天然气金额。区块链的当前状态可能与您需要交易上线时完全不同。因此,当您的交易被有效地打包成块时,可能会使用不同的代码路径,并且消耗的气体量可能完全不同。
如果执行相同的代码,则我的交易消耗的气体量是相同的。
不正确。即使使用相同的参数执行相同的指令,汽油成本也可能不同。例如,如果写入新的存储位置,则sstore;(write to storage)的成本远高于已具有非零值的存储位置的成本(请参见eip2200)。这意味着,如果您将两个ERC20代币传输发送到新地址,则即使代码相同,第一个交易的成本也远高于第二个交易的成本。
如果状态完全相同,则我的交易所消耗的汽油量是相同的
通常情况下,是的,除非你不幸遇到了一个导致某些操作重新定价的硬分叉。虽然这听起来很复杂,但问题是,您无法安全地硬编码DAPP中交易的Gas cap,除非您决心在每次发生硬分叉时发布DAPP更新。
如果代码相同,状态相同,并且没有硬分叉,我可以信任estimategas的返回值吗?
现在,您可以相信estimategas的返回值是您的交易所消耗的天然气量,但您不知道交易是否会如您所愿。所谓的Gas估计是指节点将尝试使用不同的Gas值进行交易,并返回**Gas值,以确保您的交易不会失败。但是,节点将只查看您的事务,而不是事务的内部调用。这意味着,如果您调用的合同代码具有try/catch块,这会导致内部调用发生且无法撤消,则您获得的Gas估计值对于主叫合同是足够的,但对于被调用的合同来说不够。
在多签名钱包中,这种情况经常发生:即使在事务失败的情况下,大多数多签名钱包都会将操作标记为已执行,这意味着它们无法撤消最外层的事务。因此,本机Gas估计返回的值对于多符号代码可能足够,但对于实际要运行的操作不一定足够。这就是为什么gnosis safe有专门的气体估算方法。
请注意,这就是为什么很难检测操作失败的原因,因为气体不足。内部呼叫可能会耗尽天然气,因为分配给的天然气太少,而交易本身可能有更多可用的天然气。这意味着,查看交易的气体使用量和气体上限并不是检测气体错误的可靠方法。
不管是什么,我每次都可以送更多的加气点
在大多数情况下,这种方法是有效的。但请记住,合同可以查看交易中收到的天然气。因此,很容易编写一份合同,这样如果收到太多天然气,交易就会失败。但我怀疑,除了证明这一点外,这样做没有任何意义。
对交易的误解
只要节点接受事务,事务就会被挖矿出来
我认为是这样。以太坊的网络拥塞会导致天然气价格大幅波动,因此您的交易可能会被从MemPool(等待挖矿的交易集)中驱逐出去。如果汽油价格飙升,您需要重新发送交易。
我可以稍微提高汽油价格,然后重新提交交易
只要您将天然气价格提高到与之交互的节点所需的**金额(请参见;txpool.pricebump),则没有问题,否则仍将被拒绝。
矿工总是选择天然气价格**的交易
不一定。矿工可以随意选择。他们可以为自己的利益插入自己的事务,甚至为满足自己需求的用户打开协议外通道来打包事务。
然而,即使他们根据收入决定打包优先级,如何以**方式填充块也是一个背包问题。由于交易不能分为几个部分,因此,将两个500万天然气交易打包,而不是一个有天然气上限的天然气区块中的一个600万天然气交易进行打包可能会更有利可图,即使500万天然气交易有天然气价格低于600万天然气交易。
如果我以更高的天然气价格发送同一笔交易,矿工会选择后一笔交易来取代前一笔交易吗
替换交易必须在旧交易在链上之前发送给矿工。也就是说,如果您发送了一个替换事务,您仍然需要监视以前发送的相同nonce下所有事务的哈希值。
对当前的误解
我可以通过gettransactioncount获取下一笔交易的当前信息
这取决于您使用的块参数。如果基于**的数据块查询交易计数,则将忽略未打包的交易,并进一步导致您意外覆盖其中一个未打包的交易。
我可以通过gettransactioncount(’pending’)获得下一笔交易的nonce
尽管这在大多数情况下都有效,但您不能保证所有未打包的事务都在所查询节点的MemPool中。如果您有许多未打包的事务,则与您通信的节点可能已丢弃其中一些事务,但这些事务可能仍存在于其他地方!
关于日志的误解
我可以通过连续调用getlogs来有效地监视事件
虽然这是一个非常有用的方法(是的,轮询!)但在连锁重组方面,会出现问题。如果您正在轮询**块上的新日志,则不会收到有关块重新组装的通知,也不会知道您看到的事件是否需要重新调整。
我可以通过安装过滤器来有效地监视事件
直到两周前,这还不是一个常见的选择,因为Infra不支持基于HTTP的筛选器,而metamask在默认情况下使用基于HTTP的筛选器,这意味着拥有99%的DAPP用户使用此筛选器(注意:我可能会夸大)。除了新事件外,过滤器还会通知您由于块重组而删除的事件。但是,这需要与您交互的基础设施和节点保持在线。如果它们碰巧丢失了筛选器的状态,则可能会错过重组事件。
我可以通过websocket订阅有效地监视事件
杰出的!这样,除了相信您的节点将保持在线,您还应该相信您将保持在线,并且您和节点之间的连接是可靠的。我想知道您本周缺席zoom会议多少次?
现在,我不得不承认,我对这个话题非常着迷,以至于我在DevCon 5进行了一次闪电式的演讲。如果您想了解更多,eip234很好地描述了这些挑战的基本原理,以太坊 blockstream解决了这个问题。
对合同的误解
智能合约是不变的
兄弟,如果你还有这个想法,你真的出去了。我在一篇长达30页的文章中对此进行了解释,这篇文章非常长。
不包含任何委派呼叫的智能合约是不可变的
因此,可以周期性地将状态(或调用)更改为正在运行的代码的一部分。
不包含任何委派呼叫或呼叫的智能合约始终是不可变的?
以及staticcall。不要忘记staticcall!
不能更改不包含任何呼叫的智能合约
您还必须排除这种情况,即此智能合约是通过create2部署的,并将在其initcode中动态加载运行时并进行自毁。在这种情况下,所有者可以销毁合同,并在同一地址用不同的代码重新创建它。
不包含任何呼叫且未通过create2部署的智能合约是不可更改的
还有一种情况需要排除:此合同是通过create2部署的合同进行部署的。因此,您需要跟踪整个部署链并找到最初创建契约的以太坊的外部帐户,以确保没有可疑内容,也没有自毁操作。本文对这一问题进行了深入的探讨。
对ERC20代币的误解
我不想开始。这个题目更适合写一篇完整的文章。与代币交互时,请使用openzeppelin的safeERC20;(您可以在本文中了解更多信息)。请记住,接收方收到的代币不一定等于发送方在传输时扣除的代币。让我们看下一部分。
关于以太坊的误解
以太坊的总供应量只会增加
众所周知,有许多醚是不能使用的。一些是因为外部帐户的私钥丢失了,有些是意外地被发送到所有零地址,还有一些是因为他们被困在合同中无法处理(抱歉,我无能为力)。总而言之,以太坊的这一部分仍然存在,但无法进入。
然而,有一种方法可以摧毁以太坊。如果你指示一个合同自毁并指定自己为资金的接收者,合同中的所有以太都将被销毁。这意味着,只要你愿意摧毁更多的以太而不是阻止奖励,你可以缩小以太网。
我可以写一份可以拒绝任何以太转账的合同
如您所知,如果您不声明任何应付方式,SOLidity将拒绝发送到您的合同的所有以太转账,防止资金卡在合同中。但是,我们也可以在不触发任何代码的情况下向合同发送资金:要么指定合同为自毁操作奖励的接收者,要么指定为区块奖励的接收者。就像@gorgos正如评论中指出的,合同部署地址可以提前计算,以太坊可以在合同部署之前发送到该地址。
也就是说,如果您跟踪发送到您的合同的所有以太转账,您的总余额可能会大于您处理的所有转账的总和。
源链接:gisthub.com网站
文章标题:本文澄清了以太坊开发者的常见误解:天然气、交易和智能合约等
文章链接:https://www.btchangqing.cn/134551.html
更新时间:2020年11月01日
本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。