repl.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github.com/ethereum/eth-go"
  6. "github.com/ethereum/eth-go/ethpub"
  7. "github.com/ethereum/eth-go/ethutil"
  8. "github.com/obscuren/otto"
  9. "io"
  10. "os"
  11. "path"
  12. )
  13. type Repl interface {
  14. Start()
  15. Stop()
  16. }
  17. type JSRepl struct {
  18. re *JSRE
  19. prompt string
  20. history *os.File
  21. running bool
  22. }
  23. func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
  24. hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
  25. if err != nil {
  26. panic(err)
  27. }
  28. return &JSRepl{re: NewJSRE(ethereum), prompt: "> ", history: hist}
  29. }
  30. func (self *JSRepl) Start() {
  31. if !self.running {
  32. self.running = true
  33. logger.Infoln("init JS Console")
  34. reader := bufio.NewReader(self.history)
  35. for {
  36. line, err := reader.ReadString('\n')
  37. if err != nil && err == io.EOF {
  38. break
  39. } else if err != nil {
  40. fmt.Println("error reading history", err)
  41. break
  42. }
  43. addHistory(line[:len(line)-1])
  44. }
  45. self.read()
  46. }
  47. }
  48. func (self *JSRepl) Stop() {
  49. if self.running {
  50. self.running = false
  51. self.re.Stop()
  52. logger.Infoln("exit JS Console")
  53. self.history.Close()
  54. }
  55. }
  56. func (self *JSRepl) parseInput(code string) {
  57. defer func() {
  58. if r := recover(); r != nil {
  59. fmt.Println("[native] error", r)
  60. }
  61. }()
  62. value, err := self.re.Run(code)
  63. if err != nil {
  64. fmt.Println(err)
  65. return
  66. }
  67. self.PrintValue(value)
  68. }
  69. // The JSEthereum object attempts to wrap the PEthereum object and returns
  70. // meaningful javascript objects
  71. type JSBlock struct {
  72. *ethpub.PBlock
  73. eth *JSEthereum
  74. }
  75. func (self *JSBlock) GetTransaction(hash string) otto.Value {
  76. return self.eth.toVal(self.PBlock.GetTransaction(hash))
  77. }
  78. type JSEthereum struct {
  79. *ethpub.PEthereum
  80. vm *otto.Otto
  81. }
  82. func (self *JSEthereum) GetBlock(hash string) otto.Value {
  83. return self.toVal(&JSBlock{self.PEthereum.GetBlock(hash), self})
  84. }
  85. func (self *JSEthereum) GetPeers() otto.Value {
  86. return self.toVal(self.PEthereum.GetPeers())
  87. }
  88. func (self *JSEthereum) GetKey() otto.Value {
  89. return self.toVal(self.PEthereum.GetKey())
  90. }
  91. func (self *JSEthereum) GetStateObject(addr string) otto.Value {
  92. return self.toVal(self.PEthereum.GetStateObject(addr))
  93. }
  94. func (self *JSEthereum) GetStateKeyVals(addr string) otto.Value {
  95. return self.toVal(self.PEthereum.GetStateObject(addr).StateKeyVal(false))
  96. }
  97. func (self *JSEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) otto.Value {
  98. r, err := self.PEthereum.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
  99. if err != nil {
  100. fmt.Println(err)
  101. return otto.UndefinedValue()
  102. }
  103. return self.toVal(r)
  104. }
  105. func (self *JSEthereum) Create(key, valueStr, gasStr, gasPriceStr, scriptStr string) otto.Value {
  106. r, err := self.PEthereum.Create(key, valueStr, gasStr, gasPriceStr, scriptStr)
  107. if err != nil {
  108. fmt.Println(err)
  109. return otto.UndefinedValue()
  110. }
  111. return self.toVal(r)
  112. }
  113. func (self *JSEthereum) toVal(v interface{}) otto.Value {
  114. result, err := self.vm.ToValue(v)
  115. if err != nil {
  116. fmt.Println("Value unknown:", err)
  117. return otto.UndefinedValue()
  118. }
  119. return result
  120. }