websockets.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package utils
  2. import (
  3. "github.com/ethereum/go-ethereum"
  4. "github.com/ethereum/go-ethereum/ethpipe"
  5. "github.com/ethereum/go-ethereum/ethutil"
  6. "github.com/ethereum/go-ethereum/websocket"
  7. )
  8. func args(v ...interface{}) []interface{} {
  9. return v
  10. }
  11. type WebSocketServer struct {
  12. ethereum *eth.Ethereum
  13. filterCallbacks map[int][]int
  14. }
  15. func NewWebSocketServer(eth *eth.Ethereum) *WebSocketServer {
  16. return &WebSocketServer{eth, make(map[int][]int)}
  17. }
  18. func (self *WebSocketServer) Serv() {
  19. pipe := ethpipe.NewJSPipe(self.ethereum)
  20. wsServ := websocket.NewServer("/eth", ":40404")
  21. wsServ.MessageFunc(func(c *websocket.Client, msg *websocket.Message) {
  22. switch msg.Call {
  23. case "compile":
  24. data := ethutil.NewValue(msg.Args)
  25. bcode, err := ethutil.Compile(data.Get(0).Str(), false)
  26. if err != nil {
  27. c.Write(args(nil, err.Error()), msg.Seed)
  28. }
  29. code := ethutil.Bytes2Hex(bcode)
  30. c.Write(args(code, nil), msg.Seed)
  31. case "getBlockByNumber":
  32. args := msg.Arguments()
  33. block := pipe.BlockByNumber(int32(args.Get(0).Uint()))
  34. c.Write(block, msg.Seed)
  35. case "getKey":
  36. c.Write(pipe.Key().PrivateKey, msg.Seed)
  37. case "transact":
  38. if mp, ok := msg.Args[0].(map[string]interface{}); ok {
  39. object := mapToTxParams(mp)
  40. c.Write(
  41. args(pipe.Transact(object["from"], object["to"], object["value"], object["gas"], object["gasPrice"], object["data"])),
  42. msg.Seed,
  43. )
  44. }
  45. case "getCoinBase":
  46. c.Write(pipe.CoinBase(), msg.Seed)
  47. case "getIsListening":
  48. c.Write(pipe.IsListening(), msg.Seed)
  49. case "getIsMining":
  50. c.Write(pipe.IsMining(), msg.Seed)
  51. case "getPeerCoint":
  52. c.Write(pipe.PeerCount(), msg.Seed)
  53. case "getCountAt":
  54. args := msg.Arguments()
  55. c.Write(pipe.TxCountAt(args.Get(0).Str()), msg.Seed)
  56. case "getCodeAt":
  57. args := msg.Arguments()
  58. c.Write(len(pipe.CodeAt(args.Get(0).Str())), msg.Seed)
  59. case "getBlockByHash":
  60. args := msg.Arguments()
  61. c.Write(pipe.BlockByHash(args.Get(0).Str()), msg.Seed)
  62. case "getStorageAt":
  63. args := msg.Arguments()
  64. c.Write(pipe.StorageAt(args.Get(0).Str(), args.Get(1).Str()), msg.Seed)
  65. case "getBalanceAt":
  66. args := msg.Arguments()
  67. c.Write(pipe.BalanceAt(args.Get(0).Str()), msg.Seed)
  68. case "getSecretToAddress":
  69. args := msg.Arguments()
  70. c.Write(pipe.SecretToAddress(args.Get(0).Str()), msg.Seed)
  71. case "newFilter":
  72. case "newFilterString":
  73. case "messages":
  74. // TODO
  75. }
  76. })
  77. wsServ.Listen()
  78. }
  79. func StartWebSockets(eth *eth.Ethereum) {
  80. sock := NewWebSocketServer(eth)
  81. go sock.Serv()
  82. }
  83. // TODO This is starting to become a generic method. Move to utils
  84. func mapToTxParams(object map[string]interface{}) map[string]string {
  85. // Default values
  86. if object["from"] == nil {
  87. object["from"] = ""
  88. }
  89. if object["to"] == nil {
  90. object["to"] = ""
  91. }
  92. if object["value"] == nil {
  93. object["value"] = ""
  94. }
  95. if object["gas"] == nil {
  96. object["gas"] = ""
  97. }
  98. if object["gasPrice"] == nil {
  99. object["gasPrice"] = ""
  100. }
  101. var dataStr string
  102. var data []string
  103. if str, ok := object["data"].(string); ok {
  104. data = []string{str}
  105. }
  106. for _, str := range data {
  107. if ethutil.IsHex(str) {
  108. str = str[2:]
  109. if len(str) != 64 {
  110. str = ethutil.LeftPadString(str, 64)
  111. }
  112. } else {
  113. str = ethutil.Bytes2Hex(ethutil.LeftPadBytes(ethutil.Big(str).Bytes(), 32))
  114. }
  115. dataStr += str
  116. }
  117. object["data"] = dataStr
  118. conv := make(map[string]string)
  119. for key, value := range object {
  120. if v, ok := value.(string); ok {
  121. conv[key] = v
  122. }
  123. }
  124. return conv
  125. }