github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/vm/gas_table.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2017 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package vm
    26  
    27  import (
    28  	"github.com/ethereum/go-ethereum/common"
    29  	"github.com/ethereum/go-ethereum/common/math"
    30  	"github.com/ethereum/go-ethereum/params"
    31  )
    32  
    33  //memorygascosts计算用于内存扩展的二次气体。它这样做
    34  //仅用于扩展的内存区域,而不是总内存。
    35  func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
    36  
    37  	if newMemSize == 0 {
    38  		return 0, nil
    39  	}
    40  //uint64中的最大值是max_word_count-1
    41  //上面的任何东西都会导致溢出。
    42  //此外,一个新的Memsize会导致
    43  //大于0x7ffffffff的newmemsizewords将导致平方运算
    44  //溢出。
    45  //常量0xffffffge0是可以在没有
    46  //溢出气体计算
    47  	if newMemSize > 0xffffffffe0 {
    48  		return 0, errGasUintOverflow
    49  	}
    50  
    51  	newMemSizeWords := toWordSize(newMemSize)
    52  	newMemSize = newMemSizeWords * 32
    53  
    54  	if newMemSize > uint64(mem.Len()) {
    55  		square := newMemSizeWords * newMemSizeWords
    56  		linCoef := newMemSizeWords * params.MemoryGas
    57  		quadCoef := square / params.QuadCoeffDiv
    58  		newTotalFee := linCoef + quadCoef
    59  
    60  		fee := newTotalFee - mem.lastGasCost
    61  		mem.lastGasCost = newTotalFee
    62  
    63  		return fee, nil
    64  	}
    65  	return 0, nil
    66  }
    67  
    68  func constGasFunc(gas uint64) gasFunc {
    69  	return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
    70  		return gas, nil
    71  	}
    72  }
    73  
    74  func gasCallDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
    75  	gas, err := memoryGasCost(mem, memorySize)
    76  	if err != nil {
    77  		return 0, err
    78  	}
    79  
    80  	var overflow bool
    81  	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
    82  		return 0, errGasUintOverflow
    83  	}
    84  
    85  	words, overflow := bigUint64(stack.Back(2))
    86  	if overflow {
    87  		return 0, errGasUintOverflow
    88  	}
    89  
    90  	if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
    91  		return 0, errGasUintOverflow
    92  	}
    93  
    94  	if gas, overflow = math.SafeAdd(gas, words); overflow {
    95  		return 0, errGasUintOverflow
    96  	}
    97  	return gas, nil
    98  }
    99  
   100  func gasReturnDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   101  	gas, err := memoryGasCost(mem, memorySize)
   102  	if err != nil {
   103  		return 0, err
   104  	}
   105  
   106  	var overflow bool
   107  	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
   108  		return 0, errGasUintOverflow
   109  	}
   110  
   111  	words, overflow := bigUint64(stack.Back(2))
   112  	if overflow {
   113  		return 0, errGasUintOverflow
   114  	}
   115  
   116  	if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
   117  		return 0, errGasUintOverflow
   118  	}
   119  
   120  	if gas, overflow = math.SafeAdd(gas, words); overflow {
   121  		return 0, errGasUintOverflow
   122  	}
   123  	return gas, nil
   124  }
   125  
   126  func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   127  	var (
   128  		y, x = stack.Back(1), stack.Back(0)
   129  		val  = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
   130  	)
   131  //这将检查3个场景并相应地计算气体
   132  //1。从零值地址到非零值(新值)
   133  //2。从非零值地址到零值地址(删除)
   134  //三。从非零变为非零(变化)
   135  	if val == (common.Hash{}) && y.Sign() != 0 {
   136  //0=>0
   137  		return params.SstoreSetGas, nil
   138  	} else if val != (common.Hash{}) && y.Sign() == 0 {
   139  //非0=0
   140  		evm.StateDB.AddRefund(params.SstoreRefundGas)
   141  		return params.SstoreClearGas, nil
   142  	} else {
   143  //非0=>非0(或0=>0)
   144  		return params.SstoreResetGas, nil
   145  	}
   146  }
   147  
   148  func makeGasLog(n uint64) gasFunc {
   149  	return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   150  		requestedSize, overflow := bigUint64(stack.Back(1))
   151  		if overflow {
   152  			return 0, errGasUintOverflow
   153  		}
   154  
   155  		gas, err := memoryGasCost(mem, memorySize)
   156  		if err != nil {
   157  			return 0, err
   158  		}
   159  
   160  		if gas, overflow = math.SafeAdd(gas, params.LogGas); overflow {
   161  			return 0, errGasUintOverflow
   162  		}
   163  		if gas, overflow = math.SafeAdd(gas, n*params.LogTopicGas); overflow {
   164  			return 0, errGasUintOverflow
   165  		}
   166  
   167  		var memorySizeGas uint64
   168  		if memorySizeGas, overflow = math.SafeMul(requestedSize, params.LogDataGas); overflow {
   169  			return 0, errGasUintOverflow
   170  		}
   171  		if gas, overflow = math.SafeAdd(gas, memorySizeGas); overflow {
   172  			return 0, errGasUintOverflow
   173  		}
   174  		return gas, nil
   175  	}
   176  }
   177  
   178  func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   179  	var overflow bool
   180  	gas, err := memoryGasCost(mem, memorySize)
   181  	if err != nil {
   182  		return 0, err
   183  	}
   184  
   185  	if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow {
   186  		return 0, errGasUintOverflow
   187  	}
   188  
   189  	wordGas, overflow := bigUint64(stack.Back(1))
   190  	if overflow {
   191  		return 0, errGasUintOverflow
   192  	}
   193  	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow {
   194  		return 0, errGasUintOverflow
   195  	}
   196  	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
   197  		return 0, errGasUintOverflow
   198  	}
   199  	return gas, nil
   200  }
   201  
   202  func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   203  	gas, err := memoryGasCost(mem, memorySize)
   204  	if err != nil {
   205  		return 0, err
   206  	}
   207  
   208  	var overflow bool
   209  	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
   210  		return 0, errGasUintOverflow
   211  	}
   212  
   213  	wordGas, overflow := bigUint64(stack.Back(2))
   214  	if overflow {
   215  		return 0, errGasUintOverflow
   216  	}
   217  	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
   218  		return 0, errGasUintOverflow
   219  	}
   220  	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
   221  		return 0, errGasUintOverflow
   222  	}
   223  	return gas, nil
   224  }
   225  
   226  func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   227  	gas, err := memoryGasCost(mem, memorySize)
   228  	if err != nil {
   229  		return 0, err
   230  	}
   231  
   232  	var overflow bool
   233  	if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow {
   234  		return 0, errGasUintOverflow
   235  	}
   236  
   237  	wordGas, overflow := bigUint64(stack.Back(3))
   238  	if overflow {
   239  		return 0, errGasUintOverflow
   240  	}
   241  
   242  	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
   243  		return 0, errGasUintOverflow
   244  	}
   245  
   246  	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
   247  		return 0, errGasUintOverflow
   248  	}
   249  	return gas, nil
   250  }
   251  
   252  func gasExtCodeHash(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   253  	return gt.ExtcodeHash, nil
   254  }
   255  
   256  func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   257  	var overflow bool
   258  	gas, err := memoryGasCost(mem, memorySize)
   259  	if err != nil {
   260  		return 0, errGasUintOverflow
   261  	}
   262  	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
   263  		return 0, errGasUintOverflow
   264  	}
   265  	return gas, nil
   266  }
   267  
   268  func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   269  	var overflow bool
   270  	gas, err := memoryGasCost(mem, memorySize)
   271  	if err != nil {
   272  		return 0, errGasUintOverflow
   273  	}
   274  	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
   275  		return 0, errGasUintOverflow
   276  	}
   277  	return gas, nil
   278  }
   279  
   280  func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   281  	var overflow bool
   282  	gas, err := memoryGasCost(mem, memorySize)
   283  	if err != nil {
   284  		return 0, errGasUintOverflow
   285  	}
   286  	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
   287  		return 0, errGasUintOverflow
   288  	}
   289  	return gas, nil
   290  }
   291  
   292  func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   293  	var overflow bool
   294  	gas, err := memoryGasCost(mem, memorySize)
   295  	if err != nil {
   296  		return 0, err
   297  	}
   298  	if gas, overflow = math.SafeAdd(gas, params.CreateGas); overflow {
   299  		return 0, errGasUintOverflow
   300  	}
   301  	return gas, nil
   302  }
   303  
   304  func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   305  	var overflow bool
   306  	gas, err := memoryGasCost(mem, memorySize)
   307  	if err != nil {
   308  		return 0, err
   309  	}
   310  	if gas, overflow = math.SafeAdd(gas, params.Create2Gas); overflow {
   311  		return 0, errGasUintOverflow
   312  	}
   313  	return gas, nil
   314  }
   315  
   316  func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   317  	return gt.Balance, nil
   318  }
   319  
   320  func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   321  	return gt.ExtcodeSize, nil
   322  }
   323  
   324  func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   325  	return gt.SLoad, nil
   326  }
   327  
   328  func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   329  	expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
   330  
   331  	var (
   332  gas      = expByteLen * gt.ExpByte //不需要进行溢出检查。最大为256*expbyte气体
   333  		overflow bool
   334  	)
   335  	if gas, overflow = math.SafeAdd(gas, GasSlowStep); overflow {
   336  		return 0, errGasUintOverflow
   337  	}
   338  	return gas, nil
   339  }
   340  
   341  func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   342  	var (
   343  		gas            = gt.Calls
   344  		transfersValue = stack.Back(2).Sign() != 0
   345  		address        = common.BigToAddress(stack.Back(1))
   346  		eip158         = evm.ChainConfig().IsEIP158(evm.BlockNumber)
   347  	)
   348  	if eip158 {
   349  		if transfersValue && evm.StateDB.Empty(address) {
   350  			gas += params.CallNewAccountGas
   351  		}
   352  	} else if !evm.StateDB.Exist(address) {
   353  		gas += params.CallNewAccountGas
   354  	}
   355  	if transfersValue {
   356  		gas += params.CallValueTransferGas
   357  	}
   358  	memoryGas, err := memoryGasCost(mem, memorySize)
   359  	if err != nil {
   360  		return 0, err
   361  	}
   362  	var overflow bool
   363  	if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
   364  		return 0, errGasUintOverflow
   365  	}
   366  
   367  	evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
   368  	if err != nil {
   369  		return 0, err
   370  	}
   371  	if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
   372  		return 0, errGasUintOverflow
   373  	}
   374  	return gas, nil
   375  }
   376  
   377  func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   378  	gas := gt.Calls
   379  	if stack.Back(2).Sign() != 0 {
   380  		gas += params.CallValueTransferGas
   381  	}
   382  	memoryGas, err := memoryGasCost(mem, memorySize)
   383  	if err != nil {
   384  		return 0, err
   385  	}
   386  	var overflow bool
   387  	if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
   388  		return 0, errGasUintOverflow
   389  	}
   390  
   391  	evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
   392  	if err != nil {
   393  		return 0, err
   394  	}
   395  	if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
   396  		return 0, errGasUintOverflow
   397  	}
   398  	return gas, nil
   399  }
   400  
   401  func gasReturn(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   402  	return memoryGasCost(mem, memorySize)
   403  }
   404  
   405  func gasRevert(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   406  	return memoryGasCost(mem, memorySize)
   407  }
   408  
   409  func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   410  	var gas uint64
   411  //EIP150家用天然气再定价叉:
   412  	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
   413  		gas = gt.Suicide
   414  		var (
   415  			address = common.BigToAddress(stack.Back(0))
   416  			eip158  = evm.ChainConfig().IsEIP158(evm.BlockNumber)
   417  		)
   418  
   419  		if eip158 {
   420  //如果为空并转移值
   421  			if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
   422  				gas += gt.CreateBySuicide
   423  			}
   424  		} else if !evm.StateDB.Exist(address) {
   425  			gas += gt.CreateBySuicide
   426  		}
   427  	}
   428  
   429  	if !evm.StateDB.HasSuicided(contract.Address()) {
   430  		evm.StateDB.AddRefund(params.SuicideRefundGas)
   431  	}
   432  	return gas, nil
   433  }
   434  
   435  func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   436  	gas, err := memoryGasCost(mem, memorySize)
   437  	if err != nil {
   438  		return 0, err
   439  	}
   440  	var overflow bool
   441  	if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
   442  		return 0, errGasUintOverflow
   443  	}
   444  
   445  	evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
   446  	if err != nil {
   447  		return 0, err
   448  	}
   449  	if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
   450  		return 0, errGasUintOverflow
   451  	}
   452  	return gas, nil
   453  }
   454  
   455  func gasStaticCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   456  	gas, err := memoryGasCost(mem, memorySize)
   457  	if err != nil {
   458  		return 0, err
   459  	}
   460  	var overflow bool
   461  	if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
   462  		return 0, errGasUintOverflow
   463  	}
   464  
   465  	evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
   466  	if err != nil {
   467  		return 0, err
   468  	}
   469  	if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
   470  		return 0, errGasUintOverflow
   471  	}
   472  	return gas, nil
   473  }
   474  
   475  func gasPush(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   476  	return GasFastestStep, nil
   477  }
   478  
   479  func gasSwap(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   480  	return GasFastestStep, nil
   481  }
   482  
   483  func gasDup(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
   484  	return GasFastestStep, nil
   485  }