address.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package vm
  2. import (
  3. "math/big"
  4. "github.com/ethereum/go-ethereum/crypto"
  5. "github.com/ethereum/go-ethereum/common"
  6. )
  7. type Address interface {
  8. Call(in []byte) []byte
  9. }
  10. type PrecompiledAccount struct {
  11. Gas func(l int) *big.Int
  12. fn func(in []byte) []byte
  13. }
  14. func (self PrecompiledAccount) Call(in []byte) []byte {
  15. return self.fn(in)
  16. }
  17. var Precompiled = PrecompiledContracts()
  18. // XXX Could set directly. Testing requires resetting and setting of pre compiled contracts.
  19. func PrecompiledContracts() map[string]*PrecompiledAccount {
  20. return map[string]*PrecompiledAccount{
  21. // ECRECOVER
  22. string(common.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  23. return GasEcrecover
  24. }, ecrecoverFunc},
  25. // SHA256
  26. string(common.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  27. n := big.NewInt(int64(l+31) / 32)
  28. n.Mul(n, GasSha256Word)
  29. return n.Add(n, GasSha256Base)
  30. }, sha256Func},
  31. // RIPEMD160
  32. string(common.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  33. n := big.NewInt(int64(l+31) / 32)
  34. n.Mul(n, GasRipemdWord)
  35. return n.Add(n, GasRipemdBase)
  36. }, ripemd160Func},
  37. string(common.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
  38. n := big.NewInt(int64(l+31) / 32)
  39. n.Mul(n, GasIdentityWord)
  40. return n.Add(n, GasIdentityBase)
  41. }, memCpy},
  42. }
  43. }
  44. func sha256Func(in []byte) []byte {
  45. return crypto.Sha256(in)
  46. }
  47. func ripemd160Func(in []byte) []byte {
  48. return common.LeftPadBytes(crypto.Ripemd160(in), 32)
  49. }
  50. func ecrecoverFunc(in []byte) []byte {
  51. // In case of an invalid sig. Defaults to return nil
  52. defer func() { recover() }()
  53. hash := in[:32]
  54. v := common.BigD(in[32:64]).Bytes()[0] - 27
  55. sig := append(in[64:], v)
  56. return common.LeftPadBytes(crypto.Sha3(crypto.Ecrecover(append(hash, sig...))[1:])[12:], 32)
  57. }
  58. func memCpy(in []byte) []byte {
  59. return in
  60. }