Re-wrote ethereum.js
This commit is contained in:
parent
8585e59718
commit
b4bd70c402
@ -221,7 +221,7 @@ ApplicationWindow {
|
||||
}
|
||||
height: parent.height
|
||||
width: 300
|
||||
TableViewColumn{ role: "value" ; title: "Temp" ; width: 200 }
|
||||
TableViewColumn{ role: "value" ; title: "Local VM stack" ; width: stackTableView.width - 2 }
|
||||
model: stackModel
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ ApplicationWindow {
|
||||
height: parent.height
|
||||
width: parent.width - stackTableView.width
|
||||
TableViewColumn{ id:mnumColmn ; role: "num" ; title: "#" ; width: 50 }
|
||||
TableViewColumn{ role: "value" ; title: "Memory" ; width: 750 }
|
||||
TableViewColumn{ role: "value" ; title: "Memory" ; width: 650 }
|
||||
model: memModel
|
||||
}
|
||||
}
|
||||
@ -248,8 +248,8 @@ ApplicationWindow {
|
||||
}
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
TableViewColumn{ id: key ; role: "key" ; title: "#" ; width: storageTableView.width / 2}
|
||||
TableViewColumn{ role: "value" ; title: "Storage" ; width: storageTableView.width / 2}
|
||||
TableViewColumn{ id: key ; role: "key" ; title: "#" ; width: storageTableView.width / 2 - 1}
|
||||
TableViewColumn{ role: "value" ; title: "Storage" ; width: storageTableView.width / 2 - 1}
|
||||
model: storageModel
|
||||
}
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ Filter.prototype.changed = function(callback) {
|
||||
this.callbacks.push(callback);
|
||||
|
||||
var self = this;
|
||||
message.connect(function(messages, id) {
|
||||
messages.connect(function(messages, id) {
|
||||
if(id == self.id) {
|
||||
for(var i = 0; i < self.callbacks.length; i++) {
|
||||
self.callbacks[i].call(self, messages);
|
||||
}
|
||||
for(var i = 0; i < self.callbacks.length; i++) {
|
||||
self.callbacks[i].call(self, messages);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -12,15 +12,46 @@
|
||||
|
||||
window.eth = {
|
||||
_callbacks: {},
|
||||
_onCallbacks: {},
|
||||
_events: {},
|
||||
prototype: Object(),
|
||||
|
||||
coinbase: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getCoinBase"}, function(coinbase) {
|
||||
resolve(coinbase);
|
||||
});
|
||||
});
|
||||
toHex: function(str) {
|
||||
var hex = "";
|
||||
for(var i = 0; i < str.length; i++) {
|
||||
var n = str.charCodeAt(i).toString(16);
|
||||
hex += n.length < 2 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return hex;
|
||||
},
|
||||
|
||||
toAscii: function(hex) {
|
||||
// Find termination
|
||||
var str = "";
|
||||
var i = 0, l = hex.length;
|
||||
for(; i < l; i+=2) {
|
||||
var code = hex.charCodeAt(i)
|
||||
if(code == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
fromAscii: function(str, pad) {
|
||||
if(pad === undefined) {
|
||||
pad = 32
|
||||
}
|
||||
|
||||
var hex = this.toHex(str);
|
||||
|
||||
while(hex.length < pad*2)
|
||||
hex += "00";
|
||||
|
||||
return hex
|
||||
},
|
||||
|
||||
block: function(numberOrHash) {
|
||||
@ -107,17 +138,316 @@
|
||||
});
|
||||
},
|
||||
|
||||
key: function() {
|
||||
balanceAt: function(address) {
|
||||
var promises = [];
|
||||
|
||||
if(isPromise(address)) {
|
||||
promises.push(address.then(function(_address) { address = _address; }));
|
||||
}
|
||||
|
||||
return Q.all(promises).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getBalanceAt", args: [address]}, function(balance) {
|
||||
resolve(balance);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
countAt: function(address) {
|
||||
var promises = [];
|
||||
|
||||
if(isPromise(address)) {
|
||||
promises.push(address.then(function(_address) { address = _address; }));
|
||||
}
|
||||
|
||||
return Q.all(promises).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getCountAt", args: [address]}, function(count) {
|
||||
resolve(count);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
codeAt: function(address) {
|
||||
var promises = [];
|
||||
|
||||
if(isPromise(address)) {
|
||||
promises.push(address.then(function(_address) { address = _address; }));
|
||||
}
|
||||
|
||||
return Q.all(promises).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getCodeAt", args: [address]}, function(code) {
|
||||
resolve(code);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
storageAt: function(address, storageAddress) {
|
||||
var promises = [];
|
||||
|
||||
if(isPromise(address)) {
|
||||
promises.push(address.then(function(_address) { address = _address; }));
|
||||
}
|
||||
|
||||
if(isPromise(storageAddress)) {
|
||||
promises.push(storageAddress.then(function(_sa) { storageAddress = _sa; }));
|
||||
}
|
||||
|
||||
return Q.all(promises).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getStorageAt", args: [address, storageAddress]}, function(entry) {
|
||||
resolve(entry);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
stateAt: function(address, storageAddress) {
|
||||
return this.storageAt(address, storageAddress);
|
||||
},
|
||||
|
||||
call: function(params) {
|
||||
if(params === undefined) {
|
||||
params = {};
|
||||
}
|
||||
|
||||
if(params.endowment !== undefined)
|
||||
params.value = params.endowment;
|
||||
if(params.code !== undefined)
|
||||
params.data = params.code;
|
||||
|
||||
|
||||
var promises = []
|
||||
if(isPromise(params.to)) {
|
||||
promises.push(params.to.then(function(_to) { params.to = _to; }));
|
||||
}
|
||||
if(isPromise(params.from)) {
|
||||
promises.push(params.from.then(function(_from) { params.from = _from; }));
|
||||
}
|
||||
|
||||
if(isPromise(params.data)) {
|
||||
promises.push(params.data.then(function(_code) { params.data = _code; }));
|
||||
} else {
|
||||
if(typeof params.data === "object") {
|
||||
data = "";
|
||||
for(var i = 0; i < params.data.length; i++) {
|
||||
data += params.data[i]
|
||||
}
|
||||
} else {
|
||||
data = params.data;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure everything is string
|
||||
var fields = ["value", "gas", "gasPrice"];
|
||||
for(var i = 0; i < fields.length; i++) {
|
||||
if(params[fields[i]] === undefined) {
|
||||
params[fields[i]] = "";
|
||||
}
|
||||
params[fields[i]] = params[fields[i]].toString();
|
||||
}
|
||||
|
||||
// Load promises then call the last "transact".
|
||||
return Q.all(promises).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "call", args: params}, function(data) {
|
||||
if(data[1])
|
||||
reject(data[0]);
|
||||
else
|
||||
resolve(data[0]);
|
||||
});
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
watch: function(params) {
|
||||
return new Filter(params);
|
||||
},
|
||||
|
||||
secretToAddress: function(key) {
|
||||
var promises = [];
|
||||
if(isPromise(key)) {
|
||||
promises.push(key.then(function(_key) { key = _key; }));
|
||||
}
|
||||
|
||||
return Q.all(promises).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getSecretToAddress", args: [key]}, function(address) {
|
||||
resolve(address);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
on: function(event, cb) {
|
||||
if(eth._events[event] === undefined) {
|
||||
eth._events[event] = [];
|
||||
}
|
||||
|
||||
eth._events[event].push(cb);
|
||||
|
||||
return this
|
||||
},
|
||||
|
||||
off: function(event, cb) {
|
||||
if(eth._events[event] !== undefined) {
|
||||
var callbacks = eth._events[event];
|
||||
for(var i = 0; i < callbacks.length; i++) {
|
||||
if(callbacks[i] === cb) {
|
||||
delete callbacks[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
},
|
||||
|
||||
trigger: function(event, data) {
|
||||
var callbacks = eth._events[event];
|
||||
if(callbacks !== undefined) {
|
||||
for(var i = 0; i < callbacks.length; i++) {
|
||||
// Figure out whether the returned data was an array
|
||||
// array means multiple return arguments (multiple params)
|
||||
if(data instanceof Array) {
|
||||
callbacks[i].apply(this, data);
|
||||
} else {
|
||||
callbacks[i].call(this, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Eth object properties
|
||||
Object.defineProperty(eth, "key", {
|
||||
get: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getKey"}, function(k) {
|
||||
resolve(k);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(eth, "gasPrice", {
|
||||
get: function() {
|
||||
return "1000000000000"
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(eth, "coinbase", {
|
||||
get: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getCoinBase"}, function(coinbase) {
|
||||
resolve(coinbase);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(eth, "listening", {
|
||||
get: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getIsListening"}, function(listening) {
|
||||
resolve(listening);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Object.defineProperty(eth, "mining", {
|
||||
get: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getIsMining"}, function(mining) {
|
||||
resolve(mining);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(eth, "peerCount", {
|
||||
get: function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getPeerCount"}, function(peerCount) {
|
||||
resolve(peerCount);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
var filters = [];
|
||||
var Filter = function(options) {
|
||||
filters.push(this);
|
||||
|
||||
this.callbacks = [];
|
||||
this.options = options;
|
||||
|
||||
var call;
|
||||
if(options === "chain") {
|
||||
call = "newFilterString"
|
||||
} else if(typeof options === "object") {
|
||||
call = "newFilter"
|
||||
}
|
||||
|
||||
var self = this; // Cheaper than binding
|
||||
this.promise = new Promise(function(resolve, reject) {
|
||||
postData({call: call, args: [options]}, function(id) {
|
||||
self.id = id;
|
||||
|
||||
resolve(id);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Filter.prototype.changed = function(callback) {
|
||||
var self = this;
|
||||
this.promise.then(function(id) {
|
||||
self.callbacks.push(callback);
|
||||
});
|
||||
};
|
||||
|
||||
Filter.prototype.trigger = function(messages, id) {
|
||||
if(id == this.id) {
|
||||
for(var i = 0; i < this.callbacks.length; i++) {
|
||||
this.callbacks[i].call(this, messages);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Filter.prototype.uninstall = function() {
|
||||
this.promise.then(function(id) {
|
||||
postData({call: "uninstallFilter", args:[id]});
|
||||
});
|
||||
};
|
||||
|
||||
Filter.prototype.messages = function() {
|
||||
var self=this;
|
||||
return Q.all([this.promise]).then(function() {
|
||||
var id = self.id
|
||||
return new Promise(function(resolve, reject) {
|
||||
postData({call: "getMessages", args: [id]}, function(messages) {
|
||||
resolve(messages);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Register to the messages callback. "messages" will be emitted when new messages
|
||||
// from the client have been created.
|
||||
eth.on("messages", function(messages, id) {
|
||||
for(var i = 0; i < filters.length; i++) {
|
||||
filters[i].trigger(messages, id);
|
||||
}
|
||||
});
|
||||
|
||||
var g_seed = 1;
|
||||
function postData(data, cb) {
|
||||
data._seed = Math.floor(Math.random() * 1000000)
|
||||
data._seed = g_seed;
|
||||
if(cb) {
|
||||
eth._callbacks[data._seed] = cb;
|
||||
}
|
||||
@ -126,6 +456,8 @@
|
||||
data.args = [];
|
||||
}
|
||||
|
||||
g_seed++;
|
||||
|
||||
navigator.qt.postMessage(JSON.stringify(data));
|
||||
}
|
||||
|
||||
|
@ -1,41 +1,3 @@
|
||||
// Helper function for generating pseudo callbacks and sending data to the QML part of the application
|
||||
function postData(data, cb) {
|
||||
data._seed = Math.floor(Math.random() * 1000000)
|
||||
if(cb) {
|
||||
eth._callbacks[data._seed] = cb;
|
||||
}
|
||||
|
||||
if(data.args === undefined) {
|
||||
data.args = [];
|
||||
}
|
||||
|
||||
navigator.qt.postMessage(JSON.stringify(data));
|
||||
}
|
||||
|
||||
navigator.qt.onmessage = function(ev) {
|
||||
var data = JSON.parse(ev.data)
|
||||
|
||||
if(data._event !== undefined) {
|
||||
eth.trigger(data._event, data.data);
|
||||
} else {
|
||||
if(data._seed) {
|
||||
var cb = eth._callbacks[data._seed];
|
||||
if(cb) {
|
||||
// Figure out whether the returned data was an array
|
||||
// array means multiple return arguments (multiple params)
|
||||
if(data.data instanceof Array) {
|
||||
cb.apply(this, data.data)
|
||||
} else {
|
||||
cb.call(this, data.data)
|
||||
}
|
||||
|
||||
// Remove the "trigger" callback
|
||||
delete eth._callbacks[ev._seed];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof(Promise) === "undefined") {
|
||||
window.Promise = Q.Promise;
|
||||
}
|
||||
|
@ -14,20 +14,22 @@ ApplicationWindow {
|
||||
|
||||
property alias miningButtonText: miningButton.text
|
||||
property var ethx : Eth.ethx
|
||||
property var web
|
||||
|
||||
width: 900
|
||||
height: 600
|
||||
width: 1024
|
||||
height: 750
|
||||
minimumHeight: 300
|
||||
|
||||
title: "Mist"
|
||||
|
||||
// This signal is used by the filter API. The filter API connects using this signal handler from
|
||||
// the different QML files and plugins.
|
||||
signal message(var callback, int seed);
|
||||
signal messages(var messages, int id);
|
||||
function invokeFilterCallback(data, receiverSeed) {
|
||||
//var messages = JSON.parse(data)
|
||||
// Signal handler
|
||||
message(data, receiverSeed);
|
||||
messages(data, receiverSeed);
|
||||
root.web.messages(data, receiverSeed);
|
||||
}
|
||||
|
||||
TextField {
|
||||
@ -44,7 +46,7 @@ ApplicationWindow {
|
||||
// Takes care of loading all default plugins
|
||||
Component.onCompleted: {
|
||||
addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
||||
addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
||||
root.web = addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
||||
|
||||
addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"});
|
||||
addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"});
|
||||
|
@ -10,265 +10,279 @@ import Ethereum 1.0
|
||||
import "../ext/qml_messaging.js" as Messaging
|
||||
|
||||
//ApplicationWindow {
|
||||
Rectangle {
|
||||
id: window
|
||||
property var title: "Browser"
|
||||
property var iconSource: "../browser.png"
|
||||
property var menuItem
|
||||
Rectangle {
|
||||
id: window
|
||||
property var title: "Browser"
|
||||
property var iconSource: "../browser.png"
|
||||
property var menuItem
|
||||
|
||||
property alias url: webview.url
|
||||
property alias webView: webview
|
||||
property alias url: webview.url
|
||||
property alias webView: webview
|
||||
|
||||
Component.onCompleted: {
|
||||
webview.url = "http://etherian.io"
|
||||
}
|
||||
|
||||
Item {
|
||||
objectName: "root"
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
state: "inspectorShown"
|
||||
|
||||
RowLayout {
|
||||
id: navBar
|
||||
height: 40
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: 7
|
||||
}
|
||||
|
||||
Button {
|
||||
id: back
|
||||
onClicked: {
|
||||
webview.goBack()
|
||||
}
|
||||
style: ButtonStyle {
|
||||
background: Image {
|
||||
source: "../back.png"
|
||||
width: 30
|
||||
height: 30
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextField {
|
||||
anchors {
|
||||
left: back.right
|
||||
right: toggleInspector.left
|
||||
leftMargin: 5
|
||||
rightMargin: 5
|
||||
}
|
||||
text: "http://etherian.io"
|
||||
id: uriNav
|
||||
y: parent.height / 2 - this.height / 2
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
webview.url = this.text;
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: toggleInspector
|
||||
anchors {
|
||||
right: parent.right
|
||||
}
|
||||
iconSource: "../bug.png"
|
||||
onClicked: {
|
||||
if(inspector.visible == true){
|
||||
inspector.visible = false
|
||||
}else{
|
||||
inspector.visible = true
|
||||
inspector.url = webview.experimental.remoteInspectorUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
webview.url = "http://etherian.io"
|
||||
}
|
||||
|
||||
signal messages(var messages, int id);
|
||||
onMessages: {
|
||||
// Bit of a cheat to get proper JSON
|
||||
var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
|
||||
webview.postEvent("messages", [m, id]);
|
||||
}
|
||||
|
||||
WebView {
|
||||
objectName: "webView"
|
||||
id: webview
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
top: navBar.bottom
|
||||
}
|
||||
Item {
|
||||
objectName: "root"
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
state: "inspectorShown"
|
||||
|
||||
property var cleanPath: false
|
||||
onNavigationRequested: {
|
||||
if(!this.cleanPath) {
|
||||
var uri = request.url.toString();
|
||||
if(!/.*\:\/\/.*/.test(uri)) {
|
||||
uri = "http://" + uri;
|
||||
RowLayout {
|
||||
id: navBar
|
||||
height: 40
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: 7
|
||||
}
|
||||
|
||||
Button {
|
||||
id: back
|
||||
onClicked: {
|
||||
webview.goBack()
|
||||
}
|
||||
|
||||
var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
|
||||
|
||||
if(reg.test(uri)) {
|
||||
uri.replace(reg, function(match, pre, domain, path) {
|
||||
uri = pre;
|
||||
|
||||
var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
|
||||
var ip = [];
|
||||
for(var i = 0, l = lookup.length; i < l; i++) {
|
||||
ip.push(lookup.charCodeAt(i))
|
||||
}
|
||||
|
||||
if(ip.length != 0) {
|
||||
uri += lookup;
|
||||
} else {
|
||||
uri += domain;
|
||||
}
|
||||
|
||||
uri += path;
|
||||
});
|
||||
style: ButtonStyle {
|
||||
background: Image {
|
||||
source: "../back.png"
|
||||
width: 30
|
||||
height: 30
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.cleanPath = true;
|
||||
TextField {
|
||||
anchors {
|
||||
left: back.right
|
||||
right: toggleInspector.left
|
||||
leftMargin: 5
|
||||
rightMargin: 5
|
||||
}
|
||||
text: "http://etherian.io"
|
||||
id: uriNav
|
||||
y: parent.height / 2 - this.height / 2
|
||||
|
||||
webview.url = uri;
|
||||
} else {
|
||||
// Prevent inf loop.
|
||||
this.cleanPath = false;
|
||||
Keys.onReturnPressed: {
|
||||
webview.url = this.text;
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: toggleInspector
|
||||
anchors {
|
||||
right: parent.right
|
||||
}
|
||||
iconSource: "../bug.png"
|
||||
onClicked: {
|
||||
if(inspector.visible == true){
|
||||
inspector.visible = false
|
||||
}else{
|
||||
inspector.visible = true
|
||||
inspector.url = webview.experimental.remoteInspectorUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage(data) {
|
||||
//this.experimental.evaluateJavaScript("window.____returnData="+JSON.stringify(data));
|
||||
webview.experimental.postMessage(JSON.stringify(data))
|
||||
}
|
||||
|
||||
onTitleChanged: {
|
||||
var data = Messaging.HandleMessage(title);
|
||||
if(data) {
|
||||
sendMessage(data)
|
||||
WebView {
|
||||
objectName: "webView"
|
||||
id: webview
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
top: navBar.bottom
|
||||
}
|
||||
}
|
||||
|
||||
experimental.preferences.javascriptEnabled: true
|
||||
experimental.preferences.navigatorQtObjectEnabled: true
|
||||
experimental.preferences.developerExtrasEnabled: true
|
||||
experimental.userScripts: ["../ext/q.js", "../ext/pre.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
|
||||
experimental.onMessageReceived: {
|
||||
console.log("[onMessageReceived]: ", message.data)
|
||||
// TODO move to messaging.js
|
||||
var data = JSON.parse(message.data)
|
||||
property var cleanPath: false
|
||||
onNavigationRequested: {
|
||||
if(!this.cleanPath) {
|
||||
var uri = request.url.toString();
|
||||
if(!/.*\:\/\/.*/.test(uri)) {
|
||||
uri = "http://" + uri;
|
||||
}
|
||||
|
||||
try {
|
||||
switch(data.call) {
|
||||
case "compile":
|
||||
postData(data._seed, eth.compile(data.args[0]))
|
||||
break
|
||||
var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
|
||||
|
||||
case "getCoinBase":
|
||||
postData(data._seed, eth.coinBase())
|
||||
if(reg.test(uri)) {
|
||||
uri.replace(reg, function(match, pre, domain, path) {
|
||||
uri = pre;
|
||||
|
||||
break
|
||||
var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
|
||||
var ip = [];
|
||||
for(var i = 0, l = lookup.length; i < l; i++) {
|
||||
ip.push(lookup.charCodeAt(i))
|
||||
}
|
||||
|
||||
case "getIsListening":
|
||||
postData(data._seed, eth.isListening())
|
||||
if(ip.length != 0) {
|
||||
uri += lookup;
|
||||
} else {
|
||||
uri += domain;
|
||||
}
|
||||
|
||||
break
|
||||
uri += path;
|
||||
});
|
||||
}
|
||||
|
||||
case "getIsMining":
|
||||
postData(data._seed, eth.isMining())
|
||||
this.cleanPath = true;
|
||||
|
||||
break
|
||||
webview.url = uri;
|
||||
} else {
|
||||
// Prevent inf loop.
|
||||
this.cleanPath = false;
|
||||
}
|
||||
}
|
||||
|
||||
case "getPeerCount":
|
||||
postData(data._seed, eth.peerCount())
|
||||
function sendMessage(data) {
|
||||
webview.experimental.postMessage(JSON.stringify(data))
|
||||
}
|
||||
|
||||
break
|
||||
onTitleChanged: {
|
||||
var data = Messaging.HandleMessage(title);
|
||||
if(data) {
|
||||
sendMessage(data)
|
||||
}
|
||||
}
|
||||
|
||||
case "getTxCountAt":
|
||||
require(1)
|
||||
postData(data._seed, eth.txCountAt(data.args[0]))
|
||||
experimental.preferences.javascriptEnabled: true
|
||||
experimental.preferences.navigatorQtObjectEnabled: true
|
||||
experimental.preferences.developerExtrasEnabled: true
|
||||
experimental.userScripts: ["../ext/q.js", "../ext/pre.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
|
||||
experimental.onMessageReceived: {
|
||||
console.log("[onMessageReceived]: ", message.data)
|
||||
// TODO move to messaging.js
|
||||
var data = JSON.parse(message.data)
|
||||
|
||||
break
|
||||
try {
|
||||
switch(data.call) {
|
||||
case "compile":
|
||||
postData(data._seed, eth.compile(data.args[0]))
|
||||
break
|
||||
|
||||
case "getBlockByNumber":
|
||||
var block = eth.blockByNumber(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
|
||||
case "getBlockByHash":
|
||||
var block = eth.blockByHash(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
|
||||
case "transact":
|
||||
require(5)
|
||||
|
||||
var tx = eth.transact(data.args)
|
||||
console.log("transactx", tx)
|
||||
postData(data._seed, tx)
|
||||
|
||||
break
|
||||
|
||||
case "getStorage":
|
||||
require(2);
|
||||
|
||||
var stateObject = eth.stateObject(data.args[0])
|
||||
var storage = stateObject.storageAt(data.args[1])
|
||||
postData(data._seed, storage)
|
||||
|
||||
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)
|
||||
|
||||
break
|
||||
|
||||
case "getBalance":
|
||||
require(1);
|
||||
|
||||
postData(data._seed, eth.stateObject(data.args[0]).value());
|
||||
|
||||
break
|
||||
|
||||
case "getKey":
|
||||
var key = eth.key().privateKey;
|
||||
|
||||
postData(data._seed, key)
|
||||
break
|
||||
|
||||
/*
|
||||
case "watch":
|
||||
require(1)
|
||||
eth.watch(data.args[0], data.args[1]);
|
||||
case "getCoinBase":
|
||||
postData(data._seed, eth.coinBase())
|
||||
|
||||
break
|
||||
*/
|
||||
case "watch":
|
||||
require(2)
|
||||
|
||||
case "getIsListening":
|
||||
postData(data._seed, eth.isListening())
|
||||
|
||||
break
|
||||
|
||||
case "getIsMining":
|
||||
postData(data._seed, eth.isMining())
|
||||
|
||||
break
|
||||
|
||||
case "getPeerCount":
|
||||
postData(data._seed, eth.peerCount())
|
||||
|
||||
break
|
||||
|
||||
case "getCountAt":
|
||||
require(1)
|
||||
postData(data._seed, eth.txCountAt(data.args[0]))
|
||||
|
||||
break
|
||||
|
||||
case "getCodeAt":
|
||||
require(1)
|
||||
var code = eth.codeAt(data.args[0])
|
||||
postData(data._seed, code);
|
||||
|
||||
break
|
||||
|
||||
case "getBlockByNumber":
|
||||
var block = eth.blockByNumber(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
|
||||
case "getBlockByHash":
|
||||
var block = eth.blockByHash(data.args[0])
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
|
||||
case "transact":
|
||||
require(5)
|
||||
|
||||
var tx = eth.transact(data.args)
|
||||
postData(data._seed, tx)
|
||||
|
||||
break
|
||||
|
||||
case "getStorageAt":
|
||||
require(2);
|
||||
|
||||
var storage = eth.storageAt(data.args[0], data.args[1]);
|
||||
postData(data._seed, 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)
|
||||
|
||||
break
|
||||
|
||||
case "getBalanceAt":
|
||||
require(1);
|
||||
|
||||
postData(data._seed, eth.balanceAt(data.args[0]));
|
||||
|
||||
break
|
||||
|
||||
case "getKey":
|
||||
var key = eth.key().privateKey;
|
||||
|
||||
postData(data._seed, key)
|
||||
break
|
||||
|
||||
case "watch":
|
||||
require(2)
|
||||
eth.watch(data.args[0], data.args[1])
|
||||
|
||||
case "disconnect":
|
||||
require(1)
|
||||
postData(data._seed, null)
|
||||
case "disconnect":
|
||||
require(1)
|
||||
postData(data._seed, null)
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case "getSecretToAddress":
|
||||
require(1)
|
||||
postData(data._seed, eth.secretToAddress(data.args[0]))
|
||||
case "getSecretToAddress":
|
||||
require(1)
|
||||
|
||||
break;
|
||||
var addr = eth.secretToAddress(data.args[0])
|
||||
console.log("getsecret", addr)
|
||||
postData(data._seed, addr)
|
||||
|
||||
case "messages":
|
||||
break;
|
||||
|
||||
case "messages":
|
||||
require(1);
|
||||
|
||||
var messages = JSON.parse(eth.getMessages(data.args[0]))
|
||||
@ -276,94 +290,120 @@ Rectangle {
|
||||
|
||||
break
|
||||
|
||||
case "mutan":
|
||||
case "mutan":
|
||||
require(1)
|
||||
|
||||
var code = eth.compileMutan(data.args[0])
|
||||
postData(data._seed, "0x"+code)
|
||||
|
||||
break;
|
||||
|
||||
case "newFilterString":
|
||||
require(1)
|
||||
var id = eth.newFilterString(data.args[0])
|
||||
postData(data._seed, id);
|
||||
break;
|
||||
case "newFilter":
|
||||
require(1)
|
||||
var id = eth.newFilter(data.args[0])
|
||||
|
||||
postData(data._seed, id);
|
||||
break;
|
||||
|
||||
case "getMessages":
|
||||
require(1);
|
||||
|
||||
var messages = eth.messages(data.args[0]);
|
||||
var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
|
||||
postData(data._seed, m);
|
||||
|
||||
break;
|
||||
|
||||
case "deleteFilter":
|
||||
require(1);
|
||||
eth.uninstallFilter(data.args[0])
|
||||
break;
|
||||
}
|
||||
} catch(e) {
|
||||
console.log(data.call + ": " + e)
|
||||
|
||||
postData(data._seed, null);
|
||||
}
|
||||
} catch(e) {
|
||||
console.log(data.call + ": " + e)
|
||||
}
|
||||
|
||||
postData(data._seed, null);
|
||||
|
||||
function post(seed, data) {
|
||||
postData(data._seed, data)
|
||||
}
|
||||
|
||||
function require(args, num) {
|
||||
if(args.length < num) {
|
||||
throw("required argument count of "+num+" got "+args.length);
|
||||
}
|
||||
}
|
||||
function postData(seed, data) {
|
||||
webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
|
||||
}
|
||||
function postEvent(event, data) {
|
||||
webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
|
||||
}
|
||||
|
||||
function onWatchedCb(data, id) {
|
||||
var messages = JSON.parse(data)
|
||||
postEvent("watched:"+id, messages)
|
||||
}
|
||||
|
||||
function onNewBlockCb(block) {
|
||||
postEvent("block:new", block)
|
||||
}
|
||||
function onObjectChangeCb(stateObject) {
|
||||
postEvent("object:"+stateObject.address(), stateObject)
|
||||
}
|
||||
function onStorageChangeCb(storageObject) {
|
||||
var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":");
|
||||
postEvent(ev, [storageObject.address, storageObject.value])
|
||||
}
|
||||
}
|
||||
|
||||
function post(seed, data) {
|
||||
console.log("data", data)
|
||||
postData(data._seed, data)
|
||||
}
|
||||
|
||||
function require(args, num) {
|
||||
if(args.length < num) {
|
||||
throw("required argument count of "+num+" got "+args.length);
|
||||
Rectangle {
|
||||
id: sizeGrip
|
||||
color: "gray"
|
||||
visible: false
|
||||
height: 10
|
||||
anchors {
|
||||
left: root.left
|
||||
right: root.right
|
||||
}
|
||||
y: Math.round(root.height * 2 / 3)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
drag.target: sizeGrip
|
||||
drag.minimumY: 0
|
||||
drag.maximumY: root.height
|
||||
drag.axis: Drag.YAxis
|
||||
}
|
||||
}
|
||||
function postData(seed, data) {
|
||||
webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
|
||||
}
|
||||
function postEvent(event, data) {
|
||||
webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
|
||||
}
|
||||
|
||||
function onWatchedCb(data, id) {
|
||||
var messages = JSON.parse(data)
|
||||
postEvent("watched:"+id, messages)
|
||||
}
|
||||
|
||||
function onNewBlockCb(block) {
|
||||
postEvent("block:new", block)
|
||||
}
|
||||
function onObjectChangeCb(stateObject) {
|
||||
postEvent("object:"+stateObject.address(), stateObject)
|
||||
}
|
||||
function onStorageChangeCb(storageObject) {
|
||||
var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":");
|
||||
postEvent(ev, [storageObject.address, storageObject.value])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: sizeGrip
|
||||
color: "gray"
|
||||
visible: false
|
||||
height: 10
|
||||
anchors {
|
||||
left: root.left
|
||||
right: root.right
|
||||
}
|
||||
y: Math.round(root.height * 2 / 3)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
drag.target: sizeGrip
|
||||
drag.minimumY: 0
|
||||
drag.maximumY: root.height
|
||||
drag.axis: Drag.YAxis
|
||||
}
|
||||
}
|
||||
|
||||
WebView {
|
||||
id: inspector
|
||||
visible: false
|
||||
anchors {
|
||||
left: root.left
|
||||
right: root.right
|
||||
top: sizeGrip.bottom
|
||||
bottom: root.bottom
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "inspectorShown"
|
||||
PropertyChanges {
|
||||
target: inspector
|
||||
WebView {
|
||||
id: inspector
|
||||
visible: false
|
||||
anchors {
|
||||
left: root.left
|
||||
right: root.right
|
||||
top: sizeGrip.bottom
|
||||
bottom: root.bottom
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "inspectorShown"
|
||||
PropertyChanges {
|
||||
target: inspector
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ func (d *Debugger) halting(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *et
|
||||
d.win.Root().Call("clearStorage")
|
||||
|
||||
addr := 0
|
||||
for i := 0; i+32 <= mem.Len(); i += 16 {
|
||||
for i := 0; i+16 <= mem.Len(); i += 16 {
|
||||
dat := mem.Data()[i : i+16]
|
||||
var str string
|
||||
|
||||
|
@ -37,7 +37,6 @@ type UiLib struct {
|
||||
jsEngine *javascript.JSRE
|
||||
|
||||
filterCallbacks map[int][]int
|
||||
//filters map[int]*ethpipe.JSFilter
|
||||
}
|
||||
|
||||
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
|
||||
@ -201,7 +200,7 @@ func (self *UiLib) UninstallFilter(id int) {
|
||||
self.eth.UninstallFilter(id)
|
||||
}
|
||||
|
||||
func (self *UiLib) Transact(object map[string]interface{}) (*ethpipe.JSReceipt, error) {
|
||||
func mapToTxParams(object map[string]interface{}) map[string]string {
|
||||
// Default values
|
||||
if object["from"] == nil {
|
||||
object["from"] = ""
|
||||
@ -223,6 +222,8 @@ func (self *UiLib) Transact(object map[string]interface{}) (*ethpipe.JSReceipt,
|
||||
var data []string
|
||||
if list, ok := object["data"].(*qml.List); ok {
|
||||
list.Convert(&data)
|
||||
} else if str, ok := object["data"].(string); ok {
|
||||
data = []string{str}
|
||||
}
|
||||
|
||||
for _, str := range data {
|
||||
@ -238,14 +239,29 @@ func (self *UiLib) Transact(object map[string]interface{}) (*ethpipe.JSReceipt,
|
||||
|
||||
dataStr += str
|
||||
}
|
||||
object["data"] = dataStr
|
||||
fmt.Println(object)
|
||||
|
||||
conv := make(map[string]string)
|
||||
for key, value := range object {
|
||||
if v, ok := value.(string); ok {
|
||||
conv[key] = v
|
||||
}
|
||||
}
|
||||
|
||||
return conv
|
||||
}
|
||||
|
||||
func (self *UiLib) Transact(params map[string]interface{}) (*ethpipe.JSReceipt, error) {
|
||||
object := mapToTxParams(params)
|
||||
|
||||
return self.JSPipe.Transact(
|
||||
object["from"].(string),
|
||||
object["to"].(string),
|
||||
object["value"].(string),
|
||||
object["gas"].(string),
|
||||
object["gasPrice"].(string),
|
||||
dataStr,
|
||||
object["from"],
|
||||
object["to"],
|
||||
object["value"],
|
||||
object["gas"],
|
||||
object["gasPrice"],
|
||||
object["data"],
|
||||
)
|
||||
}
|
||||
|
||||
@ -257,3 +273,15 @@ func (self *UiLib) Compile(code string) (string, error) {
|
||||
|
||||
return ethutil.Bytes2Hex(bcode), err
|
||||
}
|
||||
|
||||
func (self *UiLib) Call(params map[string]interface{}) (string, error) {
|
||||
object := mapToTxParams(params)
|
||||
|
||||
return self.JSPipe.Execute(
|
||||
object["to"],
|
||||
object["value"],
|
||||
object["gas"],
|
||||
object["gasPrice"],
|
||||
object["data"],
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user