github.com/klaytn/klaytn@v1.12.1/blockchain/vm/contracts.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from core/vm/contracts.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package vm 22 23 import ( 24 "crypto/ecdsa" 25 "crypto/sha256" 26 "encoding/binary" 27 "errors" 28 "fmt" 29 "math/big" 30 "strconv" 31 32 "github.com/klaytn/klaytn/api/debug" 33 "github.com/klaytn/klaytn/blockchain/types" 34 "github.com/klaytn/klaytn/blockchain/types/accountkey" 35 "github.com/klaytn/klaytn/common" 36 "github.com/klaytn/klaytn/common/math" 37 "github.com/klaytn/klaytn/crypto" 38 "github.com/klaytn/klaytn/crypto/blake2b" 39 "github.com/klaytn/klaytn/crypto/bn256" 40 "github.com/klaytn/klaytn/crypto/kzg4844" 41 "github.com/klaytn/klaytn/kerrors" 42 "github.com/klaytn/klaytn/log" 43 "github.com/klaytn/klaytn/params" 44 "golang.org/x/crypto/ripemd160" 45 ) 46 47 var logger = log.NewModuleLogger(log.VM) 48 49 var ( 50 errInputTooShort = errors.New("input length is too short") 51 errWrongSignatureLength = errors.New("wrong signature length") 52 ) 53 54 // PrecompiledContract is the basic interface for native Go contracts. The implementation 55 // requires a deterministic gas count based on the input size of the Run method of the 56 // contract. 57 // If you want more information about Klaytn's precompiled contracts, 58 // please refer https://docs.klaytn.com/smart-contract/precompiled-contracts 59 type PrecompiledContract interface { 60 // GetRequiredGasAndComputationCost returns the gas and computation cost 61 // required to execute the precompiled contract. 62 GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) 63 64 // Run runs the precompiled contract 65 // contract, evm is only exists in klaytn, those are not used in go-ethereum 66 Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) 67 } 68 69 // PrecompiledContractsByzantium contains the default set of pre-compiled Klaytn 70 // contracts based on Ethereum Byzantium. 71 var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{ 72 common.BytesToAddress([]byte{1}): &ecrecover{}, 73 common.BytesToAddress([]byte{2}): &sha256hash{}, 74 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 75 common.BytesToAddress([]byte{4}): &dataCopy{}, 76 common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, 77 common.BytesToAddress([]byte{6}): &bn256AddByzantium{}, 78 common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{}, 79 common.BytesToAddress([]byte{8}): &bn256PairingByzantium{}, 80 common.BytesToAddress([]byte{9}): &vmLog{}, 81 common.BytesToAddress([]byte{10}): &feePayer{}, 82 common.BytesToAddress([]byte{11}): &validateSender{}, 83 } 84 85 // DO NOT USE 0x3FD, 0x3FE, 0x3FF ADDRESSES BEFORE ISTANBUL CHANGE ACTIVATED. 86 87 // PrecompiledContractsIstanbul contains the default set of pre-compiled Klaytn 88 // contracts based on Ethereum Istanbul. 89 var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ 90 common.BytesToAddress([]byte{1}): &ecrecover{}, 91 common.BytesToAddress([]byte{2}): &sha256hash{}, 92 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 93 common.BytesToAddress([]byte{4}): &dataCopy{}, 94 common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, 95 common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, 96 common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, 97 common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, 98 common.BytesToAddress([]byte{9}): &blake2F{}, 99 common.BytesToAddress([]byte{3, 253}): &vmLog{}, 100 common.BytesToAddress([]byte{3, 254}): &feePayer{}, 101 common.BytesToAddress([]byte{3, 255}): &validateSender{}, 102 } 103 104 // PrecompiledContractsKore contains the default set of pre-compiled Klaytn 105 // contracts based on Ethereum Berlin. 106 var PrecompiledContractsKore = map[common.Address]PrecompiledContract{ 107 common.BytesToAddress([]byte{1}): &ecrecover{}, 108 common.BytesToAddress([]byte{2}): &sha256hash{}, 109 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 110 common.BytesToAddress([]byte{4}): &dataCopy{}, 111 common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, 112 common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, 113 common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, 114 common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, 115 common.BytesToAddress([]byte{9}): &blake2F{}, 116 common.BytesToAddress([]byte{3, 253}): &vmLog{}, 117 common.BytesToAddress([]byte{3, 254}): &feePayer{}, 118 common.BytesToAddress([]byte{3, 255}): &validateSender{}, 119 } 120 121 // PrecompiledContractsCancun contains the default set of pre-compiled Klaytn 122 // contracts based on Ethereum Cancun. 123 var PrecompiledContractsCancun = map[common.Address]PrecompiledContract{ 124 common.BytesToAddress([]byte{1}): &ecrecover{}, 125 common.BytesToAddress([]byte{2}): &sha256hash{}, 126 common.BytesToAddress([]byte{3}): &ripemd160hash{}, 127 common.BytesToAddress([]byte{4}): &dataCopy{}, 128 common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, 129 common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, 130 common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, 131 common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, 132 common.BytesToAddress([]byte{9}): &blake2F{}, 133 common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, 134 common.BytesToAddress([]byte{3, 253}): &vmLog{}, 135 common.BytesToAddress([]byte{3, 254}): &feePayer{}, 136 common.BytesToAddress([]byte{3, 255}): &validateSender{}, 137 } 138 139 var ( 140 PrecompiledAddressCancun []common.Address 141 PrecompiledAddressIstanbul []common.Address 142 PrecompiledAddressesByzantium []common.Address 143 ) 144 145 func init() { 146 for k := range PrecompiledContractsByzantium { 147 PrecompiledAddressesByzantium = append(PrecompiledAddressesByzantium, k) 148 } 149 for k := range PrecompiledContractsIstanbul { 150 PrecompiledAddressIstanbul = append(PrecompiledAddressIstanbul, k) 151 } 152 for k := range PrecompiledContractsCancun { 153 PrecompiledAddressCancun = append(PrecompiledAddressCancun, k) 154 } 155 } 156 157 // ActivePrecompiles returns the precompiles enabled with the current configuration. 158 func ActivePrecompiles(rules params.Rules) []common.Address { 159 var precompiledContractAddrs []common.Address 160 switch { 161 case rules.IsCancun: 162 precompiledContractAddrs = PrecompiledAddressCancun 163 case rules.IsIstanbul: 164 precompiledContractAddrs = PrecompiledAddressIstanbul 165 default: 166 precompiledContractAddrs = PrecompiledAddressesByzantium 167 } 168 169 // After istanbulCompatible hf, need to support for vmversion0 contracts, too. 170 // VmVersion0 contracts are deployed before istanbulCompatible and they use byzantiumCompatible precompiled contracts. 171 // VmVersion0 contracts are the contracts deployed before istanbulCompatible hf. 172 if rules.IsIstanbul { 173 return append(precompiledContractAddrs, 174 []common.Address{common.BytesToAddress([]byte{10}), common.BytesToAddress([]byte{11})}...) 175 } else { 176 return precompiledContractAddrs 177 } 178 } 179 180 // RunPrecompiledContract runs and evaluates the output of a precompiled contract. 181 func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract, evm *EVM) (ret []byte, computationCost uint64, err error) { 182 gas, computationCost := p.GetRequiredGasAndComputationCost(input) 183 if contract.UseGas(gas) { 184 ret, err = p.Run(input, contract, evm) 185 return ret, computationCost, err 186 } 187 return nil, computationCost, kerrors.ErrOutOfGas 188 } 189 190 // ECRECOVER implemented as a native contract. 191 type ecrecover struct{} 192 193 func (c *ecrecover) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 194 return params.EcrecoverGas, params.EcrecoverComputationCost 195 } 196 197 func (c *ecrecover) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 198 const ecRecoverInputLength = 128 199 200 input = common.RightPadBytes(input, ecRecoverInputLength) 201 // "input" is (hash, v, r, s), each 32 bytes 202 // but for ecrecover we want (r, s, v) 203 204 r := new(big.Int).SetBytes(input[64:96]) 205 s := new(big.Int).SetBytes(input[96:128]) 206 v := input[63] - 27 207 208 // tighter sig s values input homestead only apply to tx sigs 209 if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { 210 return nil, nil 211 } 212 // We must make sure not to modify the 'input', so placing the 'v' along with 213 // the signature needs to be done on a new allocation 214 sig := make([]byte, 65) 215 copy(sig, input[64:128]) 216 sig[64] = v 217 // v needs to be at the end for libsecp256k1 218 pubKey, err := crypto.Ecrecover(input[:32], sig) 219 // make sure the public key is a valid one 220 if err != nil { 221 return nil, nil 222 } 223 224 // the first byte of pubkey is bitcoin heritage 225 return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil 226 } 227 228 // SHA256 implemented as a native contract. 229 type sha256hash struct{} 230 231 // GetRequiredGasAndComputationCost returns the gas required to execute the pre-compiled contract 232 // and the computation cost of the precompiled contract. 233 // 234 // This method does not require any overflow checking as the input size gas costs 235 // required for anything significant is so high it's impossible to pay for. 236 func (c *sha256hash) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 237 n32Bytes := uint64(len(input)+31) / 32 238 239 return n32Bytes*params.Sha256PerWordGas + params.Sha256BaseGas, 240 n32Bytes*params.Sha256PerWordComputationCost + params.Sha256BaseComputationCost 241 } 242 243 func (c *sha256hash) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 244 h := sha256.Sum256(input) 245 return h[:], nil 246 } 247 248 // RIPEMD160 implemented as a native contract. 249 type ripemd160hash struct{} 250 251 // GetRequiredGasAndComputationCost returns the gas required to execute the pre-compiled contract 252 // and the computation cost of the precompiled contract. 253 // 254 // This method does not require any overflow checking as the input size gas costs 255 // required for anything significant is so high it's impossible to pay for. 256 func (c *ripemd160hash) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 257 n32Bytes := uint64(len(input)+31) / 32 258 259 return n32Bytes*params.Ripemd160PerWordGas + params.Ripemd160BaseGas, 260 n32Bytes*params.Ripemd160PerWordComputationCost + params.Ripemd160BaseComputationCost 261 } 262 263 func (c *ripemd160hash) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 264 ripemd := ripemd160.New() 265 ripemd.Write(input) 266 return common.LeftPadBytes(ripemd.Sum(nil), 32), nil 267 } 268 269 // data copy implemented as a native contract. 270 type dataCopy struct{} 271 272 // GetRequiredGasAndComputationCost returns the gas required to execute the pre-compiled contract 273 // and the computation cost of the precompiled contract. 274 // 275 // This method does not require any overflow checking as the input size gas costs 276 // required for anything significant is so high it's impossible to pay for. 277 func (c *dataCopy) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 278 n32Bytes := uint64(len(input)+31) / 32 279 return n32Bytes*params.IdentityPerWordGas + params.IdentityBaseGas, 280 n32Bytes*params.IdentityPerWordComputationCost + params.IdentityBaseComputationCost 281 } 282 283 func (c *dataCopy) Run(in []byte, contract *Contract, evm *EVM) ([]byte, error) { 284 return in, nil 285 } 286 287 // bigModExp implements a native big integer exponential modular operation. 288 type bigModExp struct { 289 eip2565 bool 290 } 291 292 var ( 293 big1 = big.NewInt(1) 294 big3 = big.NewInt(3) 295 big4 = big.NewInt(4) 296 big7 = big.NewInt(7) 297 big8 = big.NewInt(8) 298 big16 = big.NewInt(16) 299 big20 = big.NewInt(20) 300 big32 = big.NewInt(32) 301 big64 = big.NewInt(64) 302 big96 = big.NewInt(96) 303 big480 = big.NewInt(480) 304 big1024 = big.NewInt(1024) 305 big3072 = big.NewInt(3072) 306 big199680 = big.NewInt(199680) 307 ) 308 309 // modexpMultComplexity implements bigModexp multComplexity formula, as defined in EIP-198 310 // 311 // def mult_complexity(x): 312 // 313 // if x <= 64: return x ** 2 314 // elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072 315 // else: return x ** 2 // 16 + 480 * x - 199680 316 // 317 // where is x is max(length_of_MODULUS, length_of_BASE) 318 func modexpMultComplexity(x *big.Int) *big.Int { 319 switch { 320 case x.Cmp(big64) <= 0: 321 x.Mul(x, x) // x ** 2 322 case x.Cmp(big1024) <= 0: 323 // (x ** 2 // 4 ) + ( 96 * x - 3072) 324 x = new(big.Int).Add( 325 new(big.Int).Div(new(big.Int).Mul(x, x), big4), 326 new(big.Int).Sub(new(big.Int).Mul(big96, x), big3072), 327 ) 328 default: 329 // (x ** 2 // 16) + (480 * x - 199680) 330 x = new(big.Int).Add( 331 new(big.Int).Div(new(big.Int).Mul(x, x), big16), 332 new(big.Int).Sub(new(big.Int).Mul(big480, x), big199680), 333 ) 334 } 335 return x 336 } 337 338 // GetRequiredGasAndComputationCost returns the gas required to execute the pre-compiled contract 339 // and the computation cost of the precompiled contract. 340 func (c *bigModExp) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 341 var ( 342 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) 343 expLen = new(big.Int).SetBytes(getData(input, 32, 32)) 344 modLen = new(big.Int).SetBytes(getData(input, 64, 32)) 345 ) 346 if len(input) > 96 { 347 input = input[96:] 348 } else { 349 input = input[:0] 350 } 351 // Retrieve the head 32 bytes of exp for the adjusted exponent length 352 var expHead *big.Int 353 if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 { 354 expHead = new(big.Int) 355 } else { 356 if expLen.Cmp(big32) > 0 { 357 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32)) 358 } else { 359 expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64())) 360 } 361 } 362 // Calculate the adjusted exponent length 363 var msb int 364 if bitlen := expHead.BitLen(); bitlen > 0 { 365 msb = bitlen - 1 366 } 367 adjExpLen := new(big.Int) 368 if expLen.Cmp(big32) > 0 { 369 adjExpLen.Sub(expLen, big32) 370 adjExpLen.Mul(big8, adjExpLen) 371 } 372 adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) 373 374 // Calculate the gas cost of the operation 375 gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) 376 if c.eip2565 { 377 // EIP-2565 has three changes 378 // 1. Different multComplexity (inlined here) 379 // in EIP-2565 (https://eips.ethereum.org/EIPS/eip-2565): 380 // 381 // def mult_complexity(x): 382 // ceiling(x/8)^2 383 // 384 //where is x is max(length_of_MODULUS, length_of_BASE) 385 gas = gas.Add(gas, big7) 386 gas = gas.Div(gas, big8) 387 gas.Mul(gas, gas) 388 389 gas.Mul(gas, math.BigMax(adjExpLen, big1)) 390 // 2. Different divisor (`GQUADDIVISOR`) (3) 391 gas.Div(gas, big3) 392 if gas.BitLen() > 64 { 393 return math.MaxUint64, math.MaxUint64 394 } 395 // 3. Minimum price of 200 gas 396 if gas.Uint64() < 200 { 397 return 200, (200 / 100) + params.BigModExpBaseComputationCost 398 } 399 return gas.Uint64(), (gas.Uint64() / 100) + params.BigModExpBaseComputationCost 400 } 401 gas = modexpMultComplexity(gas) 402 gas.Mul(gas, math.BigMax(adjExpLen, big1)) 403 gas.Div(gas, big20) 404 405 if gas.BitLen() > 64 { 406 return math.MaxUint64, math.MaxUint64 407 } 408 return gas.Uint64(), (gas.Uint64() / 100) + params.BigModExpBaseComputationCost 409 } 410 411 func (c *bigModExp) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 412 var ( 413 baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() 414 expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() 415 modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() 416 ) 417 if len(input) > 96 { 418 input = input[96:] 419 } else { 420 input = input[:0] 421 } 422 // Handle a special case when both the base and mod length is zero 423 if baseLen == 0 && modLen == 0 { 424 return []byte{}, nil 425 } 426 // Retrieve the operands and execute the exponentiation 427 var ( 428 base = new(big.Int).SetBytes(getData(input, 0, baseLen)) 429 exp = new(big.Int).SetBytes(getData(input, baseLen, expLen)) 430 mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) 431 ) 432 if mod.BitLen() == 0 { 433 // Modulo 0 is undefined, return zero 434 return common.LeftPadBytes([]byte{}, int(modLen)), nil 435 } 436 return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), int(modLen)), nil 437 } 438 439 // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, 440 // returning it, or an error if the point is invalid. 441 func newCurvePoint(blob []byte) (*bn256.G1, error) { 442 p := new(bn256.G1) 443 if _, err := p.Unmarshal(blob); err != nil { 444 return nil, err 445 } 446 return p, nil 447 } 448 449 // newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point, 450 // returning it, or an error if the point is invalid. 451 func newTwistPoint(blob []byte) (*bn256.G2, error) { 452 p := new(bn256.G2) 453 if _, err := p.Unmarshal(blob); err != nil { 454 return nil, err 455 } 456 return p, nil 457 } 458 459 // runBn256Add implements the Bn256Add precompile, referenced by both 460 // Byzantium and Istanbul operations. 461 func runBn256Add(input []byte) ([]byte, error) { 462 x, err := newCurvePoint(getData(input, 0, 64)) 463 if err != nil { 464 return nil, err 465 } 466 y, err := newCurvePoint(getData(input, 64, 64)) 467 if err != nil { 468 return nil, err 469 } 470 res := new(bn256.G1) 471 res.Add(x, y) 472 return res.Marshal(), nil 473 } 474 475 // bn256Add implements a native elliptic curve point addition conforming to 476 // Istanbul consensus rules. 477 type bn256AddIstanbul struct{} 478 479 func (c *bn256AddIstanbul) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 480 return params.Bn256AddGasIstanbul, params.Bn256AddComputationCost 481 } 482 483 func (c *bn256AddIstanbul) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 484 return runBn256Add(input) 485 } 486 487 // bn256AddByzantium implements a native elliptic curve point addition 488 // conforming to Byzantium consensus rules. 489 type bn256AddByzantium struct{} 490 491 func (c *bn256AddByzantium) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 492 return params.Bn256AddGasByzantium, params.Bn256AddComputationCost 493 } 494 495 func (c *bn256AddByzantium) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 496 return runBn256Add(input) 497 } 498 499 // runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by 500 // both Constantionple and Istanbul operations. 501 func runBn256ScalarMul(input []byte) ([]byte, error) { 502 p, err := newCurvePoint(getData(input, 0, 64)) 503 if err != nil { 504 return nil, err 505 } 506 res := new(bn256.G1) 507 res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32))) 508 return res.Marshal(), nil 509 } 510 511 // bn256ScalarMulIstanbul implements a native elliptic curve scalar 512 // multiplication conforming to Istanbul consensus rules. 513 type bn256ScalarMulIstanbul struct{} 514 515 func (c *bn256ScalarMulIstanbul) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 516 return params.Bn256ScalarMulGasIstanbul, params.Bn256ScalarMulComputationCost 517 } 518 519 func (c *bn256ScalarMulIstanbul) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 520 return runBn256ScalarMul(input) 521 } 522 523 // bn256ScalarMulByzantium implements a native elliptic curve scalar 524 // multiplication conforming to Byzantium consensus rules. 525 type bn256ScalarMulByzantium struct{} 526 527 func (c *bn256ScalarMulByzantium) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 528 return params.Bn256ScalarMulGasByzantium, params.Bn256ScalarMulComputationCost 529 } 530 531 func (c *bn256ScalarMulByzantium) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 532 return runBn256ScalarMul(input) 533 } 534 535 var ( 536 // true32Byte is returned if the bn256 pairing check succeeds. 537 true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} 538 539 // false32Byte is returned if the bn256 pairing check fails. 540 false32Byte = make([]byte, 32) 541 542 // errBadPairingInput is returned if the bn256 pairing input is invalid. 543 errBadPairingInput = errors.New("bad elliptic curve pairing size") 544 ) 545 546 // runBn256Pairing implements the Bn256Pairing precompile, referenced by both 547 // Byzantium and Istanbul operations. 548 func runBn256Pairing(input []byte) ([]byte, error) { 549 // Handle some corner cases cheaply 550 if len(input)%192 > 0 { 551 return nil, errBadPairingInput 552 } 553 // Convert the input into a set of coordinates 554 var ( 555 cs []*bn256.G1 556 ts []*bn256.G2 557 ) 558 for i := 0; i < len(input); i += 192 { 559 c, err := newCurvePoint(input[i : i+64]) 560 if err != nil { 561 return nil, err 562 } 563 t, err := newTwistPoint(input[i+64 : i+192]) 564 if err != nil { 565 return nil, err 566 } 567 cs = append(cs, c) 568 ts = append(ts, t) 569 } 570 // Execute the pairing checks and return the results 571 if bn256.PairingCheck(cs, ts) { 572 return true32Byte, nil 573 } 574 return false32Byte, nil 575 } 576 577 // bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve 578 // conforming to Istanbul consensus rules. 579 type bn256PairingIstanbul struct{} 580 581 func (c *bn256PairingIstanbul) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 582 numParings := uint64(len(input) / 192) 583 return params.Bn256PairingBaseGasIstanbul + numParings*params.Bn256PairingPerPointGasIstanbul, 584 params.Bn256ParingBaseComputationCost + numParings*params.Bn256ParingPerPointComputationCost 585 } 586 587 func (c *bn256PairingIstanbul) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 588 return runBn256Pairing(input) 589 } 590 591 // bn256PairingByzantium implements a pairing pre-compile for the bn256 curve 592 // conforming to Byzantium consensus rules. 593 type bn256PairingByzantium struct{} 594 595 func (c *bn256PairingByzantium) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 596 numParings := uint64(len(input) / 192) 597 return params.Bn256PairingBaseGasByzantium + numParings*params.Bn256PairingPerPointGasByzantium, 598 params.Bn256ParingBaseComputationCost + numParings*params.Bn256ParingPerPointComputationCost 599 } 600 601 func (c *bn256PairingByzantium) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 602 return runBn256Pairing(input) 603 } 604 605 type blake2F struct{} 606 607 const ( 608 blake2FInputLength = 213 609 blake2FFinalBlockBytes = byte(1) 610 blake2FNonFinalBlockBytes = byte(0) 611 ) 612 613 var ( 614 errBlake2FInvalidInputLength = errors.New("invalid input length") 615 errBlake2FInvalidFinalFlag = errors.New("invalid final flag") 616 ) 617 618 func (c *blake2F) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 619 // If the input is malformed, we can't calculate the gas, return 0 and let the 620 // actual call choke and fault. 621 if len(input) != blake2FInputLength { 622 return 0, 0 623 } 624 gas := uint64(binary.BigEndian.Uint32(input[0:4])) 625 return gas, params.Blake2bBaseComputationCost + params.Blake2bScaleComputationCost*gas 626 } 627 628 func (c *blake2F) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 629 // Make sure the input is valid (correct length and final flag) 630 if len(input) != blake2FInputLength { 631 return nil, errBlake2FInvalidInputLength 632 } 633 if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes { 634 return nil, errBlake2FInvalidFinalFlag 635 } 636 // Parse the input into the Blake2b call parameters 637 var ( 638 rounds = binary.BigEndian.Uint32(input[0:4]) 639 final = (input[212] == blake2FFinalBlockBytes) 640 641 h [8]uint64 642 m [16]uint64 643 t [2]uint64 644 ) 645 for i := 0; i < 8; i++ { 646 offset := 4 + i*8 647 h[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) 648 } 649 for i := 0; i < 16; i++ { 650 offset := 68 + i*8 651 m[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) 652 } 653 t[0] = binary.LittleEndian.Uint64(input[196:204]) 654 t[1] = binary.LittleEndian.Uint64(input[204:212]) 655 656 // Execute the compression function, extract and return the result 657 blake2b.F(&h, m, t, final, rounds) 658 659 output := make([]byte, 64) 660 for i := 0; i < 8; i++ { 661 offset := i * 8 662 binary.LittleEndian.PutUint64(output[offset:offset+8], h[i]) 663 } 664 return output, nil 665 } 666 667 // kzgPointEvaluation implements the EIP-4844 point evaluation precompile. 668 type kzgPointEvaluation struct{} 669 670 // GetRequiredGasAndComputationCost estimates the gas required for running the point evaluation precompile and computation cost. 671 func (b *kzgPointEvaluation) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 672 return params.BlobTxPointEvaluationPrecompileGas, params.BlobTxPointEvaluationPrecompileComputationCost 673 } 674 675 const ( 676 blobVerifyInputLength = 192 // Max input length for the point evaluation precompile. 677 blobCommitmentVersionKZG uint8 = 0x01 // Version byte for the point evaluation precompile. 678 blobPrecompileReturnValue = "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" 679 ) 680 681 var ( 682 errBlobVerifyInvalidInputLength = errors.New("invalid input length") 683 errBlobVerifyMismatchedVersion = errors.New("mismatched versioned hash") 684 errBlobVerifyKZGProof = errors.New("error verifying kzg proof") 685 ) 686 687 // Run executes the point evaluation precompile. 688 func (b *kzgPointEvaluation) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 689 if len(input) != blobVerifyInputLength { 690 return nil, errBlobVerifyInvalidInputLength 691 } 692 // versioned hash: first 32 bytes 693 var versionedHash common.Hash 694 copy(versionedHash[:], input[:]) 695 696 var ( 697 point kzg4844.Point 698 claim kzg4844.Claim 699 ) 700 // Evaluation point: next 32 bytes 701 copy(point[:], input[32:]) 702 // Expected output: next 32 bytes 703 copy(claim[:], input[64:]) 704 705 // input kzg point: next 48 bytes 706 var commitment kzg4844.Commitment 707 copy(commitment[:], input[96:]) 708 if kZGToVersionedHash(commitment) != versionedHash { 709 return nil, errBlobVerifyMismatchedVersion 710 } 711 712 // Proof: next 48 bytes 713 var proof kzg4844.Proof 714 copy(proof[:], input[144:]) 715 716 if err := kzg4844.VerifyProof(commitment, point, claim, proof); err != nil { 717 return nil, fmt.Errorf("%w: %v", errBlobVerifyKZGProof, err) 718 } 719 720 return common.Hex2Bytes(blobPrecompileReturnValue), nil 721 } 722 723 // kZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 724 func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash { 725 h := sha256.Sum256(kzg[:]) 726 h[0] = blobCommitmentVersionKZG 727 728 return h 729 } 730 731 // vmLog implemented as a native contract. 732 type vmLog struct{} 733 734 // GetRequiredGasAndComputationCost returns the gas required to execute the pre-compiled contract 735 // and the computation cost of the precompiled contract. 736 func (c *vmLog) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 737 l := uint64(len(input)) 738 return l*params.VMLogPerByteGas + params.VMLogBaseGas, 739 l*params.VMLogPerByteComputationCost + params.VMLogBaseComputationCost 740 } 741 742 // Runs the vmLog contract. 743 func (c *vmLog) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 744 if (params.VMLogTarget & params.VMLogToFile) != 0 { 745 prefix := "tx=" + evm.StateDB.GetTxHash().String() + " caller=" + contract.CallerAddress.String() + " msg=" 746 debug.Handler.WriteVMLog(prefix + string(input)) 747 } 748 if (params.VMLogTarget & params.VMLogToStdout) != 0 { 749 logger.Debug("vmlog", "tx", evm.StateDB.GetTxHash().String(), 750 "caller", contract.CallerAddress.String(), "msg", strconv.QuoteToASCII(string(input))) 751 } 752 return nil, nil 753 } 754 755 type feePayer struct{} 756 757 func (c *feePayer) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 758 return params.FeePayerGas, params.FeePayerComputationCost 759 } 760 761 func (c *feePayer) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 762 return contract.FeePayerAddress.Bytes(), nil 763 } 764 765 type validateSender struct{} 766 767 func (c *validateSender) GetRequiredGasAndComputationCost(input []byte) (uint64, uint64) { 768 numSigs := uint64(len(input) / common.SignatureLength) 769 return numSigs * params.ValidateSenderGas, 770 numSigs*params.ValidateSenderPerSigComputationCost + params.ValidateSenderBaseComputationCost 771 } 772 773 func (c *validateSender) Run(input []byte, contract *Contract, evm *EVM) ([]byte, error) { 774 if err := c.validateSender(input, evm.StateDB, evm.Context.BlockNumber.Uint64()); err != nil { 775 // If return error makes contract execution failed, do not return the error. 776 // Instead, print log. 777 logger.Trace("validateSender failed", "err", err) 778 return []byte{0}, nil 779 } 780 return []byte{1}, nil 781 } 782 783 func (c *validateSender) validateSender(input []byte, picker types.AccountKeyPicker, currentBlockNumber uint64) error { 784 ptr := input 785 786 // Parse the first 20 bytes. They represent an address to be verified. 787 if len(ptr) < common.AddressLength { 788 return errInputTooShort 789 } 790 from := common.BytesToAddress(input[0:common.AddressLength]) 791 ptr = ptr[common.AddressLength:] 792 793 // Parse the next 32 bytes. They represent a message which was used to generate signatures. 794 if len(ptr) < common.HashLength { 795 return errInputTooShort 796 } 797 msg := ptr[0:common.HashLength] 798 ptr = ptr[common.HashLength:] 799 800 // Parse remaining bytes. The length should be divided by common.SignatureLength. 801 if len(ptr)%common.SignatureLength != 0 { 802 return errWrongSignatureLength 803 } 804 805 numSigs := len(ptr) / common.SignatureLength 806 pubs := make([]*ecdsa.PublicKey, numSigs) 807 for i := 0; i < numSigs; i++ { 808 p, err := crypto.Ecrecover(msg, ptr[0:common.SignatureLength]) 809 if err != nil { 810 return err 811 } 812 pubs[i], err = crypto.UnmarshalPubkey(p) 813 if err != nil { 814 return err 815 } 816 ptr = ptr[common.SignatureLength:] 817 } 818 819 k := picker.GetKey(from) 820 if err := accountkey.ValidateAccountKey(currentBlockNumber, from, k, pubs, accountkey.RoleTransaction); err != nil { 821 return err 822 } 823 824 return nil 825 }