evm.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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 core
  17. import (
  18. "math/big"
  19. "github.com/ethereum/go-ethereum/common"
  20. "github.com/ethereum/go-ethereum/core/types"
  21. "github.com/ethereum/go-ethereum/core/vm"
  22. )
  23. // BlockFetcher retrieves headers by their hash
  24. type HeaderFetcher interface {
  25. // GetHeader returns the hash corresponding to their hash
  26. GetHeader(common.Hash, uint64) *types.Header
  27. }
  28. // NewEVMContext creates a new context for use in the EVM.
  29. func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context {
  30. return vm.Context{
  31. CanTransfer: CanTransfer,
  32. Transfer: Transfer,
  33. GetHash: GetHashFn(header, chain),
  34. Origin: msg.From(),
  35. Coinbase: header.Coinbase,
  36. BlockNumber: new(big.Int).Set(header.Number),
  37. Time: new(big.Int).Set(header.Time),
  38. Difficulty: new(big.Int).Set(header.Difficulty),
  39. GasLimit: new(big.Int).Set(header.GasLimit),
  40. GasPrice: new(big.Int).Set(msg.GasPrice()),
  41. }
  42. }
  43. // GetHashFn returns a GetHashFunc which retrieves header hashes by number
  44. func GetHashFn(ref *types.Header, chain HeaderFetcher) func(n uint64) common.Hash {
  45. return func(n uint64) common.Hash {
  46. for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
  47. if header.Number.Uint64() == n {
  48. return header.Hash()
  49. }
  50. }
  51. return common.Hash{}
  52. }
  53. }
  54. // CanTransfer checks wether there are enough funds in the address' account to make a transfer.
  55. // This does not take the necessary gas in to account to make the transfer valid.
  56. func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
  57. return db.GetBalance(addr).Cmp(amount) >= 0
  58. }
  59. // Transfer subtracts amount from sender and adds amount to recipient using the given Db
  60. func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {
  61. db.SubBalance(sender, amount)
  62. db.AddBalance(recipient, amount)
  63. }