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 }