contracts.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2014 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package vm
  17. import (
  18. "math/big"
  19. "github.com/ethereum/go-ethereum/common"
  20. "github.com/ethereum/go-ethereum/crypto"
  21. "github.com/ethereum/go-ethereum/logger"
  22. "github.com/ethereum/go-ethereum/logger/glog"
  23. "github.com/ethereum/go-ethereum/params"
  24. )
  25. // PrecompiledAccount represents a native ethereum contract
  26. type PrecompiledAccount struct {
  27. Gas func(l int) *big.Int
  28. fn func(in []byte) []byte
  29. }
  30. // Call calls the native function
  31. func (self PrecompiledAccount) Call(in []byte) []byte {
  32. return self.fn(in)
  33. }
  34. // Precompiled contains the default set of ethereum contracts
  35. var Precompiled = PrecompiledContracts()
  36. // PrecompiledContracts returns the default set of precompiled ethereum
  37. // contracts defined by the ethereum yellow paper.
  38. func PrecompiledContracts() map[string]*PrecompiledAccount {
  39. return map[string]*PrecompiledAccount{
  40. // ECRECOVER
  41. string(common.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  42. return params.EcrecoverGas
  43. }, ecrecoverFunc},
  44. // SHA256
  45. string(common.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  46. n := big.NewInt(int64(l+31) / 32)
  47. n.Mul(n, params.Sha256WordGas)
  48. return n.Add(n, params.Sha256Gas)
  49. }, sha256Func},
  50. // RIPEMD160
  51. string(common.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  52. n := big.NewInt(int64(l+31) / 32)
  53. n.Mul(n, params.Ripemd160WordGas)
  54. return n.Add(n, params.Ripemd160Gas)
  55. }, ripemd160Func},
  56. string(common.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  57. n := big.NewInt(int64(l+31) / 32)
  58. n.Mul(n, params.IdentityWordGas)
  59. return n.Add(n, params.IdentityGas)
  60. }, memCpy},
  61. }
  62. }
  63. func sha256Func(in []byte) []byte {
  64. return crypto.Sha256(in)
  65. }
  66. func ripemd160Func(in []byte) []byte {
  67. return common.LeftPadBytes(crypto.Ripemd160(in), 32)
  68. }
  69. const ecRecoverInputLength = 128
  70. func ecrecoverFunc(in []byte) []byte {
  71. in = common.RightPadBytes(in, 128)
  72. // "in" is (hash, v, r, s), each 32 bytes
  73. // but for ecrecover we want (r, s, v)
  74. r := common.BytesToBig(in[64:96])
  75. s := common.BytesToBig(in[96:128])
  76. // Treat V as a 256bit integer
  77. vbig := common.Bytes2Big(in[32:64])
  78. v := byte(vbig.Uint64())
  79. if !crypto.ValidateSignatureValues(v, r, s) {
  80. glog.V(logger.Debug).Infof("EC RECOVER FAIL: v, r or s value invalid")
  81. return nil
  82. }
  83. // v needs to be at the end and normalized for libsecp256k1
  84. vbignormal := new(big.Int).Sub(vbig, big.NewInt(27))
  85. vnormal := byte(vbignormal.Uint64())
  86. rsv := append(in[64:128], vnormal)
  87. pubKey, err := crypto.Ecrecover(in[:32], rsv)
  88. // make sure the public key is a valid one
  89. if err != nil {
  90. glog.V(logger.Error).Infof("EC RECOVER FAIL: ", err)
  91. return nil
  92. }
  93. // the first byte of pubkey is bitcoin heritage
  94. return common.LeftPadBytes(crypto.Sha3(pubKey[1:])[12:], 32)
  95. }
  96. func memCpy(in []byte) []byte {
  97. return in
  98. }