dev_console.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package main
  2. import (
  3. "bufio"
  4. "bytes"
  5. "encoding/hex"
  6. "errors"
  7. "fmt"
  8. "github.com/ethereum/eth-go"
  9. "github.com/ethereum/eth-go/ethchain"
  10. "github.com/ethereum/eth-go/ethdb"
  11. "github.com/ethereum/eth-go/ethutil"
  12. "github.com/ethereum/eth-go/ethwire"
  13. _ "math/big"
  14. "os"
  15. "strings"
  16. )
  17. type Console struct {
  18. db *ethdb.MemDatabase
  19. trie *ethutil.Trie
  20. ethereum *eth.Ethereum
  21. }
  22. func NewConsole(s *eth.Ethereum) *Console {
  23. db, _ := ethdb.NewMemDatabase()
  24. trie := ethutil.NewTrie(db, "")
  25. return &Console{db: db, trie: trie, ethereum: s}
  26. }
  27. func (i *Console) ValidateInput(action string, argumentLength int) error {
  28. err := false
  29. var expArgCount int
  30. switch {
  31. case action == "update" && argumentLength != 2:
  32. err = true
  33. expArgCount = 2
  34. case action == "get" && argumentLength != 1:
  35. err = true
  36. expArgCount = 1
  37. case action == "dag" && argumentLength != 2:
  38. err = true
  39. expArgCount = 2
  40. case action == "decode" && argumentLength != 1:
  41. err = true
  42. expArgCount = 1
  43. case action == "encode" && argumentLength != 1:
  44. err = true
  45. expArgCount = 1
  46. case action == "gettx" && argumentLength != 1:
  47. err = true
  48. expArgCount = 1
  49. case action == "tx" && argumentLength != 2:
  50. err = true
  51. expArgCount = 2
  52. case action == "getaddr" && argumentLength != 1:
  53. err = true
  54. expArgCount = 1
  55. case action == "contract" && argumentLength != 1:
  56. err = true
  57. expArgCount = 1
  58. case action == "say" && argumentLength != 1:
  59. err = true
  60. expArgCount = 1
  61. case action == "addp" && argumentLength != 1:
  62. err = true
  63. expArgCount = 1
  64. case action == "block" && argumentLength != 1:
  65. err = true
  66. expArgCount = 1
  67. }
  68. if err {
  69. return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength))
  70. } else {
  71. return nil
  72. }
  73. }
  74. func (i *Console) Editor() []string {
  75. var buff bytes.Buffer
  76. for {
  77. reader := bufio.NewReader(os.Stdin)
  78. str, _, err := reader.ReadLine()
  79. if len(str) > 0 {
  80. buff.Write(str)
  81. buff.WriteString("\n")
  82. }
  83. if err != nil && err.Error() == "EOF" {
  84. break
  85. }
  86. }
  87. scanner := bufio.NewScanner(strings.NewReader(buff.String()))
  88. scanner.Split(bufio.ScanLines)
  89. var lines []string
  90. for scanner.Scan() {
  91. lines = append(lines, scanner.Text())
  92. }
  93. return lines
  94. }
  95. func (i *Console) PrintRoot() {
  96. root := ethutil.NewValue(i.trie.Root)
  97. if len(root.Bytes()) != 0 {
  98. fmt.Println(hex.EncodeToString(root.Bytes()))
  99. } else {
  100. fmt.Println(i.trie.Root)
  101. }
  102. }
  103. func (i *Console) ParseInput(input string) bool {
  104. scanner := bufio.NewScanner(strings.NewReader(input))
  105. scanner.Split(bufio.ScanWords)
  106. count := 0
  107. var tokens []string
  108. for scanner.Scan() {
  109. count++
  110. tokens = append(tokens, scanner.Text())
  111. }
  112. if err := scanner.Err(); err != nil {
  113. fmt.Fprintln(os.Stderr, "reading input:", err)
  114. }
  115. if len(tokens) == 0 {
  116. return true
  117. }
  118. err := i.ValidateInput(tokens[0], count-1)
  119. if err != nil {
  120. fmt.Println(err)
  121. } else {
  122. switch tokens[0] {
  123. case "update":
  124. i.trie.Update(tokens[1], tokens[2])
  125. i.PrintRoot()
  126. case "get":
  127. fmt.Println(i.trie.Get(tokens[1]))
  128. case "root":
  129. i.PrintRoot()
  130. case "rawroot":
  131. fmt.Println(i.trie.Root)
  132. case "print":
  133. i.db.Print()
  134. case "dag":
  135. fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash
  136. ethutil.BigPow(2, 36), // diff
  137. ethutil.Big(tokens[2]))) // nonce
  138. case "decode":
  139. value := ethutil.NewValueFromBytes([]byte(tokens[1]))
  140. fmt.Println(value)
  141. case "getaddr":
  142. encoded, _ := hex.DecodeString(tokens[1])
  143. addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded)
  144. fmt.Println("addr:", addr)
  145. case "block":
  146. encoded, _ := hex.DecodeString(tokens[1])
  147. block := i.ethereum.BlockChain().GetBlock(encoded)
  148. info := block.BlockInfo()
  149. fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block)
  150. case "say":
  151. i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]})
  152. case "addp":
  153. i.ethereum.ConnectToPeer(tokens[1])
  154. case "pcount":
  155. fmt.Println("peers:", i.ethereum.Peers().Len())
  156. case "encode":
  157. fmt.Printf("%q\n", ethutil.Encode(tokens[1]))
  158. case "tx":
  159. recipient, err := hex.DecodeString(tokens[1])
  160. if err != nil {
  161. fmt.Println("recipient err:", err)
  162. } else {
  163. tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""})
  164. key := ethutil.Config.Db.GetKeys()[0]
  165. tx.Sign(key.PrivateKey)
  166. i.ethereum.TxPool().QueueTransaction(tx)
  167. fmt.Printf("%x\n", tx.Hash())
  168. }
  169. case "gettx":
  170. addr, _ := hex.DecodeString(tokens[1])
  171. data, _ := ethutil.Config.Db.Get(addr)
  172. if len(data) != 0 {
  173. decoder := ethutil.NewValueFromBytes(data)
  174. fmt.Println(decoder)
  175. } else {
  176. fmt.Println("gettx: tx not found")
  177. }
  178. case "contract":
  179. fmt.Println("Contract editor (Ctrl-D = done)")
  180. code := ethchain.Compile(i.Editor())
  181. contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code)
  182. key := ethutil.Config.Db.GetKeys()[0]
  183. contract.Sign(key.PrivateKey)
  184. i.ethereum.TxPool().QueueTransaction(contract)
  185. fmt.Printf("%x\n", contract.Hash()[12:])
  186. case "exit", "quit", "q":
  187. return false
  188. case "help":
  189. fmt.Printf("COMMANDS:\n" +
  190. "\033[1m= DB =\033[0m\n" +
  191. "update KEY VALUE - Updates/Creates a new value for the given key\n" +
  192. "get KEY - Retrieves the given key\n" +
  193. "root - Prints the hex encoded merkle root\n" +
  194. "rawroot - Prints the raw merkle root\n" +
  195. "block HASH - Prints the block\n" +
  196. "getaddr ADDR - Prints the account associated with the address\n" +
  197. "\033[1m= Dagger =\033[0m\n" +
  198. "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" +
  199. "\033[1m= Encoding =\033[0m\n" +
  200. "decode STR\n" +
  201. "encode STR\n" +
  202. "\033[1m= Other =\033[0m\n" +
  203. "addp HOST:PORT\n" +
  204. "tx TO AMOUNT\n" +
  205. "contract AMOUNT\n")
  206. default:
  207. fmt.Println("Unknown command:", tokens[0])
  208. }
  209. }
  210. return true
  211. }
  212. func (i *Console) Start() {
  213. fmt.Printf("Eth Console. Type (help) for help\n")
  214. reader := bufio.NewReader(os.Stdin)
  215. for {
  216. fmt.Printf("eth >>> ")
  217. str, _, err := reader.ReadLine()
  218. if err != nil {
  219. fmt.Println("Error reading input", err)
  220. } else {
  221. if !i.ParseInput(string(str)) {
  222. return
  223. }
  224. }
  225. }
  226. }