以太坊中的gas机制实现分析

gas相关参数

一个交易中和gas相关的参数如下

  • startgas

    startgas在交易加入到交易池的时候从输入参数中获取, 一般由用户指定,即gaslimit的值, 如果没有指定,默认值是: default_startgas = 500 * 1000

  • gasprice

    gasprice也是一样, 默认值是: default_gasprice = 60 * denoms.shannon ,

    注意:

    gasprice不能小于: self.min_gasprice = 20 * 10**9

    通过控制台执行交易的默认值是: startgas=25000, gasprice=60 * denoms.shannon

  • intrinsic_gas_used

    固有的gas花费, 即任何一笔交易所需要花费的最小费用. 计算方法如下:

    intrinsic_gas_used = 
     (opcodes.GTXCOST
     + opcodes.GTXDATAZERO * 
     + opcodes.GTXDATANONZERO * )
    

    其中GTXCOST=21000 , GTXDATAZERO=4 , GTXDATANONZERO=68

gas处理

和gas相关的处理主流程在 apply_transaction(state, tx) 中.

  1. 检查交易的有效性,和gas相关的检查如下:
  2. startgas必须大于等于 intrinsic_gas_used
  3. sender账户的eth余额必须大于等于 tx.value + tx.gasprice * tx.startgas ,其中 tx.value是转账金额, tx.gasprice是单价,tx.startgas是gaslimit数量
  4. 当前block剩余的gas数量 加上 startgas必须小于block的gas_limit数量
  5. 家园版本及后续版本的以太坊中, 如果是创建合约, startgas必须大于等于 intrinsic_gas_used + opcodes.CREATE[3] ,其中CREATE[3]=32000
  6. 检查通过后, 从sender账户中扣除金额: startgas * gasprice
  7. 虚拟机执行交易, 执行中可用的gas数量是: startgas - intrinsic_gas_used
  8. 交易执行过程中,出现gas不足或异常,会直接退出交易的执行,并且gas_remained=0
  9. 执行完成后得到剩余的gas数量: gas_remained ,以及使用的gas数量: gas_used = tx.startgas - gas_remained
  10. 根据交易执行的情况,转移gas:
  11. 交易执行失败.
- 给sender加上: `gasprice * gas_remained` , 其中gas_remained=0
- 给矿工加上: `gasprice * gas_used` 其中gas_used=startgas
  1. 交易执行成功.
- 检查有没有'自杀'的地址, 比如执行suicide交易的合约地址, 如果有自杀地址, 根据自杀的地址数量计算'回退'资金: `refunds = len(suicides) * opcodes.GSUICIDEREFUND` ,其中GSUICIDEREFUND=24000
- 将'回退'资金和上面的gas_used/2的数量 进行比较, 取较小的值, 作为'奖励',回退给sender

      gas_remained += min(refunds, gas_used / 2)
      gas_used -= min(refunds, gas_used / 2) 

- 给sender加上: `gasprice * gas_remained`
- 给矿工加上: `gasprice * gas_used`
- 更新block的gas_used

你可能感兴趣的:(以太坊中的gas机制实现分析)