You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.6 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package vm
  2. import (
  3. "crypto/sha256"
  4. "github.com/tendermint/tendermint/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160"
  5. . "github.com/tendermint/tendermint/common"
  6. "github.com/tendermint/tendermint/vm/secp256k1"
  7. "github.com/tendermint/tendermint/vm/sha3"
  8. )
  9. var registeredNativeContracts = make(map[Word256]NativeContract)
  10. func RegisteredNativeContract(addr Word256) bool {
  11. _, ok := registeredNativeContracts[addr]
  12. return ok
  13. }
  14. func init() {
  15. registerNativeContracts()
  16. registerSNativeContracts()
  17. }
  18. func registerNativeContracts() {
  19. registeredNativeContracts[Int64ToWord256(1)] = ecrecoverFunc
  20. registeredNativeContracts[Int64ToWord256(2)] = sha256Func
  21. registeredNativeContracts[Int64ToWord256(3)] = ripemd160Func
  22. registeredNativeContracts[Int64ToWord256(4)] = identityFunc
  23. }
  24. //-----------------------------------------------------------------------------
  25. type NativeContract func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error)
  26. func ecrecoverFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  27. // Deduct gas
  28. gasRequired := GasEcRecover
  29. if *gas < gasRequired {
  30. return nil, ErrInsufficientGas
  31. } else {
  32. *gas -= gasRequired
  33. }
  34. // Recover
  35. hash := input[:32]
  36. v := byte(input[32] - 27) // ignore input[33:64], v is small.
  37. sig := append(input[64:], v)
  38. recovered, err := secp256k1.RecoverPubkey(hash, sig)
  39. if err != nil {
  40. return nil, err
  41. }
  42. hashed := sha3.Sha3(recovered[1:])
  43. return LeftPadBytes(hashed, 32), nil
  44. }
  45. func sha256Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  46. // Deduct gas
  47. gasRequired := int64((len(input)+31)/32)*GasSha256Word + GasSha256Base
  48. if *gas < gasRequired {
  49. return nil, ErrInsufficientGas
  50. } else {
  51. *gas -= gasRequired
  52. }
  53. // Hash
  54. hasher := sha256.New()
  55. // CONTRACT: this does not err
  56. hasher.Write(input)
  57. return hasher.Sum(nil), nil
  58. }
  59. func ripemd160Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  60. // Deduct gas
  61. gasRequired := int64((len(input)+31)/32)*GasRipemd160Word + GasRipemd160Base
  62. if *gas < gasRequired {
  63. return nil, ErrInsufficientGas
  64. } else {
  65. *gas -= gasRequired
  66. }
  67. // Hash
  68. hasher := ripemd160.New()
  69. // CONTRACT: this does not err
  70. hasher.Write(input)
  71. return LeftPadBytes(hasher.Sum(nil), 32), nil
  72. }
  73. func identityFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  74. // Deduct gas
  75. gasRequired := int64((len(input)+31)/32)*GasIdentityWord + GasIdentityBase
  76. if *gas < gasRequired {
  77. return nil, ErrInsufficientGas
  78. } else {
  79. *gas -= gasRequired
  80. }
  81. // Return identity
  82. return input, nil
  83. }