Commit 8e0a39f3 authored by obscuren's avatar obscuren

Updated to use ethereum.js

parent df5603de
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
/tmp
*/**/*un~
*un~
.DS_Store
*/**/.DS_Store
ethereum/ethereum
ethereal/ethereal
# Ethereum JavaScript API
This is the Ethereum compatible JavaScript API using `Promise`s
which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC) spec.
For an example see `index.html`.
**Please note this repo is in it's early stage.**
If you'd like to run a WebSocket ethereum node check out
[go-ethereum](https://github.com/ethereum/go-ethereum).
To install ethereum and spawn a node:
```
go get github.com/ethereum/go-ethereum/ethereum
ethereum -ws -loglevel=4
```
(function () {
var HttpRpcProvider = function (host) {
this.handlers = [];
this.host = host;
};
function formatJsonRpcObject(object) {
return {
jsonrpc: '2.0',
method: object.call,
params: object.args,
id: object._id
}
};
function formatJsonRpcMessage(message) {
var object = JSON.parse(message);
return {
_id: object.id,
data: object.result
};
};
HttpRpcProvider.prototype.sendRequest = function (payload, cb) {
var data = formatJsonRpcObject(payload);
var request = new XMLHttpRequest();
request.open("POST", this.host, true);
request.send(JSON.stringify(data));
request.onreadystatechange = function () {
if (request.readyState === 4 && cb) {
cb(request);
}
}
};
HttpRpcProvider.prototype.send = function (payload) {
var self = this;
this.sendRequest(payload, function (request) {
self.handlers.forEach(function (handler) {
handler.call(self, formatJsonRpcMessage(request.responseText));
});
});
};
HttpRpcProvider.prototype.poll = function (payload, id) {
var self = this;
this.sendRequest(payload, function (request) {
var parsed = JSON.parse(request.responseText);
if (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result) {
return;
}
self.handlers.forEach(function (handler) {
handler.call(self, {_event: payload.call, _id: id, data: parsed.result});
});
});
};
Object.defineProperty(HttpRpcProvider.prototype, "onmessage", {
set: function (handler) {
this.handlers.push(handler);
}
});
if (typeof(web3) !== "undefined" && web3.providers !== undefined) {
web3.providers.HttpRpcProvider = HttpRpcProvider;
}
})();
<!doctype>
<html>
<head>
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="websocket.js"></script>
<script type="text/javascript" src="qt.js"></script>
<script type="text/javascript" src="httprpc.js"></script>
<script type="text/javascript">
function registerName() {
var name = document.querySelector("#name").value;
name = web3.fromAscii(name);
var eth = web3.eth;
eth.transact({to: "NameReg", gas: "10000", gasPrice: eth.gasPrice, data: [web3.fromAscii("register"), name]}).then(function(tx) {
document.querySelector("#result").innerHTML = "Registered name. Please wait for the next block to come through.";
}, function(err) {
console.log(err);
});
}
</script>
</head>
<body>
<h1>std::name_reg</h1>
<input type="text" id="name"></input>
<input type="submit" onClick="registerName();"></input>
<div id="result"></div>
</body>
</html>
This diff is collapsed.
(function() {
var QtProvider = function() {
this.handlers = [];
var self = this;
navigator.qt.onmessage = function (message) {
self.handlers.forEach(function (handler) {
handler.call(self, JSON.parse(message.data));
});
}
};
QtProvider.prototype.send = function(payload) {
navigator.qt.postMessage(JSON.stringify(payload));
};
Object.defineProperty(QtProvider.prototype, "onmessage", {
set: function(handler) {
this.handlers.push(handler);
},
});
if(typeof(web3) !== "undefined" && web3.providers !== undefined) {
web3.providers.QtProvider = QtProvider;
}
})();
(function() {
var WebSocketProvider = function(host) {
// onmessage handlers
this.handlers = [];
// queue will be filled with messages if send is invoked before the ws is ready
this.queued = [];
this.ready = false;
this.ws = new WebSocket(host);
var self = this;
this.ws.onmessage = function(event) {
for(var i = 0; i < self.handlers.length; i++) {
self.handlers[i].call(self, JSON.parse(event.data), event)
}
};
this.ws.onopen = function() {
self.ready = true;
for(var i = 0; i < self.queued.length; i++) {
// Resend
self.send(self.queued[i]);
}
};
};
WebSocketProvider.prototype.send = function(payload) {
if(this.ready) {
var data = JSON.stringify(payload);
this.ws.send(data);
} else {
this.queued.push(payload);
}
};
WebSocketProvider.prototype.onMessage = function(handler) {
this.handlers.push(handler);
};
WebSocketProvider.prototype.unload = function() {
this.ws.close();
};
Object.defineProperty(WebSocketProvider.prototype, "onmessage", {
set: function(provider) { this.onMessage(provider); }
});
if(typeof(web3) !== "undefined" && web3.providers !== undefined) {
web3.providers.WebSocketProvider = WebSocketProvider;
}
})();
(function() {
if (typeof(Promise) === "undefined")
window.Promise = Q.Promise;
var eth = web3.eth;
web3.setProvider(new web3.providers.QtProvider());
})()
......@@ -155,7 +155,8 @@ Rectangle {
experimental.preferences.javascriptEnabled: true
experimental.preferences.navigatorQtObjectEnabled: true
experimental.preferences.developerExtrasEnabled: true
experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
//experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
experimental.userScripts: ["../ext/q.js", "../ext/eth.js/main.js", "../ext/eth.js/qt.js", "../ext/setup.js"]
experimental.onMessageReceived: {
console.log("[onMessageReceived]: ", message.data)
// TODO move to messaging.js
......@@ -164,51 +165,88 @@ Rectangle {
try {
switch(data.call) {
case "compile":
postData(data._seed, eth.compile(data.args[0]))
postData(data._id, eth.compile(data.args[0]))
break
case "getCoinBase":
postData(data._seed, eth.coinBase())
case "coinbase":
postData(data._id, eth.coinBase())
break
case "account":
postData(data._id, eth.key().address);
case "getIsListening":
postData(data._seed, eth.isListening())
case "isListening":
postData(data._id, eth.isListening())
break
case "getIsMining":
postData(data._seed, eth.isMining())
case "isMining":
postData(data._id, eth.isMining())
break
case "getPeerCount":
postData(data._seed, eth.peerCount())
case "peerCount":
postData(data._id, eth.peerCount())
break
case "getCountAt":
case "countAt":
require(1)
postData(data._seed, eth.txCountAt(data.args[0]))
postData(data._id, eth.txCountAt(data.args[0]))
break
case "getCodeAt":
case "codeAt":
require(1)
var code = eth.codeAt(data.args[0])
postData(data._seed, code);
postData(data._id, code);
break
case "getBlockByNumber":
case "blockByNumber":
require(1)
var block = eth.blockByNumber(data.args[0])
postData(data._seed, block)
postData(data._id, block)
break
case "blockByHash":
require(1)
var block = eth.blockByHash(data.args[0])
postData(data._id, block)
break
case "getBlockByHash":
require(2)
var block = eth.blockByHash(data.args[0])
postData(data._seed, block)
postData(data._id, block.transactions[data.args[1]])
break
case "transactionByHash":
case "transactionByNumber":
require(2)
var block;
if (data.call === "transactionByHash")
block = eth.blockByHash(data.args[0])
else
block = eth.blockByNumber(data.args[0])
var tx = block.transactions.get(data.args[1])
postData(data._id, tx)
break
case "uncleByHash":
case "uncleByNumber":
require(2)
var block;
if (data.call === "uncleByHash")
block = eth.blockByHash(data.args[0])
else
block = eth.blockByNumber(data.args[0])
var uncle = block.uncles.get(data.args[1])
postData(data._id, uncle)
break
......@@ -216,50 +254,28 @@ Rectangle {
require(5)
var tx = eth.transact(data.args)
postData(data._seed, tx)
postData(data._id, tx)
break
case "getStorageAt":
case "stateAt":
require(2);
var storage = eth.storageAt(data.args[0], data.args[1]);
postData(data._seed, storage)
postData(data._id, storage)
break
case "call":
require(1);
var ret = eth.call(data.args)
postData(data._seed, ret)
break
case "getEachStorage":
require(1);
var storage = JSON.parse(eth.eachStorage(data.args[0]))
postData(data._seed, storage)
break
case "getTransactionsFor":
require(1);
var txs = eth.transactionsFor(data.args[0], true)
postData(data._seed, txs)
postData(data._id, ret)
break
case "getBalanceAt":
case "balanceAt":
require(1);
postData(data._seed, eth.balanceAt(data.args[0]));
break
case "getKey":
var key = eth.key().privateKey;
postData(data._seed, key)
postData(data._id, eth.balanceAt(data.args[0]));
break
case "watch":
......@@ -268,45 +284,34 @@ Rectangle {
case "disconnect":
require(1)
postData(data._seed, null)
break;
case "getSecretToAddress":
require(1)
var addr = eth.secretToAddress(data.args[0])
console.log("getsecret", addr)
postData(data._seed, addr)
postData(data._id, null)
break;
case "messages":
require(1);
var messages = JSON.parse(eth.getMessages(data.args[0]))
postData(data._seed, messages)
postData(data._id, messages)
break
case "mutan":
require(1)
var code = eth.compileMutan(data.args[0])
postData(data._seed, "0x"+code)
postData(data._id, "0x"+code)
break;
case "newFilterString":
require(1)
var id = eth.newFilterString(data.args[0])
postData(data._seed, id);
postData(data._id, id);
break;
case "newFilter":
require(1)
var id = eth.newFilter(data.args[0])
postData(data._seed, id);
postData(data._id, id);
break;
case "getMessages":
......@@ -314,7 +319,7 @@ Rectangle {
var messages = eth.messages(data.args[0]);
var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
postData(data._seed, m);
postData(data._id, m);
break;
......@@ -326,13 +331,13 @@ Rectangle {
} catch(e) {
console.log(data.call + ": " + e)
postData(data._seed, null);
postData(data._id, null);
}
}
function post(seed, data) {
postData(data._seed, data)
postData(data._id, data)
}
function require(args, num) {
......@@ -341,7 +346,7 @@ Rectangle {
}
}
function postData(seed, data) {
webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
webview.experimental.postMessage(JSON.stringify({data: data, _id: seed}))
}
function postEvent(event, data) {
webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
......
......@@ -90,7 +90,7 @@ func (self *Filter) Find() []*ethstate.Message {
for i := 0; !quit && block != nil; i++ {
// Quit on latest
switch {
case block.Number.Uint64() == earliestBlockNo:
case block.Number.Uint64() == earliestBlockNo, block.Number.Uint64() == 0:
quit = true
case self.max <= len(messages):
break
......
......@@ -194,7 +194,7 @@ done:
}
// Notify all subscribers
self.eth.EventMux().Post(TxPostEvent{tx})
go self.eth.EventMux().Post(TxPostEvent{tx})
receipts = append(receipts, receipt)
handled = append(handled, tx)
......
......@@ -19,6 +19,7 @@ type JSBlock struct {
Number int `json:"number"`
Hash string `json:"hash"`
Transactions *ethutil.List `json:"transactions"`
Uncles *ethutil.List `json:"uncles"`
Time int64 `json:"time"`
Coinbase string `json:"coinbase"`
Name string `json:"name"`
......@@ -33,18 +34,24 @@ func NewJSBlock(block *ethchain.Block) *JSBlock {
return &JSBlock{}
}
var ptxs []*JSTransaction
for _, tx := range block.Transactions() {
ptxs = append(ptxs, NewJSTx(tx, block.State()))
ptxs := make([]*JSTransaction, len(block.Transactions()))
for i, tx := range block.Transactions() {
ptxs[i] = NewJSTx(tx, block.State())
}
txlist := ethutil.NewList(ptxs)
list := ethutil.NewList(ptxs)
puncles := make([]*JSBlock, len(block.Uncles))
for i, uncle := range block.Uncles {
puncles[i] = NewJSBlock(uncle)
}
ulist := ethutil.NewList(puncles)
return &JSBlock{
ref: block, Size: block.Size().String(),
Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(),
GasLimit: block.GasLimit.String(), Hash: ethutil.Bytes2Hex(block.Hash()),
Transactions: list, Time: block.Time,
Transactions: txlist, Uncles: ulist,
Time: block.Time,
Coinbase: ethutil.Bytes2Hex(block.Coinbase),
PrevHash: ethutil.Bytes2Hex(block.PrevHash),
}
......
......@@ -69,7 +69,8 @@ func (self *List) Interface() interface{} {
// For JavaScript <3
func (self *List) ToJSON() string {
var list []interface{}
// make(T, 0) != nil
list := make([]interface{}, 0)
for i := 0; i < self.Length; i++ {
list = append(list, self.Get(i))
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment