pipe.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package xeth
  2. /*
  3. * eXtended ETHereum
  4. */
  5. import (
  6. "github.com/ethereum/go-ethereum/core"
  7. "github.com/ethereum/go-ethereum/core/types"
  8. "github.com/ethereum/go-ethereum/crypto"
  9. "github.com/ethereum/go-ethereum/ethutil"
  10. "github.com/ethereum/go-ethereum/logger"
  11. "github.com/ethereum/go-ethereum/state"
  12. )
  13. var pipelogger = logger.NewLogger("XETH")
  14. type VmVars struct {
  15. State *state.State
  16. }
  17. type XEth struct {
  18. obj core.EthManager
  19. blockManager *core.BlockManager
  20. blockChain *core.ChainManager
  21. world *World
  22. Vm VmVars
  23. }
  24. func New(obj core.EthManager) *XEth {
  25. pipe := &XEth{
  26. obj: obj,
  27. blockManager: obj.BlockManager(),
  28. blockChain: obj.ChainManager(),
  29. }
  30. pipe.world = NewWorld(pipe)
  31. return pipe
  32. }
  33. func (self *XEth) Balance(addr []byte) *ethutil.Value {
  34. return ethutil.NewValue(self.World().safeGet(addr).Balance)
  35. }
  36. func (self *XEth) Nonce(addr []byte) uint64 {
  37. return self.World().safeGet(addr).Nonce
  38. }
  39. func (self *XEth) Execute(addr []byte, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
  40. return self.ExecuteObject(&Object{self.World().safeGet(addr)}, data, value, gas, price)
  41. }
  42. func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
  43. var (
  44. initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address())
  45. block = self.blockChain.CurrentBlock
  46. )
  47. self.Vm.State = self.World().State().Copy()
  48. vmenv := NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address())
  49. return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
  50. /*
  51. evm := vm.New(, vm.Type(ethutil.Config.VmType))
  52. msg := vm.NewExecution(evm, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
  53. ret, err := msg.Exec(object.Address(), initiator)
  54. fmt.Println("returned from call", ret, err)
  55. return ret, err
  56. */
  57. }
  58. func (self *XEth) Block(hash []byte) *types.Block {
  59. return self.blockChain.GetBlock(hash)
  60. }
  61. func (self *XEth) Storage(addr, storageAddr []byte) *ethutil.Value {
  62. return self.World().safeGet(addr).GetStorage(ethutil.BigD(storageAddr))
  63. }
  64. func (self *XEth) ToAddress(priv []byte) []byte {
  65. pair, err := crypto.NewKeyPairFromSec(priv)
  66. if err != nil {
  67. return nil
  68. }
  69. return pair.Address()
  70. }
  71. func (self *XEth) Exists(addr []byte) bool {
  72. return self.World().Get(addr) != nil
  73. }
  74. func (self *XEth) TransactString(key *crypto.KeyPair, rec string, value, gas, price *ethutil.Value, data []byte) (*types.Transaction, error) {
  75. // Check if an address is stored by this address
  76. var hash []byte
  77. addr := self.World().Config().Get("NameReg").StorageString(rec).Bytes()
  78. if len(addr) > 0 {
  79. hash = addr
  80. } else if ethutil.IsHex(rec) {
  81. hash = ethutil.Hex2Bytes(rec[2:])
  82. } else {
  83. hash = ethutil.Hex2Bytes(rec)
  84. }
  85. return self.Transact(key, hash, value, gas, price, data)
  86. }
  87. func (self *XEth) Transact(key *crypto.KeyPair, to []byte, value, gas, price *ethutil.Value, data []byte) (*types.Transaction, error) {
  88. var hash []byte
  89. var contractCreation bool
  90. if types.IsContractAddr(to) {
  91. contractCreation = true
  92. } else {
  93. // Check if an address is stored by this address
  94. addr := self.World().Config().Get("NameReg").Storage(to).Bytes()
  95. if len(addr) > 0 {
  96. hash = addr
  97. } else {
  98. hash = to
  99. }
  100. }
  101. var tx *types.Transaction
  102. if contractCreation {
  103. tx = types.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), data)
  104. } else {
  105. tx = types.NewTransactionMessage(hash, value.BigInt(), gas.BigInt(), price.BigInt(), data)
  106. }
  107. state := self.blockManager.TransState()
  108. nonce := state.GetNonce(key.Address())
  109. tx.Nonce = nonce
  110. tx.Sign(key.PrivateKey)
  111. err := self.obj.TxPool().Add(tx)
  112. if err != nil {
  113. return nil, err
  114. }
  115. state.SetNonce(key.Address(), nonce+1)
  116. if contractCreation {
  117. addr := tx.CreationAddress(self.World().State())
  118. pipelogger.Infof("Contract addr %x\n", addr)
  119. }
  120. return tx, nil
  121. //acc := self.blockManager.TransState().GetOrNewStateObject(key.Address())
  122. //self.obj.TxPool().QueueTransaction(tx)
  123. //acc.Nonce += 1
  124. //self.blockManager.TransState().UpdateStateObject(acc)
  125. }
  126. func (self *XEth) PushTx(tx *types.Transaction) ([]byte, error) {
  127. err := self.obj.TxPool().Add(tx)
  128. if err != nil {
  129. return nil, err
  130. }
  131. if tx.Recipient == nil {
  132. addr := tx.CreationAddress(self.World().State())
  133. pipelogger.Infof("Contract addr %x\n", addr)
  134. return addr, nil
  135. }
  136. return tx.Hash(), nil
  137. }
  138. func (self *XEth) CompileMutan(code string) ([]byte, error) {
  139. data, err := ethutil.Compile(code, false)
  140. if err != nil {
  141. return nil, err
  142. }
  143. return data, nil
  144. }