aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-10-01 05:26:16 +0800
committerobscuren <geffobscura@gmail.com>2014-10-01 05:26:16 +0800
commit6db40ecb22c28a777f4ab1cd4de5a12e41ac669d (patch)
treed444855839bf2e498dc9c4724928c7eb07cf6c22 /utils
parent41ae6f298e079a073282de001e6b1eaa51472638 (diff)
downloaddexon-6db40ecb22c28a777f4ab1cd4de5a12e41ac669d.tar.gz
dexon-6db40ecb22c28a777f4ab1cd4de5a12e41ac669d.tar.zst
dexon-6db40ecb22c28a777f4ab1cd4de5a12e41ac669d.zip
WebSocket interface
Web sockets handlers fully implemented. Filter handlers have yet to be implemented.
Diffstat (limited to 'utils')
-rw-r--r--utils/websockets.go161
1 files changed, 161 insertions, 0 deletions
diff --git a/utils/websockets.go b/utils/websockets.go
new file mode 100644
index 000000000..e89331a98
--- /dev/null
+++ b/utils/websockets.go
@@ -0,0 +1,161 @@
+package utils
+
+import (
+ "github.com/ethereum/eth-go"
+ "github.com/ethereum/eth-go/ethpipe"
+ "github.com/ethereum/eth-go/ethutil"
+ "github.com/ethereum/eth-go/websocket"
+)
+
+func args(v ...interface{}) []interface{} {
+ return v
+}
+
+type WebSocketServer struct {
+ ethereum *eth.Ethereum
+ filterCallbacks map[int][]int
+}
+
+func NewWebSocketServer(eth *eth.Ethereum) *WebSocketServer {
+ return &WebSocketServer{eth, make(map[int][]int)}
+}
+
+func (self *WebSocketServer) Serv() {
+ pipe := ethpipe.NewJSPipe(self.ethereum)
+
+ wsServ := websocket.NewServer("/eth", ":40404")
+ wsServ.MessageFunc(func(c *websocket.Client, msg *websocket.Message) {
+ switch msg.Call {
+ case "compile":
+ data := ethutil.NewValue(msg.Args)
+ bcode, err := ethutil.Compile(data.Get(0).Str(), false)
+ if err != nil {
+ c.Write(args(nil, err.Error()), msg.Seed)
+ }
+
+ code := ethutil.Bytes2Hex(bcode)
+ c.Write(args(code, nil), msg.Seed)
+ case "getBlockByNumber":
+ args := msg.Arguments()
+
+ block := pipe.BlockByNumber(int32(args.Get(0).Uint()))
+ c.Write(block, msg.Seed)
+
+ case "getKey":
+ c.Write(pipe.Key().PrivateKey, msg.Seed)
+ case "transact":
+ if mp, ok := msg.Args[0].(map[string]interface{}); ok {
+ object := mapToTxParams(mp)
+ c.Write(
+ args(pipe.Transact(object["from"], object["to"], object["value"], object["gas"], object["gasPrice"], object["data"])),
+ msg.Seed,
+ )
+
+ }
+ case "getCoinBase":
+ c.Write(pipe.CoinBase(), msg.Seed)
+
+ case "getIsListening":
+ c.Write(pipe.IsListening(), msg.Seed)
+
+ case "getIsMining":
+ c.Write(pipe.IsMining(), msg.Seed)
+
+ case "getPeerCoint":
+ c.Write(pipe.PeerCount(), msg.Seed)
+
+ case "getCountAt":
+ args := msg.Arguments()
+
+ c.Write(pipe.TxCountAt(args.Get(0).Str()), msg.Seed)
+
+ case "getCodeAt":
+ args := msg.Arguments()
+
+ c.Write(len(pipe.CodeAt(args.Get(0).Str())), msg.Seed)
+
+ case "getBlockByHash":
+ args := msg.Arguments()
+
+ c.Write(pipe.BlockByHash(args.Get(0).Str()), msg.Seed)
+
+ case "getStorageAt":
+ args := msg.Arguments()
+
+ c.Write(pipe.StorageAt(args.Get(0).Str(), args.Get(1).Str()), msg.Seed)
+
+ case "getBalanceAt":
+ args := msg.Arguments()
+
+ c.Write(pipe.BalanceAt(args.Get(0).Str()), msg.Seed)
+
+ case "getSecretToAddress":
+ args := msg.Arguments()
+
+ c.Write(pipe.SecretToAddress(args.Get(0).Str()), msg.Seed)
+
+ case "newFilter":
+ case "newFilterString":
+ case "messages":
+ // TODO
+ }
+
+ })
+
+ wsServ.Listen()
+}
+
+func StartWebSockets(eth *eth.Ethereum) {
+ sock := NewWebSocketServer(eth)
+ go sock.Serv()
+}
+
+// TODO This is starting to become a generic method. Move to utils
+func mapToTxParams(object map[string]interface{}) map[string]string {
+ // Default values
+ if object["from"] == nil {
+ object["from"] = ""
+ }
+ if object["to"] == nil {
+ object["to"] = ""
+ }
+ if object["value"] == nil {
+ object["value"] = ""
+ }
+ if object["gas"] == nil {
+ object["gas"] = ""
+ }
+ if object["gasPrice"] == nil {
+ object["gasPrice"] = ""
+ }
+
+ var dataStr string
+ var data []string
+ if str, ok := object["data"].(string); ok {
+ data = []string{str}
+ }
+
+ for _, str := range data {
+ if ethutil.IsHex(str) {
+ str = str[2:]
+
+ if len(str) != 64 {
+ str = ethutil.LeftPadString(str, 64)
+ }
+ } else {
+ str = ethutil.Bytes2Hex(ethutil.LeftPadBytes(ethutil.Big(str).Bytes(), 32))
+ }
+
+ dataStr += str
+ }
+ object["data"] = dataStr
+
+ conv := make(map[string]string)
+ for key, value := range object {
+ if v, ok := value.(string); ok {
+ conv[key] = v
+ }
+ }
+
+ return conv
+}