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.

104 lines
2.8 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
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. )
  7. var registeredNativeContracts = make(map[Word256]NativeContract)
  8. func RegisteredNativeContract(addr Word256) bool {
  9. _, ok := registeredNativeContracts[addr]
  10. return ok
  11. }
  12. func RegisterNativeContract(addr Word256, fn NativeContract) bool {
  13. _, exists := registeredNativeContracts[addr]
  14. if exists {
  15. return false
  16. }
  17. registeredNativeContracts[addr] = fn
  18. return true
  19. }
  20. func init() {
  21. registerNativeContracts()
  22. registerSNativeContracts()
  23. }
  24. func registerNativeContracts() {
  25. // registeredNativeContracts[Int64ToWord256(1)] = ecrecoverFunc
  26. registeredNativeContracts[Int64ToWord256(2)] = sha256Func
  27. registeredNativeContracts[Int64ToWord256(3)] = ripemd160Func
  28. registeredNativeContracts[Int64ToWord256(4)] = identityFunc
  29. }
  30. //-----------------------------------------------------------------------------
  31. type NativeContract func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error)
  32. /* Removed due to C dependency
  33. func ecrecoverFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  34. // Deduct gas
  35. gasRequired := GasEcRecover
  36. if *gas < gasRequired {
  37. return nil, ErrInsufficientGas
  38. } else {
  39. *gas -= gasRequired
  40. }
  41. // Recover
  42. hash := input[:32]
  43. v := byte(input[32] - 27) // ignore input[33:64], v is small.
  44. sig := append(input[64:], v)
  45. recovered, err := secp256k1.RecoverPubkey(hash, sig)
  46. if err != nil {
  47. return nil, err
  48. }
  49. hashed := sha3.Sha3(recovered[1:])
  50. return LeftPadBytes(hashed, 32), nil
  51. }
  52. */
  53. func sha256Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  54. // Deduct gas
  55. gasRequired := int64((len(input)+31)/32)*GasSha256Word + GasSha256Base
  56. if *gas < gasRequired {
  57. return nil, ErrInsufficientGas
  58. } else {
  59. *gas -= gasRequired
  60. }
  61. // Hash
  62. hasher := sha256.New()
  63. // CONTRACT: this does not err
  64. hasher.Write(input)
  65. return hasher.Sum(nil), nil
  66. }
  67. func ripemd160Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  68. // Deduct gas
  69. gasRequired := int64((len(input)+31)/32)*GasRipemd160Word + GasRipemd160Base
  70. if *gas < gasRequired {
  71. return nil, ErrInsufficientGas
  72. } else {
  73. *gas -= gasRequired
  74. }
  75. // Hash
  76. hasher := ripemd160.New()
  77. // CONTRACT: this does not err
  78. hasher.Write(input)
  79. return LeftPadBytes(hasher.Sum(nil), 32), nil
  80. }
  81. func identityFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
  82. // Deduct gas
  83. gasRequired := int64((len(input)+31)/32)*GasIdentityWord + GasIdentityBase
  84. if *gas < gasRequired {
  85. return nil, ErrInsufficientGas
  86. } else {
  87. *gas -= gasRequired
  88. }
  89. // Return identity
  90. return input, nil
  91. }