aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaran <maran.hidskes@gmail.com>2014-05-02 19:35:44 +0800
committerMaran <maran.hidskes@gmail.com>2014-05-02 19:35:44 +0800
commit60f9966cd8f991967882dd61e602822a95681d85 (patch)
tree037e8d0a7a9a546b10ddef65be17a0328b62d551
parent3424bf17ca791b97ea512bef5290d1a52c1758af (diff)
parentf1da6f0564696f4fb5a6c04d1b9e24ed12432d63 (diff)
downloaddexon-60f9966cd8f991967882dd61e602822a95681d85.tar.gz
dexon-60f9966cd8f991967882dd61e602822a95681d85.tar.zst
dexon-60f9966cd8f991967882dd61e602822a95681d85.zip
Merge branch 'develop' into feature/rpc
-rw-r--r--README.md10
-rw-r--r--ethereal/assets/ethereum.js66
-rw-r--r--ethereal/assets/qml/webapp.qml9
-rw-r--r--ethereal/assets/samplecoin.html69
-rwxr-xr-xethereal/assets/samplecoin/bootstrap-theme.min.css7
-rwxr-xr-xethereal/assets/samplecoin/bootstrap.min.css7
-rw-r--r--ethereal/assets/samplecoin/icon.png (renamed from ethereal/assets/icon.png)bin86700 -> 86700 bytes
-rw-r--r--ethereal/assets/samplecoin/samplecoin.css34
-rw-r--r--ethereal/assets/samplecoin/samplecoin.html70
-rw-r--r--ethereal/assets/test.html55
-rw-r--r--ethereal/ui/ext_app.go96
-rw-r--r--ethereal/ui/gui.go13
-rw-r--r--ethereal/ui/html_container.go5
-rw-r--r--ethereal/ui/library.go10
-rw-r--r--utils/ethereum.go110
-rw-r--r--utils/types.go (renamed from ethereal/ui/types.go)44
16 files changed, 352 insertions, 253 deletions
diff --git a/README.md b/README.md
index 08104b075..ddf8f2bed 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,15 @@ For the development package please see the [eth-go package](https://github.com/e
Build
=======
-For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go))
+To build Ethereal (GUI):
+
+`go get github.com/ethereum/go-ethereum/ethereal`
+
+To build the node (CLI):
+
+`go get github.com/ethereum/go-ethereum/ethereum`
+
+For further, detailed, build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go))
General command line options
====================
diff --git a/ethereal/assets/ethereum.js b/ethereal/assets/ethereum.js
index fd5091bd1..64a7ff47c 100644
--- a/ethereal/assets/ethereum.js
+++ b/ethereal/assets/ethereum.js
@@ -19,8 +19,7 @@ window.eth = {
// Create transaction
//
- // Creates a transaction with the current account
- // If no recipient is set, the Ethereum API will see it as a contract creation
+ // Transact between two state objects
transact: function(sec, recipient, value, gas, gasPrice, data, cb) {
postData({call: "transact", args: [sec, recipient, value, gas, gasPrice, data]}, cb);
},
@@ -71,6 +70,10 @@ window.eth = {
postData({call: "disconnect", args: [address, storageAddrOrCb]});
},
+ set: function(props) {
+ postData({call: "set", args: props});
+ },
+
on: function(event, cb) {
if(eth._onCallbacks[event] === undefined) {
eth._onCallbacks[event] = [];
@@ -110,7 +113,7 @@ function debug(/**/) {
var args = arguments;
var msg = ""
for(var i = 0; i < args.length; i++){
- if(typeof args[i] == "object") {
+ if(typeof args[i] === "object") {
msg += " " + JSON.stringify(args[i])
} else {
msg += args[i]
@@ -151,3 +154,60 @@ navigator.qt.onmessage = function(ev) {
}
}
}
+
+window.eth._0 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+String.prototype.pad = function(len) {
+ var bin = this.bin();
+ var l = bin.length;
+ if(l < 32) {
+ return eth._0.substr(0, 32 - bin.length) + bin;
+ }
+
+ return bin;
+}
+
+String.prototype.unpad = function() {
+ var i, l;
+ for(i = 0, l = this.length; i < l; i++) {
+ if(this[i] != "\0") {
+ return this.substr(i, this.length);
+ }
+ }
+
+ return this.substr(i, this.length);
+}
+
+String.prototype.bin = function() {
+ if(this.substr(0, 2) == "0x") {
+ return this.hex2bin();
+ } else if(/^\d+$/.test(this)) {
+ return this.num2bin()
+ }
+
+ // Otherwise we'll return the "String" object instead of an actual string
+ return this.substr(0, this.length)
+}
+
+String.prototype.unbin = function() {
+ var i, l, o = '';
+ for(i = 0, l = this.length; i < l; i++) {
+ var n = this.charCodeAt(i).toString(16);
+ o += n.length < 2 ? '0' + n : n;
+ }
+
+ return "0x" + o;
+}
+
+String.prototype.hex2bin = function() {
+ bytes = []
+
+ for(var i=2; i< this.length-1; i+=2) {
+ bytes.push(parseInt(this.substr(i, 2), 16));
+ }
+
+ return String.fromCharCode.apply(String, bytes);
+}
+
+String.prototype.num2bin = function() {
+ return ("0x"+parseInt(this).toString(16)).bin()
+}
diff --git a/ethereal/assets/qml/webapp.qml b/ethereal/assets/qml/webapp.qml
index c0df0b66e..4bac12ef0 100644
--- a/ethereal/assets/qml/webapp.qml
+++ b/ethereal/assets/qml/webapp.qml
@@ -60,6 +60,7 @@ ApplicationWindow {
var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[5])
postData(data._seed, tx)
+
break
case "create":
postData(data._seed, null)
@@ -91,6 +92,12 @@ ApplicationWindow {
require(1)
postData(data._seed, null)
break;
+ case "set":
+ for(var key in data.args) {
+ if(webview.hasOwnProperty(key)) {
+ window[key] = data.args[key];
+ }
+ }
}
} catch(e) {
console.log(data.call + ": " + e)
@@ -117,6 +124,8 @@ ApplicationWindow {
function onObjectChangeCb(stateObject) {
postEvent("object:"+stateObject.address(), stateObject)
}
+ function onStorageChangeCb() {
+ }
}
Rectangle {
diff --git a/ethereal/assets/samplecoin.html b/ethereal/assets/samplecoin.html
deleted file mode 100644
index 3b039fb04..000000000
--- a/ethereal/assets/samplecoin.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<html>
-<head>
-<title>jeffcoin</title>
-<script type="text/javascript">
-var jefcoinAddr = "3dff537f51350239abc95c76a5864aa605259e7d"
-
-function createTransaction() {
- var addr = document.querySelector("#addr").value;
- var amount = document.querySelector("#amount").value;
-
- var data = "0x" + addr + "\n" + amount
- eth.transact("", jefcoinAddr, 0, "10000000", "250", data, function(tx) {
- debug("received tx hash:", tx)
- })
-}
-
-// Any test related actions here please
-function tests() {
- eth.getKey(function(keys) {
- debug(keys)
- })
-}
-
-function init() {
- eth.getKey(function(key) {
- eth.getStorageAt(jefcoinAddr, key, function(storage) {
- document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
- });
-
- eth.watch(jefcoinAddr, function(stateObject) {
- eth.getStorageAt(jefcoinAddr, key, function(storage) {
- document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
- });
- });
-
- eth.getBalanceAt(key, function(balance) {
- debug("balance", balance);
- })
- });
-}
-
-</script>
-<style type="text/css">
-input[type="text"] {
- width: 300px;
-}
-</style>
-</head>
-
-<body onload="init();">
-<h1>Jeff Coin</h1>
-
-<img src="icon.png">
-<div id="currentAmount"></div>
-
-<div id="transactions">
- <input id="addr" type="text" placeholder="Receiver address"></input><br>
- <input id="amount" type="text" placeholder="Amount"></input><br>
- <button onclick="createTransaction();">Send Tx</button>
-</div>
-
-<div><button onclick="tests();">Tests</button></div>
-
-
-<div id="debug" style="border: 1px solid block"></div>
-
-</body>
-</html>
-
diff --git a/ethereal/assets/samplecoin/bootstrap-theme.min.css b/ethereal/assets/samplecoin/bootstrap-theme.min.css
new file mode 100755
index 000000000..8dee07209
--- /dev/null
+++ b/ethereal/assets/samplecoin/bootstrap-theme.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:linear-gradient(to bottom, #fff 0, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top, #428bca 0, #2d6ca2 100%);background-image:linear-gradient(to bottom, #428bca 0, #2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:linear-gradient(to bottom, #5cb85c 0, #419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:linear-gradient(to bottom, #fff 0, #f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f3f3f3 100%);background-image:linear-gradient(to bottom, #ebebeb 0, #f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:linear-gradient(to bottom, #3c3c3c 0, #222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #222 0, #282828 100%);background-image:linear-gradient(to bottom, #222 0, #282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top, #428bca 0, #3071a9 100%);background-image:linear-gradient(to bottom, #428bca 0, #3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:linear-gradient(to bottom, #5cb85c 0, #449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:linear-gradient(to bottom, #d9534f 0, #c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top, #428bca 0, #3278b3 100%);background-image:linear-gradient(to bottom, #428bca 0, #3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} \ No newline at end of file
diff --git a/ethereal/assets/samplecoin/bootstrap.min.css b/ethereal/assets/samplecoin/bootstrap.min.css
new file mode 100755
index 000000000..e281af6ed
--- /dev/null
+++ b/ethereal/assets/samplecoin/bootstrap.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.table td,.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}input[type="date"]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:normal;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%} \ No newline at end of file
diff --git a/ethereal/assets/icon.png b/ethereal/assets/samplecoin/icon.png
index 73e0ceb75..73e0ceb75 100644
--- a/ethereal/assets/icon.png
+++ b/ethereal/assets/samplecoin/icon.png
Binary files differ
diff --git a/ethereal/assets/samplecoin/samplecoin.css b/ethereal/assets/samplecoin/samplecoin.css
new file mode 100644
index 000000000..bc4e7f53c
--- /dev/null
+++ b/ethereal/assets/samplecoin/samplecoin.css
@@ -0,0 +1,34 @@
+/* Space out content a bit */
+body {
+ padding-top: 20px;
+ padding-bottom: 20px;
+}
+
+/* Everything but the jumbotron gets side spacing for mobile first
+ * views */
+.header,
+.marketing,
+.footer {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+/* Custom page header */
+.header {
+ border-bottom: 1px solid #e5e5e5;
+}
+/* Make the masthead heading the same height as the navigation */
+.header h3 {
+ padding-bottom: 19px;
+ margin-top: 0;
+ margin-bottom: 0;
+ line-height: 40px;
+}
+
+.jumbotron {
+ text-align: center;
+ border-bottom: 1px solid #e5e5e5;
+
+ margin: 0 auto;
+ width: 300px;
+}
diff --git a/ethereal/assets/samplecoin/samplecoin.html b/ethereal/assets/samplecoin/samplecoin.html
new file mode 100644
index 000000000..6f35a1312
--- /dev/null
+++ b/ethereal/assets/samplecoin/samplecoin.html
@@ -0,0 +1,70 @@
+<html>
+<head>
+<title>jeffcoin</title>
+
+<link rel="stylesheet" href="bootstrap.min.css">
+<link rel="stylesheet" href="bootstrap-theme.min.css">
+<link rel="stylesheet" href="samplecoin.css">
+<meta name="viewport" content="minimum-scale=1; maximum-scale=1; initial-scale=1;">
+
+<script type="text/javascript">
+var jefcoinAddr = "3dff537f51350239abc95c76a5864aa605259e7d"
+var mAddr = ""
+
+function createTransaction() {
+ var addr = document.querySelector("#addr").value;
+ var amount = document.querySelector("#amount").value;
+
+ var data = (("0x"+addr).pad(32) + amount.pad(32)).unbin()
+ eth.transact(mAddr, jefcoinAddr, 0, "10000000", "250", data, function(tx) {
+ debug("received tx hash:", tx)
+ })
+}
+
+function init() {
+ eth.set({width: 500})
+
+ eth.getKey(function(keyPair) {
+ mAddr = keyPair.privateKey;
+
+ eth.getStorageAt(jefcoinAddr, keyPair.address, function(storage) {
+ document.querySelector("#current-amount").innerHTML = storage;
+ });
+
+ eth.watch(jefcoinAddr, function(stateObject) {
+ eth.getStorageAt(jefcoinAddr, keyPair.address, function(storage) {
+ document.querySelector("#current-amount").innerHTML = storage;
+ });
+ });
+ });
+}
+
+</script>
+</head>
+
+<body onload="init();">
+<div class="container">
+ <div class="header">
+ <h3 class="text-muted">JeffCoin</h3>
+ </div>
+
+ <div class="jumbotron ">
+ <img src="icon.png">
+ <div>Amount: <strong id="current-amount"></strong></div>
+
+ <div id="transactions">
+ <div class="form-group">
+ <input id="addr" class="form-control" type="text" placeholder="Receiver address"></input><br>
+ <input id="amount" class="form-control" type="text" placeholder="Amount"></input><br>
+ </div>
+
+ <button class="btn btn-default" onclick="createTransaction();">Send Tx</button>
+ </div>
+ </div>
+</div>
+
+<div id="debug" style="border: 1px solid black; min-height: 30px;"></div>
+
+</body>
+</html>
+
diff --git a/ethereal/assets/test.html b/ethereal/assets/test.html
deleted file mode 100644
index beb888685..000000000
--- a/ethereal/assets/test.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<html>
-<head>
-<title>jeffcoin</title>
-<script type="text/javascript">
-var jefcoinAddr = "3dff537f51350239abc95c76a5864aa605259e7d"
-
-function createTransaction() {
- var addr = document.querySelector("#addr").value;
- var amount = document.querySelector("#amount").value;
-
- var data = "0x" + addr + "\n" + amount
- eth.createTx(jefcoinAddr, 0, "10000000", "250", data, function(tx) {
- debug("received tx hash:", tx)
- })
-}
-
-function init() {
- eth.getKey(function(key) {
- eth.getStorage(jefcoinAddr, key, function(storage) {
- document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
- });
-
- eth.on("block:new", function() {
- eth.getStorage(jefcoinAddr, key, function(storage) {
- document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
- });
- });
- });
-}
-
-</script>
-<style type="text/css">
-input[type="text"] {
- width: 300px;
-}
-</style>
-</head>
-
-<body onload="init();">
-<h1>Jeff Coin</h1>
-
-<img src="icon.png">
-<div id="currentAmount"></div>
-
-<div id="transactions">
- <input id="addr" type="text" placeholder="Receiver address"></input><br>
- <input id="amount" type="text" placeholder="Amount"></input><br>
- <button onclick="createTransaction();">Send Tx</button>
-</div>
-
-<div id="debug" style="border: 1px solid block"></div>
-
-</body>
-</html>
-
diff --git a/ethereal/ui/ext_app.go b/ethereal/ui/ext_app.go
index c02ffb7b2..1021afea9 100644
--- a/ethereal/ui/ext_app.go
+++ b/ethereal/ui/ext_app.go
@@ -2,13 +2,11 @@ package ethui
import (
"fmt"
- "github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
"math/big"
- "strings"
)
type AppContainer interface {
@@ -24,7 +22,7 @@ type AppContainer interface {
}
type ExtApplication struct {
- *QEthereum
+ *utils.PEthereum
blockChan chan ethutil.React
changeChan chan ethutil.React
@@ -37,7 +35,7 @@ type ExtApplication struct {
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
app := &ExtApplication{
- NewQEthereum(lib.eth),
+ utils.NewPEthereum(lib.eth),
make(chan ethutil.React, 1),
make(chan ethutil.React, 1),
make(chan bool),
@@ -127,93 +125,3 @@ func (app *ExtApplication) Watch(addr, storageAddr string) {
app.registeredEvents = append(app.registeredEvents, event)
}
-
-type QEthereum struct {
- stateManager *ethchain.StateManager
- blockChain *ethchain.BlockChain
- txPool *ethchain.TxPool
-}
-
-func NewQEthereum(eth *eth.Ethereum) *QEthereum {
- return &QEthereum{
- eth.StateManager(),
- eth.BlockChain(),
- eth.TxPool(),
- }
-}
-
-func (lib *QEthereum) GetBlock(hexHash string) *QBlock {
- hash := ethutil.FromHex(hexHash)
-
- block := lib.blockChain.GetBlock(hash)
-
- return &QBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
-}
-
-func (lib *QEthereum) GetKey() string {
- return ethutil.Hex(ethutil.Config.Db.GetKeys()[0].Address())
-}
-
-func (lib *QEthereum) GetStateObject(address string) *QStateObject {
- stateObject := lib.stateManager.ProcState().GetContract(ethutil.FromHex(address))
- if stateObject != nil {
- return NewQStateObject(stateObject)
- }
-
- // See GetStorage for explanation on "nil"
- return NewQStateObject(nil)
-}
-
-func (lib *QEthereum) Watch(addr, storageAddr string) {
- // lib.stateManager.Watch(ethutil.FromHex(addr), ethutil.FromHex(storageAddr))
-}
-
-func (lib *QEthereum) CreateTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
- return lib.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
-}
-
-func (lib *QEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
- var hash []byte
- var contractCreation bool
- if len(recipient) == 0 {
- contractCreation = true
- } else {
- hash = ethutil.FromHex(recipient)
- }
-
- keyPair := ethutil.Config.Db.GetKeys()[0]
- value := ethutil.Big(valueStr)
- gas := ethutil.Big(gasStr)
- gasPrice := ethutil.Big(gasPriceStr)
- var tx *ethchain.Transaction
- // Compile and assemble the given data
- if contractCreation {
- // Compile script
- mainScript, initScript, err := utils.CompileScript(dataStr)
- if err != nil {
- return "", err
- }
-
- tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
- } else {
- lines := strings.Split(dataStr, "\n")
- var data []byte
- for _, line := range lines {
- data = append(data, ethutil.BigToBytes(ethutil.Big(line), 256)...)
- }
-
- tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, data)
- }
- acc := lib.stateManager.GetAddrState(keyPair.Address())
- tx.Nonce = acc.Nonce
- tx.Sign(keyPair.PrivateKey)
- lib.txPool.QueueTransaction(tx)
-
- if contractCreation {
- ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:])
- } else {
- ethutil.Config.Log.Infof("Tx hash %x", tx.Hash())
- }
-
- return ethutil.Hex(tx.Hash()), nil
-}
diff --git a/ethereal/ui/gui.go b/ethereal/ui/gui.go
index c821fa824..8e6433207 100644
--- a/ethereal/ui/gui.go
+++ b/ethereal/ui/gui.go
@@ -7,6 +7,7 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethutil"
+ "github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
"math/big"
"strings"
@@ -56,9 +57,9 @@ func (ui *Gui) Start(assetPath string) {
// Register ethereum functions
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
- Init: func(p *QBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
+ Init: func(p *utils.PBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
}, {
- Init: func(p *QTx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
+ Init: func(p *utils.PTx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
}})
ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.2"))
@@ -129,13 +130,13 @@ func (ui *Gui) readPreviousTransactions() {
for it.Next() {
tx := ethchain.NewTransactionFromBytes(it.Value())
- ui.win.Root().Call("addTx", NewQTx(tx))
+ ui.win.Root().Call("addTx", utils.NewPTx(tx))
}
it.Release()
}
func (ui *Gui) ProcessBlock(block *ethchain.Block) {
- ui.win.Root().Call("addBlock", NewQBlock(block))
+ ui.win.Root().Call("addBlock", utils.NewPBlock(block))
}
// Simple go routine function that updates the list of peers in the GUI
@@ -156,13 +157,13 @@ func (ui *Gui) update() {
if txMsg.Type == ethchain.TxPre {
if bytes.Compare(tx.Sender(), ui.addr) == 0 && addrState.Nonce <= tx.Nonce {
- ui.win.Root().Call("addTx", NewQTx(tx))
+ ui.win.Root().Call("addTx", utils.NewPTx(tx))
ui.txDb.Put(tx.Hash(), tx.RlpEncode())
addrState.Nonce += 1
unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
} else if bytes.Compare(tx.Recipient, ui.addr) == 0 {
- ui.win.Root().Call("addTx", NewQTx(tx))
+ ui.win.Root().Call("addTx", utils.NewPTx(tx))
ui.txDb.Put(tx.Hash(), tx.RlpEncode())
unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
diff --git a/ethereal/ui/html_container.go b/ethereal/ui/html_container.go
index 8e3ef0fc7..16cc531f2 100644
--- a/ethereal/ui/html_container.go
+++ b/ethereal/ui/html_container.go
@@ -4,6 +4,7 @@ import (
"errors"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
+ "github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
"math/big"
"path/filepath"
@@ -56,12 +57,12 @@ func (app *HtmlApplication) Window() *qml.Window {
}
func (app *HtmlApplication) NewBlock(block *ethchain.Block) {
- b := &QBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
+ b := &utils.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
app.webView.Call("onNewBlockCb", b)
}
func (app *HtmlApplication) ObjectChanged(stateObject *ethchain.StateObject) {
- app.webView.Call("onObjectChangeCb", NewQStateObject(stateObject))
+ app.webView.Call("onObjectChangeCb", utils.NewPStateObject(stateObject))
}
func (app *HtmlApplication) StorageChanged(stateObject *ethchain.StateObject, addr []byte, value *big.Int) {
diff --git a/ethereal/ui/library.go b/ethereal/ui/library.go
index 70462a93d..231fd96e7 100644
--- a/ethereal/ui/library.go
+++ b/ethereal/ui/library.go
@@ -47,14 +47,14 @@ func (lib *EthLib) GetKey() string {
return ethutil.Hex(ethutil.Config.Db.GetKeys()[0].Address())
}
-func (lib *EthLib) GetStateObject(address string) *QStateObject {
+func (lib *EthLib) GetStateObject(address string) *utils.PStateObject {
stateObject := lib.stateManager.ProcState().GetContract(ethutil.FromHex(address))
if stateObject != nil {
- return NewQStateObject(stateObject)
+ return utils.NewPStateObject(stateObject)
}
// See GetStorage for explanation on "nil"
- return NewQStateObject(nil)
+ return utils.NewPStateObject(nil)
}
func (lib *EthLib) Watch(addr, storageAddr string) {
@@ -115,7 +115,7 @@ func (lib *EthLib) Transact(recipient, valueStr, gasStr, gasPriceStr, dataStr st
return ethutil.Hex(tx.Hash()), nil
}
-func (lib *EthLib) GetBlock(hexHash string) *QBlock {
+func (lib *EthLib) GetBlock(hexHash string) *utils.PBlock {
hash, err := hex.DecodeString(hexHash)
if err != nil {
return nil
@@ -123,5 +123,5 @@ func (lib *EthLib) GetBlock(hexHash string) *QBlock {
block := lib.blockChain.GetBlock(hash)
- return &QBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
+ return &utils.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
}
diff --git a/utils/ethereum.go b/utils/ethereum.go
new file mode 100644
index 000000000..526795894
--- /dev/null
+++ b/utils/ethereum.go
@@ -0,0 +1,110 @@
+package utils
+
+import (
+ "fmt"
+ "github.com/ethereum/eth-go"
+ "github.com/ethereum/eth-go/ethchain"
+ "github.com/ethereum/eth-go/ethutil"
+)
+
+type PEthereum struct {
+ stateManager *ethchain.StateManager
+ blockChain *ethchain.BlockChain
+ txPool *ethchain.TxPool
+}
+
+func NewPEthereum(eth *eth.Ethereum) *PEthereum {
+ return &PEthereum{
+ eth.StateManager(),
+ eth.BlockChain(),
+ eth.TxPool(),
+ }
+}
+
+func (lib *PEthereum) GetBlock(hexHash string) *PBlock {
+ hash := ethutil.FromHex(hexHash)
+
+ block := lib.blockChain.GetBlock(hash)
+
+ return &PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
+}
+
+func (lib *PEthereum) GetKey() *PKey {
+ keyPair, err := ethchain.NewKeyPairFromSec(ethutil.Config.Db.GetKeys()[0].PrivateKey)
+ if err != nil {
+ return nil
+ }
+
+ return NewPKey(keyPair)
+}
+
+func (lib *PEthereum) GetStateObject(address string) *PStateObject {
+ stateObject := lib.stateManager.ProcState().GetContract(ethutil.FromHex(address))
+ if stateObject != nil {
+ return NewPStateObject(stateObject)
+ }
+
+ // See GetStorage for explanation on "nil"
+ return NewPStateObject(nil)
+}
+
+func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
+ return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr, "")
+}
+
+func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) (string, error) {
+ return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, initStr, bodyStr)
+}
+
+func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, initStr, scriptStr string) (string, error) {
+ var hash []byte
+ var contractCreation bool
+ if len(recipient) == 0 {
+ contractCreation = true
+ } else {
+ hash = ethutil.FromHex(recipient)
+ }
+
+ keyPair, err := ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
+ if err != nil {
+ return "", err
+ }
+
+ value := ethutil.Big(valueStr)
+ gas := ethutil.Big(gasStr)
+ gasPrice := ethutil.Big(gasPriceStr)
+ var tx *ethchain.Transaction
+ // Compile and assemble the given data
+ if contractCreation {
+ initScript, err := Compile(initStr)
+ if err != nil {
+ return "", err
+ }
+ mainScript, err := Compile(scriptStr)
+ if err != nil {
+ return "", err
+ }
+
+ tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
+ } else {
+ // Just in case it was submitted as a 0x prefixed string
+ if initStr[0:2] == "0x" {
+ initStr = initStr[2:len(initStr)]
+ }
+ fmt.Println("DATA:", initStr)
+ tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(initStr))
+ }
+
+ acc := lib.stateManager.GetAddrState(keyPair.Address())
+ tx.Nonce = acc.Nonce
+ tx.Sign(keyPair.PrivateKey)
+ lib.txPool.QueueTransaction(tx)
+
+ if contractCreation {
+ ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:])
+ } else {
+ ethutil.Config.Log.Infof("Tx hash %x", tx.Hash())
+ }
+
+ return ethutil.Hex(tx.Hash()), nil
+}
diff --git a/ethereal/ui/types.go b/utils/types.go
index 9e12a8892..0bbc61627 100644
--- a/ethereal/ui/types.go
+++ b/utils/types.go
@@ -1,4 +1,4 @@
-package ethui
+package utils
import (
"encoding/hex"
@@ -7,53 +7,61 @@ import (
)
// Block interface exposed to QML
-type QBlock struct {
+type PBlock struct {
Number int
Hash string
}
// Creates a new QML Block from a chain block
-func NewQBlock(block *ethchain.Block) *QBlock {
+func NewPBlock(block *ethchain.Block) *PBlock {
info := block.BlockInfo()
hash := hex.EncodeToString(block.Hash())
- return &QBlock{Number: int(info.Number), Hash: hash}
+ return &PBlock{Number: int(info.Number), Hash: hash}
}
-type QTx struct {
+type PTx struct {
Value, Hash, Address string
Contract bool
}
-func NewQTx(tx *ethchain.Transaction) *QTx {
+func NewPTx(tx *ethchain.Transaction) *PTx {
hash := hex.EncodeToString(tx.Hash())
sender := hex.EncodeToString(tx.Recipient)
isContract := len(tx.Data) > 0
- return &QTx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender, Contract: isContract}
+ return &PTx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender, Contract: isContract}
}
-type QKey struct {
- Address string
+type PKey struct {
+ Address string
+ PrivateKey string
+ PublicKey string
}
-type QKeyRing struct {
+func NewPKey(key *ethchain.KeyPair) *PKey {
+ return &PKey{ethutil.Hex(key.Address()), ethutil.Hex(key.PrivateKey), ethutil.Hex(key.PublicKey)}
+}
+
+/*
+type PKeyRing struct {
Keys []interface{}
}
-func NewQKeyRing(keys []interface{}) *QKeyRing {
- return &QKeyRing{Keys: keys}
+func NewPKeyRing(keys []interface{}) *PKeyRing {
+ return &PKeyRing{Keys: keys}
}
+*/
-type QStateObject struct {
+type PStateObject struct {
object *ethchain.StateObject
}
-func NewQStateObject(object *ethchain.StateObject) *QStateObject {
- return &QStateObject{object: object}
+func NewPStateObject(object *ethchain.StateObject) *PStateObject {
+ return &PStateObject{object: object}
}
-func (c *QStateObject) GetStorage(address string) string {
+func (c *PStateObject) GetStorage(address string) string {
// Because somehow, even if you return nil to QML it
// still has some magical object so we can't rely on
// undefined or null at the QML side
@@ -66,7 +74,7 @@ func (c *QStateObject) GetStorage(address string) string {
return ""
}
-func (c *QStateObject) Value() string {
+func (c *PStateObject) Value() string {
if c.object != nil {
return c.object.Amount.String()
}
@@ -74,7 +82,7 @@ func (c *QStateObject) Value() string {
return ""
}
-func (c *QStateObject) Address() string {
+func (c *PStateObject) Address() string {
if c.object != nil {
return ethutil.Hex(c.object.Address())
}