内部传输链中的气体消耗
1 个回答
- 投票数
-
- 2019-03-26
您不能超过hard_gas_limit_per_operation=400000.但是在将来的协议中,它可能会增加(例如,请参见"雅典"提案).
内部传输会消耗大量的气体.
首先,每次传输的固定费用为10000瓦斯.
第二,更重要的是,当合同被"解析"时,合同的整个
code
和storage
将从Tezos数据库中读出(除了big_map
).您根据读取的数据的二进制大小来支付费用.整个code
也会被"解析",以提取合同的参数类型,并将其与期望的类型进行比较.这种情况至少发生在两个地方:- 当您在
storage
类型中(在storage
之外)具有big_map
时,将在运行脚本之前解析协定. - 当脚本执行
CONTRACT p
Michelson指令时,协定将被解析.
因此,这意味着为了将TRANSFER_TOKENS转换为脚本合约,您必须对其进行解析,并按照其代码和存储大小支付一定的费用.当该合同收到转移并加载执行时,将在目标脚本甚至开始运行之前再次 支付这笔费用以及更多费用.
(解析合同时,从数据库中读取
storage
完全是 .我们可以在以后的协议升级中轻松解决此问题-我们可以确实应该,它会导致非常令人惊讶的漏洞.使用code
修复该问题将较不容易,但我希望有一天通过将代码分成数据库中的多个部分来解决此问题.当我们添加一流的入口点时,可能会发生这种情况.)因此,减轻这种情况的一种方法是确保所涉及的每个合同都具有较小的代码和存储空间-除了big_map之外.您只有在
GET
(可能是UNPACK
)时才为big_map的内容付费.不幸的是,这似乎意味着,今天,写复杂合同的最佳方法(尤其是当它们是内部传输的目的地时)将使用
big_map bytes bytes
作为存储,并且将所有代码和存储放入big_map中,并使用UNPACK按需加载.You cannot exceed the hard_gas_limit_per_operation = 400000. It will probably be increased in future protocols, though (see e.g. the "Athens" proposals).
Internal transfers can use up a lot of gas.
First, there is a fixed cost of 10000 gas per transfer.
Second, and more importantly, when a contract is 'parsed', the contract's entire
code
andstorage
are read out of the Tezos database (except for thebig_map
). You pay gas according the binary size of the data read. The entirecode
is also 'parsed', in order to pull out the parameter type of the contract, and compare it to the expected type. This happens in at least two places:- When you have
contract p
in yourstorage
type (outside of thebig_map
), the contract will be parsed before your script runs. - When your script executes the
CONTRACT p
Michelson instruction, the contract will be parsed.
So, this means that in order to TRANSFER_TOKENS to a scripted contract, you must parse it, paying gas proportional to its code and storage size. When that contract receives the transfer and is loaded to be executed, this cost, and more, will be paid again, before the destination script even starts running.
(It is completely unnecessary for the
storage
to be read from the database when parsing a contract. We could fix this trivially in a future protocol upgrade -- and we really should, it can lead to very surprising vulnerabilities. It will be less easy to fix the problem withcode
, but I expect it will be fixed someday, by splitting the code into several pieces in the database. Maybe this can happen when we add first-class entry points.)So, one way to mitigate this is to make sure that every contract involved has small code and storage -- except for the big_map. You only pay gas for the contents of the big_map when you
GET
(and maybeUNPACK
) them.Unfortunately, this seems to mean that, today, the most optimal way to write complex contracts (especially when they are the destination for internal transfers) will be to use
big_map bytes bytes
as storage, and to put all the code and storage inside the big_map, loading it on demand, using UNPACK.-
谢谢,一旦我通过--dry-run确认天然气成本正在增加这条内部通话链的标准限额后,我将提高答案.Thanks, I'll upvote the answer once I confirm via --dry-run that gas cost is increasing the standard limit in this chain of internal calls.
- 0
- 2019-03-28
- user_184
-
它不是非常有用,但是请注意,您还可以在" Pair any what"存储上使用"tezos-client run脚本foo.tz"并输入" whatever"-track-stack,这样您就可以在每一步.It's not terribly usable, but note that you can also use `tezos-client run script foo.tz on storage 'Pair whatever whatever' and input 'whatever' --track-stack`, which will allow you to see the remaining gas at each step.
- 0
- 2019-03-28
- Tom
-
似乎--track-stack不起作用或不受欢迎.我收到以下错误: "意外的命令行选项--track-stack." 但是,正如您所指出的,气体限制正在耗尽.Seems like --track-stack doesn't work or deprected. I get following error : "Unexpected command line option --track-stack." However, As you pointed out , gas limit is exhausting.
- 0
- 2019-04-17
- user_184
-
哎呀,错字是--trace-stackoops, typo, it's --trace-stack
- 0
- 2019-04-17
- Tom
-
是的,那行得通.尽管他们默认在故障日志中添加了此标志提供的详细信息.yep, that works. Though they have added the details provided by this flag by default in failure logs.
- 0
- 2019-04-17
- user_184
我正在尝试通过内部转账执行一系列合同通话.
我认为我目前的合同非常简单,但是在进行了4次内部转帐后,我就没钱了
当涉及到的通话很复杂时,如果我继续遇到汽油耗尽错误,我将无法在两个或三个合同之间执行通话.
是什么原因造成的,我对此有什么办法?