diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html
index a15345ab31..0528a5ad00 100644
--- a/cmd/mist/assets/examples/coin.html
+++ b/cmd/mist/assets/examples/coin.html
@@ -3,7 +3,7 @@
JevCoin
-
+
diff --git a/cmd/mist/assets/ext/ethereum.js b/cmd/mist/assets/ext/ethereum.js
index 2536888f81..31e046dbec 160000
--- a/cmd/mist/assets/ext/ethereum.js
+++ b/cmd/mist/assets/ext/ethereum.js
@@ -1 +1 @@
-Subproject commit 2536888f817a1a15b05dab4727d30f73d6763f07
+Subproject commit 31e046dbecea51d3b99b21f3e7e60ddfb6c39304
diff --git a/common/size.go b/common/size.go
index b5c0b0b3f6..0d9dbf5583 100644
--- a/common/size.go
+++ b/common/size.go
@@ -17,6 +17,10 @@ func (self StorageSize) String() string {
}
}
+func (self StorageSize) Int64() int64 {
+ return int64(self)
+}
+
// The different number of units
var (
Douglas = BigPow(10, 42)
diff --git a/eth/protocol.go b/eth/protocol.go
index a0ab177cdc..b39ac5b154 100644
--- a/eth/protocol.go
+++ b/eth/protocol.go
@@ -14,7 +14,7 @@ import (
const (
ProtocolVersion = 60
- NetworkId = 0
+ NetworkId = 100
ProtocolLength = uint64(8)
ProtocolMaxMsgSize = 10 * 1024 * 1024
maxHashes = 256
diff --git a/jsre/ethereum_js.go b/jsre/ethereum_js.go
index fe15178fa3..0c38cd0e46 100644
--- a/jsre/ethereum_js.go
+++ b/jsre/ethereum_js.go
@@ -1,3 +1,4 @@
package jsre
-const Ethereum_JS = `require=function t(e,n,r){function o(a,u){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!u&&s)return s(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;av;v++)g.push(h(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(s),n.push(h(e.slice(0,s))),e=e.slice(s)):(n.push(h(e.slice(0,s))),e=e.slice(s))}),n},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:h,outputParser:d,formatInput:l,formatOutput:m}},{"../utils/config":5,"../utils/utils":6,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("bignumber.js"),r=t("../utils/utils"),o=t("../utils/config"),i=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e=2*o.ETH_PADDING;return n.config(o.ETH_BIGNUMBER_ROUNDING_MODE),i(r.toTwosComplement(t).round().toString(16),e)},u=function(t){return r.fromAscii(t,o.ETH_PADDING).substr(2)},s=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},c=function(t){return a(new n(t).times(new n(2).pow(128)))},l=function(t){return"1"===new n(t.substr(0,1),16).toString(2).substr(0,1)},f=function(t){return t=t||"0",l(t)?new n(t,16).minus(new n("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new n(t,16)},p=function(t){return t=t||"0",new n(t,16)},m=function(t){return f(t).dividedBy(new n(2).pow(128))},h=function(t){return p(t).dividedBy(new n(2).pow(128))},d=function(t){return"0x"+t},g=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},v=function(t){return r.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:a,formatInputString:u,formatInputBool:s,formatInputReal:c,formatOutputInt:f,formatOutputUInt:p,formatOutputReal:m,formatOutputUReal:h,formatOutputHash:d,formatOutputBool:g,formatOutputString:v,formatOutputAddress:y}},{"../utils/config":5,"../utils/utils":6,"bignumber.js":"bignumber.js"}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],5:[function(t,e){var n=t("bignumber.js"),r=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:r,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:n.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{"bignumber.js":"bignumber.js"}],6:[function(t,e){var n=t("bignumber.js"),r={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},o=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},a=function(t){for(var e="",n=0;n1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},i.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},i.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return n.getInstance().sendAsync(t,function(n,r){t.callback(null,e.formatOutput(r))})}return this.formatOutput(n.getInstance().send(t))},e.exports=i},{"../utils/utils":6,"./errors":11,"./requestmanager":22}],19:[function(t,e){var n=t("../utils/utils"),r=t("./property"),o=[],i=[new r({name:"listening",getter:"net_listening"}),new r({name:"peerCount",getter:"net_peerCount",outputFormatter:n.toDecimal})];e.exports={methods:o,properties:i}},{"../utils/utils":6,"./property":20}],20:[function(t,e){var n=t("./requestmanager"),r=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};r.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},r.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},r.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},Object.defineProperty(t[n[0]],n[1],e)):Object.defineProperty(t,n[0],e)},r.prototype.get=function(){return this.formatOutput(n.getInstance().send({method:this.getter}))},r.prototype.set=function(t){return n.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=r},{"./requestmanager":22}],21:[function(t,e){var n=function(){};n.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=n},{}],22:[function(t,e){var n=t("./jsonrpc"),r=t("../utils/utils"),o=t("../utils/config"),i=t("./errors"),a=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};a.getInstance=function(){var t=new a;return t},a.prototype.send=function(t){if(!this.provider)return console.error(i.InvalidProvider),null;var e=n.getInstance().toPayload(t.method,t.params),r=this.provider.send(e);if(!n.getInstance().isValidResponse(r))throw i.InvalidResponse(r);return r.result},a.prototype.sendAsync=function(t,e){if(!this.provider)return e(i.InvalidProvider);var r=n.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(r,function(t,r){return t?e(t):n.getInstance().isValidResponse(r)?void e(null,r.result):e(i.InvalidResponse(r))})},a.prototype.setProvider=function(t){this.provider=t},a.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},a.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},a.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},a.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),o.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(i.InvalidProvider);var t=n.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,o){if(!t){if(!r.isArray(o))throw i.InvalidResponse(o);o.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=n.getInstance().isValidResponse(t);return e||t.callback(i.InvalidResponse(t)),e}).filter(function(t){return r.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=a},{"../utils/config":5,"../utils/utils":6,"./errors":11,"./jsonrpc":17}],23:[function(t,e){var n=t("./method"),r=t("./formatters"),o=new n({name:"post",call:"shh_post",params:1,inputFormatter:r.inputPostFormatter}),i=new n({name:"newIdentity",call:"shh_newIdentity",params:0}),a=new n({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new n({name:"newGroup",call:"shh_newGroup",params:0}),s=new n({name:"addToGroup",call:"shh_addToGroup",params:0}),c=[o,i,a,u,s];e.exports={methods:c}},{"./formatters":15,"./method":18}],24:[function(t,e){var n=t("../web3"),r=t("../utils/config"),o=function(t){return n.sha3(n.fromAscii(t)).slice(0,2+2*r.ETH_SIGNATURE_LENGTH)},i=function(t){return n.sha3(n.fromAscii(t))};e.exports={functionSignatureFromAscii:o,eventSignatureFromAscii:i}},{"../utils/config":5,"../web3":8}],25:[function(t,e){var n=t("./method"),r=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new n({name:"newFilter",call:t,params:1}),r=new n({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new n({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new n({name:"poll",call:"eth_getFilterChanges",params:1});return[e,r,o,i]},o=function(){var t=new n({name:"newFilter",call:"shh_newFilter",params:1}),e=new n({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),r=new n({name:"getLogs",call:"shh_getMessages",params:1}),o=new n({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,r,o]};e.exports={eth:r,shh:o}},{"./method":18}],26:[function(){},{}],"bignumber.js":[function(t,e){"use strict";e.exports=BigNumber},{}],"ethereum.js":[function(t,e){var n=t("./lib/web3");n.providers.HttpProvider=t("./lib/web3/httpprovider"),n.providers.QtSyncProvider=t("./lib/web3/qtsync"),n.eth.contract=t("./lib/web3/contract"),n.abi=t("./lib/solidity/abi"),e.exports=n},{"./lib/solidity/abi":1,"./lib/web3":8,"./lib/web3/contract":9,"./lib/web3/httpprovider":16,"./lib/web3/qtsync":21}]},{},["ethereum.js"]);`
+const Ethereum_JS = `
+require=function t(e,n,r){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;av;v++)g.push(h(e.slice(0,u))),e=e.slice(u);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(u),n.push(h(e.slice(0,u))),e=e.slice(u)):(n.push(h(e.slice(0,u))),e=e.slice(u))}),n},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:h,outputParser:d,formatInput:l,formatOutput:m}},{"../utils/config":5,"../utils/utils":6,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("bignumber.js"),r=t("../utils/utils"),o=t("../utils/config"),i=function(t){var e=2*o.ETH_PADDING;return n.config(o.ETH_BIGNUMBER_ROUNDING_MODE),r.padLeft(r.toTwosComplement(t).round().toString(16),e)},a=function(t){return r.fromAscii(t,o.ETH_PADDING).substr(2)},s=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},u=function(t){return i(new n(t).times(new n(2).pow(128)))},c=function(t){return"1"===new n(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new n(t,16).minus(new n("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new n(t,16)},f=function(t){return t=t||"0",new n(t,16)},p=function(t){return l(t).dividedBy(new n(2).pow(128))},m=function(t){return f(t).dividedBy(new n(2).pow(128))},h=function(t){return"0x"+t},d=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return r.toAscii(t)},v=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:i,formatInputString:a,formatInputBool:s,formatInputReal:u,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:h,formatOutputBool:d,formatOutputString:g,formatOutputAddress:v}},{"../utils/config":5,"../utils/utils":6,"bignumber.js":"bignumber.js"}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],5:[function(t,e){var n=t("bignumber.js"),r=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:r,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:n.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{"bignumber.js":"bignumber.js"}],6:[function(t,e){var n=t("bignumber.js"),r={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},i=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",n=0;n1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},i.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},i.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return n.getInstance().sendAsync(t,function(n,r){t.callback(null,e.formatOutput(r))})}return this.formatOutput(n.getInstance().send(t))},e.exports=i},{"../utils/utils":6,"./errors":11,"./requestmanager":22}],19:[function(t,e){var n=t("../utils/utils"),r=t("./property"),o=[],i=[new r({name:"listening",getter:"net_listening"}),new r({name:"peerCount",getter:"net_peerCount",outputFormatter:n.toDecimal})];e.exports={methods:o,properties:i}},{"../utils/utils":6,"./property":20}],20:[function(t,e){var n=t("./requestmanager"),r=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};r.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},r.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},r.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},Object.defineProperty(t[n[0]],n[1],e)):Object.defineProperty(t,n[0],e)},r.prototype.get=function(){return this.formatOutput(n.getInstance().send({method:this.getter}))},r.prototype.set=function(t){return n.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=r},{"./requestmanager":22}],21:[function(t,e){var n=function(){};n.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=n},{}],22:[function(t,e){var n=t("./jsonrpc"),r=t("../utils/utils"),o=t("../utils/config"),i=t("./errors"),a=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};a.getInstance=function(){var t=new a;return t},a.prototype.send=function(t){if(!this.provider)return console.error(i.InvalidProvider),null;var e=n.getInstance().toPayload(t.method,t.params),r=this.provider.send(e);if(!n.getInstance().isValidResponse(r))throw i.InvalidResponse(r);return r.result},a.prototype.sendAsync=function(t,e){if(!this.provider)return e(i.InvalidProvider);var r=n.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(r,function(t,r){return t?e(t):n.getInstance().isValidResponse(r)?void e(null,r.result):e(i.InvalidResponse(r))})},a.prototype.setProvider=function(t){this.provider=t},a.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},a.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},a.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},a.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),o.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(i.InvalidProvider);var t=n.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,o){if(!t){if(!r.isArray(o))throw i.InvalidResponse(o);o.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=n.getInstance().isValidResponse(t);return e||t.callback(i.InvalidResponse(t)),e}).filter(function(t){return r.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=a},{"../utils/config":5,"../utils/utils":6,"./errors":11,"./jsonrpc":17}],23:[function(t,e){var n=t("./method"),r=t("./formatters"),o=new n({name:"post",call:"shh_post",params:1,inputFormatter:r.inputPostFormatter}),i=new n({name:"newIdentity",call:"shh_newIdentity",params:0}),a=new n({name:"hasIdentity",call:"shh_hasIdentity",params:1}),s=new n({name:"newGroup",call:"shh_newGroup",params:0}),u=new n({name:"addToGroup",call:"shh_addToGroup",params:0}),c=[o,i,a,s,u];e.exports={methods:c}},{"./formatters":15,"./method":18}],24:[function(t,e){var n=t("../web3"),r=t("../utils/config"),o=function(t){return n.sha3(n.fromAscii(t)).slice(0,2+2*r.ETH_SIGNATURE_LENGTH)},i=function(t){return n.sha3(n.fromAscii(t))};e.exports={functionSignatureFromAscii:o,eventSignatureFromAscii:i}},{"../utils/config":5,"../web3":8}],25:[function(t,e){var n=t("./method"),r=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new n({name:"newFilter",call:t,params:1}),r=new n({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new n({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new n({name:"poll",call:"eth_getFilterChanges",params:1});return[e,r,o,i]},o=function(){var t=new n({name:"newFilter",call:"shh_newFilter",params:1}),e=new n({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),r=new n({name:"getLogs",call:"shh_getMessages",params:1}),o=new n({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,r,o]};e.exports={eth:r,shh:o}},{"./method":18}],26:[function(){},{}],"bignumber.js":[function(t,e){"use strict";e.exports=BigNumber},{}],"ethereum.js":[function(t,e){var n=t("./lib/web3");n.providers.HttpProvider=t("./lib/web3/httpprovider"),n.providers.QtSyncProvider=t("./lib/web3/qtsync"),n.eth.contract=t("./lib/web3/contract"),n.abi=t("./lib/solidity/abi"),e.exports=n},{"./lib/solidity/abi":1,"./lib/web3":8,"./lib/web3/contract":9,"./lib/web3/httpprovider":16,"./lib/web3/qtsync":21}]},{},["ethereum.js"]);`
diff --git a/jsre/pp_js.go b/jsre/pp_js.go
index 3352f23ce0..0b22afe6d3 100644
--- a/jsre/pp_js.go
+++ b/jsre/pp_js.go
@@ -23,18 +23,28 @@ function pp(object, indent) {
}
}
str += " ]";
+ } else if (object instanceof Error) {
+ str += "\033[31m" + "Error";
+ } else if (isBigNumber(object)) {
+ str += "\033[32m'" + object.toString(10) + "'";
} else if(typeof(object) === "object") {
str += "{\n";
- indent += " ";
- var last = Object.keys(object).pop()
- for(var k in object) {
- str += indent + k + ": " + pp(object[k], indent);
+ indent += " ";
+ var last = Object.getOwnPropertyNames(object).pop()
+ Object.getOwnPropertyNames(object).forEach(function (k) {
+ str += indent + k + ": ";
+ try {
+ str += pp(object[k], indent);
+ } catch (e) {
+ str += pp(e, indent);
+ }
if(k !== last) {
str += ",";
}
- str += "\n";
- }
+
+ str += "\n";
+ });
str += indent.substr(2, indent.length) + "}";
} else if(typeof(object) === "string") {
str += "\033[32m'" + object + "'";
@@ -43,7 +53,7 @@ function pp(object, indent) {
} else if(typeof(object) === "number") {
str += "\033[31m" + object;
} else if(typeof(object) === "function") {
- str += "\033[35m[Function]";
+ str += "\033[35m[Function]";
} else {
str += object;
}
@@ -53,6 +63,11 @@ function pp(object, indent) {
return str;
}
+var isBigNumber = function (object) {
+ return typeof BigNumber !== 'undefined' && object instanceof BigNumber;
+};
+
+
function prettyPrint(/* */) {
var args = arguments;
var ret = "";
diff --git a/miner/worker.go b/miner/worker.go
index 2ba3faed85..4385b51c80 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -171,6 +171,8 @@ func (self *worker) wait() {
}
self.mux.Post(core.NewMinedBlockEvent{block})
+ minerlogger.Infof("🔨 Mined block #%v", block.Number())
+
jsonlogger.LogJson(&logger.EthMinerNewBlock{
BlockHash: block.Hash().Hex(),
BlockNumber: block.Number(),
diff --git a/rpc/api.go b/rpc/api.go
index 80dd27afba..afd242aa3d 100644
--- a/rpc/api.go
+++ b/rpc/api.go
@@ -67,7 +67,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
case "eth_mining":
*reply = api.xeth().IsMining()
case "eth_gasPrice":
- v := api.xeth().DefaultGas()
+ v := xeth.DefaultGas()
*reply = common.ToHex(v.Bytes())
case "eth_accounts":
*reply = api.xeth().Accounts()
@@ -80,8 +80,9 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
return err
}
- v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
- *reply = common.ToHex(v.Bytes())
+ *reply = api.xethAtStateNum(args.BlockNumber).BalanceAt(args.Address)
+ //v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance()
+ //*reply = common.ToHex(v.Bytes())
case "eth_getStorage", "eth_storageAt":
args := new(GetStorageArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -105,15 +106,15 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
*reply = common.ToHex(big.NewInt(int64(count)).Bytes())
case "eth_getBlockTransactionCountByHash":
- args := new(GetBlockByHashArgs)
+ args := new(HashArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
return err
}
- block := NewBlockRes(api.xeth().EthBlockByHash(args.BlockHash), false)
+ block := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
*reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
case "eth_getBlockTransactionCountByNumber":
- args := new(GetBlockByNumberArgs)
+ args := new(BlockNumArg)
if err := json.Unmarshal(req.Params, &args); err != nil {
return err
}
@@ -121,16 +122,16 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
block := NewBlockRes(api.xeth().EthBlockByNumber(args.BlockNumber), false)
*reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
case "eth_getUncleCountByBlockHash":
- args := new(GetBlockByHashArgs)
+ args := new(HashArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
return err
}
- block := api.xeth().EthBlockByHash(args.BlockHash)
+ block := api.xeth().EthBlockByHash(args.Hash)
br := NewBlockRes(block, false)
*reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
case "eth_getUncleCountByBlockNumber":
- args := new(GetBlockByNumberArgs)
+ args := new(BlockNumArg)
if err := json.Unmarshal(req.Params, &args); err != nil {
return err
}
@@ -143,7 +144,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
if err := json.Unmarshal(req.Params, &args); err != nil {
return err
}
- *reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address)
+ v := api.xethAtStateNum(args.BlockNumber).CodeAtBytes(args.Address)
+ *reply = newHexData(v)
case "eth_sendTransaction", "eth_transact":
args := new(NewTxArgs)
if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -176,7 +178,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
}
block := api.xeth().EthBlockByHash(args.BlockHash)
- br := NewBlockRes(block, true)
+ br := NewBlockRes(block, args.IncludeTxs)
*reply = br
case "eth_getBlockByNumber":
@@ -186,7 +188,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
}
block := api.xeth().EthBlockByNumber(args.BlockNumber)
- br := NewBlockRes(block, true)
+ br := NewBlockRes(block, args.IncludeTxs)
*reply = br
case "eth_getTransactionByHash":
@@ -235,6 +237,10 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
}
br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash), false)
+ if br == nil {
+ *reply = nil
+ return nil
+ }
if args.Index >= int64(len(br.Uncles)) || args.Index < 0 {
return NewValidationError("Index", "does not exist")
@@ -253,6 +259,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
block := api.xeth().EthBlockByNumber(args.BlockNumber)
v := NewBlockRes(block, true)
+ if v == nil {
+ *reply = nil
+ return nil
+ }
+
if args.Index >= int64(len(v.Uncles)) || args.Index < 0 {
return NewValidationError("Index", "does not exist")
}
diff --git a/rpc/args.go b/rpc/args.go
index dd013147d9..70618a01a4 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -108,8 +108,8 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
return NewDecodeParamError(err.Error())
}
- if len(obj) < 1 {
- return NewInsufficientParamsError(len(obj), 1)
+ if len(obj) < 2 {
+ return NewInsufficientParamsError(len(obj), 2)
}
argstr, ok := obj[0].(string)
@@ -118,9 +118,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
}
args.BlockHash = argstr
- if len(obj) > 1 {
- args.IncludeTxs = obj[1].(bool)
- }
+ args.IncludeTxs = obj[1].(bool)
return nil
}
@@ -136,8 +134,8 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
return NewDecodeParamError(err.Error())
}
- if len(obj) < 1 {
- return NewInsufficientParamsError(len(obj), 1)
+ if len(obj) < 2 {
+ return NewInsufficientParamsError(len(obj), 2)
}
if v, ok := obj[0].(float64); ok {
@@ -148,9 +146,7 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
return NewInvalidTypeError("blockNumber", "not a number or string")
}
- if len(obj) > 1 {
- args.IncludeTxs = obj[1].(bool)
- }
+ args.IncludeTxs = obj[1].(bool)
return nil
}
@@ -202,7 +198,7 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
var num int64
if ext.Value == nil {
- return NewValidationError("value", "is required")
+ num = 0
} else {
if err := numString(ext.Value, &num); err != nil {
return err
@@ -211,7 +207,7 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
args.Value = big.NewInt(num)
if ext.Gas == nil {
- return NewValidationError("gas", "is required")
+ num = 0
} else {
if err := numString(ext.Gas, &num); err != nil {
return err
@@ -220,7 +216,7 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
args.Gas = big.NewInt(num)
if ext.GasPrice == nil {
- return NewValidationError("gasprice", "is required")
+ num = 0
} else {
if err := numString(ext.GasPrice, &num); err != nil {
return err
@@ -233,6 +229,8 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
}
return nil
@@ -320,6 +318,8 @@ func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
}
return nil
@@ -350,6 +350,8 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
}
return nil
@@ -387,6 +389,8 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeight(obj[2], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
}
return nil
@@ -417,6 +421,8 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
}
return nil
@@ -447,6 +453,8 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
}
return nil
@@ -477,6 +485,29 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
return err
}
+ } else {
+ args.BlockNumber = -1
+ }
+
+ return nil
+}
+
+type BlockNumArg struct {
+ BlockNumber int64
+}
+
+func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) {
+ var obj []interface{}
+ if err := json.Unmarshal(b, &obj); err != nil {
+ return NewDecodeParamError(err.Error())
+ }
+
+ if len(obj) < 1 {
+ return NewInsufficientParamsError(len(obj), 1)
+ }
+
+ if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
+ return err
}
return nil
@@ -493,31 +524,28 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
return NewDecodeParamError(err.Error())
}
- if len(obj) < 1 {
- return NewInsufficientParamsError(len(obj), 1)
+ if len(obj) < 2 {
+ return NewInsufficientParamsError(len(obj), 2)
}
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
return err
}
- if len(obj) > 1 {
- arg1, ok := obj[1].(string)
- if !ok {
- return NewInvalidTypeError("index", "not a string")
- }
- args.Index = common.Big(arg1).Int64()
+ arg1, ok := obj[1].(string)
+ if !ok {
+ return NewInvalidTypeError("index", "not a string")
}
+ args.Index = common.Big(arg1).Int64()
return nil
}
-type HashIndexArgs struct {
- Hash string
- Index int64
+type HashArgs struct {
+ Hash string
}
-func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
+func (args *HashArgs) UnmarshalJSON(b []byte) (err error) {
var obj []interface{}
if err := json.Unmarshal(b, &obj); err != nil {
return NewDecodeParamError(err.Error())
@@ -533,14 +561,36 @@ func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
}
args.Hash = arg0
- if len(obj) > 1 {
- arg1, ok := obj[1].(string)
- if !ok {
- return NewInvalidTypeError("index", "not a string")
- }
- args.Index = common.Big(arg1).Int64()
+ return nil
+}
+
+type HashIndexArgs struct {
+ Hash string
+ Index int64
+}
+
+func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
+ var obj []interface{}
+ if err := json.Unmarshal(b, &obj); err != nil {
+ return NewDecodeParamError(err.Error())
}
+ if len(obj) < 2 {
+ return NewInsufficientParamsError(len(obj), 2)
+ }
+
+ arg0, ok := obj[0].(string)
+ if !ok {
+ return NewInvalidTypeError("hash", "not a string")
+ }
+ args.Hash = arg0
+
+ arg1, ok := obj[1].(string)
+ if !ok {
+ return NewInvalidTypeError("index", "not a string")
+ }
+ args.Index = common.Big(arg1).Int64()
+
return nil
}
diff --git a/rpc/args_test.go b/rpc/args_test.go
index 3635882c00..902f8013e4 100644
--- a/rpc/args_test.go
+++ b/rpc/args_test.go
@@ -225,7 +225,7 @@ func TestGetBlockByHashArgsHashInt(t *testing.T) {
input := `[8]`
args := new(GetBlockByHashArgs)
- str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
+ str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args))
if len(str) > 0 {
t.Error(str)
}
@@ -281,6 +281,16 @@ func TestGetBlockByNumberEmpty(t *testing.T) {
}
}
+func TestGetBlockByNumberShort(t *testing.T) {
+ input := `["0xbbb"]`
+
+ args := new(GetBlockByNumberArgs)
+ str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args))
+ if len(str) > 0 {
+ t.Error(str)
+ }
+}
+
func TestGetBlockByNumberBool(t *testing.T) {
input := `[true, true]`
@@ -458,11 +468,16 @@ func TestNewTxArgsGasMissing(t *testing.T) {
"value": "0x9184e72a000",
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}]`
+ expected := new(NewTxArgs)
+ expected.Gas = big.NewInt(0)
args := new(NewTxArgs)
- str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
- if len(str) > 0 {
- t.Error(str)
+ if err := json.Unmarshal([]byte(input), &args); err != nil {
+ t.Error(err)
+ }
+
+ if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 {
+ t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas)
}
}
@@ -474,12 +489,18 @@ func TestNewTxArgsBlockGaspriceMissing(t *testing.T) {
"value": "0x9184e72a000",
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}]`
+ expected := new(NewTxArgs)
+ expected.GasPrice = big.NewInt(0)
args := new(NewTxArgs)
- str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
- if len(str) > 0 {
- t.Error(str)
+ if err := json.Unmarshal([]byte(input), &args); err != nil {
+ t.Error(err)
}
+
+ if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 {
+ t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice)
+ }
+
}
func TestNewTxArgsValueMissing(t *testing.T) {
@@ -490,12 +511,18 @@ func TestNewTxArgsValueMissing(t *testing.T) {
"gasPrice": "0x9184e72a000",
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}]`
+ expected := new(NewTxArgs)
+ expected.Value = big.NewInt(0)
args := new(NewTxArgs)
- str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
- if len(str) > 0 {
- t.Error(str)
+ if err := json.Unmarshal([]byte(input), &args); err != nil {
+ t.Error(err)
}
+
+ if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 {
+ t.Errorf("Value shoud be %v but is %v", expected.Value, args.Value)
+ }
+
}
func TestNewTxArgsEmpty(t *testing.T) {
diff --git a/rpc/jeth.go b/rpc/jeth.go
index 9d33f45e1d..e83212bb5c 100644
--- a/rpc/jeth.go
+++ b/rpc/jeth.go
@@ -2,6 +2,7 @@ package rpc
import (
"encoding/json"
+ "fmt"
// "fmt"
"github.com/ethereum/go-ethereum/jsre"
"github.com/robertkrimen/otto"
@@ -42,6 +43,7 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
var respif interface{}
err = self.ethApi.GetRequestReply(&req, &respif)
if err != nil {
+ fmt.Printf("error: %s\n", err)
return self.err(-32603, err.Error(), req.Id)
}
self.re.Set("ret_jsonrpc", jsonrpcver)
diff --git a/rpc/responses.go b/rpc/responses.go
index 45a2fa18b2..3d1687cb68 100644
--- a/rpc/responses.go
+++ b/rpc/responses.go
@@ -1,6 +1,8 @@
package rpc
import (
+ "encoding/json"
+
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
)
@@ -11,10 +13,10 @@ type BlockRes struct {
BlockNumber *hexnum `json:"number"`
BlockHash *hexdata `json:"hash"`
ParentHash *hexdata `json:"parentHash"`
- Nonce *hexnum `json:"nonce"`
+ Nonce *hexdata `json:"nonce"`
Sha3Uncles *hexdata `json:"sha3Uncles"`
LogsBloom *hexdata `json:"logsBloom"`
- TransactionRoot *hexdata `json:"transactionRoot"`
+ TransactionRoot *hexdata `json:"transactionsRoot"`
StateRoot *hexdata `json:"stateRoot"`
Miner *hexdata `json:"miner"`
Difficulty *hexnum `json:"difficulty"`
@@ -29,11 +31,104 @@ type BlockRes struct {
Uncles []*hexdata `json:"uncles"`
}
+func (b *BlockRes) MarshalJSON() ([]byte, error) {
+ if b.fullTx {
+ var ext struct {
+ BlockNumber *hexnum `json:"number"`
+ BlockHash *hexdata `json:"hash"`
+ ParentHash *hexdata `json:"parentHash"`
+ Nonce *hexdata `json:"nonce"`
+ Sha3Uncles *hexdata `json:"sha3Uncles"`
+ LogsBloom *hexdata `json:"logsBloom"`
+ TransactionRoot *hexdata `json:"transactionsRoot"`
+ StateRoot *hexdata `json:"stateRoot"`
+ Miner *hexdata `json:"miner"`
+ Difficulty *hexnum `json:"difficulty"`
+ TotalDifficulty *hexnum `json:"totalDifficulty"`
+ Size *hexnum `json:"size"`
+ ExtraData *hexdata `json:"extraData"`
+ GasLimit *hexnum `json:"gasLimit"`
+ MinGasPrice *hexnum `json:"minGasPrice"`
+ GasUsed *hexnum `json:"gasUsed"`
+ UnixTimestamp *hexnum `json:"timestamp"`
+ Transactions []*TransactionRes `json:"transactions"`
+ Uncles []*hexdata `json:"uncles"`
+ }
+
+ ext.BlockNumber = b.BlockNumber
+ ext.BlockHash = b.BlockHash
+ ext.ParentHash = b.ParentHash
+ ext.Nonce = b.Nonce
+ ext.Sha3Uncles = b.Sha3Uncles
+ ext.LogsBloom = b.LogsBloom
+ ext.TransactionRoot = b.TransactionRoot
+ ext.StateRoot = b.StateRoot
+ ext.Miner = b.Miner
+ ext.Difficulty = b.Difficulty
+ ext.TotalDifficulty = b.TotalDifficulty
+ ext.Size = b.Size
+ ext.ExtraData = b.ExtraData
+ ext.GasLimit = b.GasLimit
+ ext.MinGasPrice = b.MinGasPrice
+ ext.GasUsed = b.GasUsed
+ ext.UnixTimestamp = b.UnixTimestamp
+ ext.Transactions = b.Transactions
+ ext.Uncles = b.Uncles
+ return json.Marshal(ext)
+ } else {
+ var ext struct {
+ BlockNumber *hexnum `json:"number"`
+ BlockHash *hexdata `json:"hash"`
+ ParentHash *hexdata `json:"parentHash"`
+ Nonce *hexdata `json:"nonce"`
+ Sha3Uncles *hexdata `json:"sha3Uncles"`
+ LogsBloom *hexdata `json:"logsBloom"`
+ TransactionRoot *hexdata `json:"transactionsRoot"`
+ StateRoot *hexdata `json:"stateRoot"`
+ Miner *hexdata `json:"miner"`
+ Difficulty *hexnum `json:"difficulty"`
+ TotalDifficulty *hexnum `json:"totalDifficulty"`
+ Size *hexnum `json:"size"`
+ ExtraData *hexdata `json:"extraData"`
+ GasLimit *hexnum `json:"gasLimit"`
+ MinGasPrice *hexnum `json:"minGasPrice"`
+ GasUsed *hexnum `json:"gasUsed"`
+ UnixTimestamp *hexnum `json:"timestamp"`
+ Transactions []*hexdata `json:"transactions"`
+ Uncles []*hexdata `json:"uncles"`
+ }
+
+ ext.BlockNumber = b.BlockNumber
+ ext.BlockHash = b.BlockHash
+ ext.ParentHash = b.ParentHash
+ ext.Nonce = b.Nonce
+ ext.Sha3Uncles = b.Sha3Uncles
+ ext.LogsBloom = b.LogsBloom
+ ext.TransactionRoot = b.TransactionRoot
+ ext.StateRoot = b.StateRoot
+ ext.Miner = b.Miner
+ ext.Difficulty = b.Difficulty
+ ext.TotalDifficulty = b.TotalDifficulty
+ ext.Size = b.Size
+ ext.ExtraData = b.ExtraData
+ ext.GasLimit = b.GasLimit
+ ext.MinGasPrice = b.MinGasPrice
+ ext.GasUsed = b.GasUsed
+ ext.UnixTimestamp = b.UnixTimestamp
+ ext.Transactions = make([]*hexdata, len(b.Transactions))
+ for i, tx := range b.Transactions {
+ ext.Transactions[i] = tx.Hash
+ }
+ ext.Uncles = b.Uncles
+ return json.Marshal(ext)
+ }
+}
+
func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
// TODO respect fullTx flag
if block == nil {
- return &BlockRes{}
+ return nil
}
res := new(BlockRes)
@@ -41,7 +136,7 @@ func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
res.BlockNumber = newHexNum(block.Number())
res.BlockHash = newHexData(block.Hash())
res.ParentHash = newHexData(block.ParentHash())
- res.Nonce = newHexNum(block.Header().Nonce)
+ res.Nonce = newHexData(block.Nonce())
res.Sha3Uncles = newHexData(block.Header().UncleHash)
res.LogsBloom = newHexData(block.Bloom())
res.TransactionRoot = newHexData(block.Header().TxHash)
@@ -49,7 +144,7 @@ func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
res.Miner = newHexData(block.Header().Coinbase)
res.Difficulty = newHexNum(block.Difficulty())
res.TotalDifficulty = newHexNum(block.Td)
- res.Size = newHexNum(block.Size())
+ res.Size = newHexNum(block.Size().Int64())
res.ExtraData = newHexData(block.Header().Extra)
res.GasLimit = newHexNum(block.GasLimit())
// res.MinGasPrice =
diff --git a/rpc/responses_test.go b/rpc/responses_test.go
index 43924151a4..2ec6d9d15f 100644
--- a/rpc/responses_test.go
+++ b/rpc/responses_test.go
@@ -13,12 +13,16 @@ import (
)
const (
- reHash = `"0x[0-9a-f]{64}"` // 32 bytes
- reHashOpt = `"(0x[0-9a-f]{64})"|null` // 32 bytes or null
- reAddress = `"0x[0-9a-f]{40}"` // 20 bytes
- reAddressOpt = `"0x[0-9a-f]{40}"|null` // 20 bytes or null
- reNum = `"0x([1-9a-f][0-9a-f]{1,15})|0"` // must not have left-padded zeros
- reData = `"0x[0-9a-f]*"` // can be "empty"
+ reHash = `"0x[0-9a-f]{64}"` // 32 bytes
+ reHashOpt = `"(0x[0-9a-f]{64})"|null` // 32 bytes or null
+ reAddress = `"0x[0-9a-f]{40}"` // 20 bytes
+ reAddressOpt = `"0x[0-9a-f]{40}"|null` // 20 bytes or null
+ reNum = `"0x([1-9a-f][0-9a-f]{0,15})|0"` // must not have left-padded zeros
+ reNumNonZero = `"0x([1-9a-f][0-9a-f]{0,15})"` // non-zero required must not have left-padded zeros
+ reNumOpt = `"0x([1-9a-f][0-9a-f]{0,15})|0"|null` // must not have left-padded zeros or null
+ reData = `"0x[0-9a-f]*"` // can be "empty"
+ // reListHash = `[("\w":"0x[0-9a-f]{64}",?)*]`
+ // reListObj = `[("\w":(".+"|null),?)*]`
)
func TestNewBlockRes(t *testing.T) {
@@ -30,26 +34,87 @@ func TestNewBlockRes(t *testing.T) {
extra := ""
block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra)
tests := map[string]string{
- "number": reNum,
- "hash": reHash,
- "parentHash": reHash,
- "nonce": reNum,
- "sha3Uncles": reHash,
- "logsBloom": reData,
- "transactionRoot": reHash,
- "stateRoot": reHash,
- "miner": reAddress,
- "difficulty": `"0x1"`,
- "totalDifficulty": reNum,
- "size": reNum,
- "extraData": reData,
- "gasLimit": reNum,
+ "number": reNum,
+ "hash": reHash,
+ "parentHash": reHash,
+ "nonce": reData,
+ "sha3Uncles": reHash,
+ "logsBloom": reData,
+ "transactionsRoot": reHash,
+ "stateRoot": reHash,
+ "miner": reAddress,
+ "difficulty": `"0x1"`,
+ "totalDifficulty": reNum,
+ "size": reNumNonZero,
+ "extraData": reData,
+ "gasLimit": reNum,
// "minGasPrice": "0x",
"gasUsed": reNum,
"timestamp": reNum,
+ // "transactions": reListHash,
+ // "uncles": reListHash,
}
+ to := common.HexToAddress("0x02")
+ amount := big.NewInt(1)
+ gasAmount := big.NewInt(1)
+ gasPrice := big.NewInt(1)
+ data := []byte{1, 2, 3}
+ tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data)
+
v := NewBlockRes(block, false)
+ v.Transactions = make([]*TransactionRes, 1)
+ v.Transactions[0] = NewTransactionRes(tx)
+ j, _ := json.Marshal(v)
+
+ for k, re := range tests {
+ match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
+ if !match {
+ t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j))
+ }
+ }
+}
+
+func TestNewBlockResWithTrans(t *testing.T) {
+ parentHash := common.HexToHash("0x01")
+ coinbase := common.HexToAddress("0x01")
+ root := common.HexToHash("0x01")
+ difficulty := common.Big1
+ nonce := uint64(1)
+ extra := ""
+ block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra)
+ tests := map[string]string{
+ "number": reNum,
+ "hash": reHash,
+ "parentHash": reHash,
+ "nonce": reData,
+ "sha3Uncles": reHash,
+ "logsBloom": reData,
+ "transactionsRoot": reHash,
+ "stateRoot": reHash,
+ "miner": reAddress,
+ "difficulty": `"0x1"`,
+ "totalDifficulty": reNum,
+ "size": reNumNonZero,
+ "extraData": reData,
+ "gasLimit": reNum,
+ // "minGasPrice": "0x",
+ "gasUsed": reNum,
+ "timestamp": reNum,
+ // "transactions": `[{.*}]`,
+ // "uncles": reListHash,
+ }
+
+ to := common.HexToAddress("0x02")
+ amount := big.NewInt(1)
+ gasAmount := big.NewInt(1)
+ gasPrice := big.NewInt(1)
+ data := []byte{1, 2, 3}
+ tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data)
+
+ v := NewBlockRes(block, true)
+ v.Transactions = make([]*TransactionRes, 1)
+ v.Transactions[0] = NewTransactionRes(tx)
j, _ := json.Marshal(v)
for k, re := range tests {
@@ -71,9 +136,9 @@ func TestNewTransactionRes(t *testing.T) {
tests := map[string]string{
"hash": reHash,
"nonce": reNum,
- "blockHash": reHash,
- "blockNum": reNum,
- "transactionIndex": reNum,
+ "blockHash": reHashOpt,
+ "blockNum": reNumOpt,
+ "transactionIndex": reNumOpt,
"from": reAddress,
"to": reAddressOpt,
"value": reNum,
diff --git a/rpc/messages.go b/rpc/types.go
similarity index 80%
rename from rpc/messages.go
rename to rpc/types.go
index 3c011cd93b..806c9c8a43 100644
--- a/rpc/messages.go
+++ b/rpc/types.go
@@ -17,16 +17,19 @@
package rpc
import (
+ "encoding/binary"
"encoding/json"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
)
type hexdata struct {
- data []byte
+ data []byte
+ isNil bool
}
func (d *hexdata) String() string {
@@ -34,6 +37,9 @@ func (d *hexdata) String() string {
}
func (d *hexdata) MarshalJSON() ([]byte, error) {
+ if d.isNil {
+ return json.Marshal(nil)
+ }
return json.Marshal(d.String())
}
@@ -45,27 +51,69 @@ func (d *hexdata) UnmarshalJSON(b []byte) (err error) {
func newHexData(input interface{}) *hexdata {
d := new(hexdata)
+ if input == nil {
+ d.data = nil
+ return d
+ }
switch input := input.(type) {
case []byte:
d.data = input
case common.Hash:
d.data = input.Bytes()
case *common.Hash:
- d.data = input.Bytes()
+ if input == nil {
+ d.isNil = true
+ } else {
+ d.data = input.Bytes()
+ }
case common.Address:
d.data = input.Bytes()
case *common.Address:
+ if input == nil {
+ d.isNil = true
+ } else {
+ d.data = input.Bytes()
+ }
+ case types.Bloom:
d.data = input.Bytes()
+ case *types.Bloom:
+ if input == nil {
+ d.isNil = true
+ } else {
+ d.data = input.Bytes()
+ }
case *big.Int:
- d.data = input.Bytes()
+ if input == nil {
+ d.isNil = true
+ } else {
+ d.data = input.Bytes()
+ }
case int64:
d.data = big.NewInt(input).Bytes()
case uint64:
- d.data = big.NewInt(int64(input)).Bytes()
+ buff := make([]byte, 8)
+ binary.BigEndian.PutUint64(buff, input)
+ d.data = buff
case int:
d.data = big.NewInt(int64(input)).Bytes()
case uint:
d.data = big.NewInt(int64(input)).Bytes()
+ case int8:
+ d.data = big.NewInt(int64(input)).Bytes()
+ case uint8:
+ d.data = big.NewInt(int64(input)).Bytes()
+ case int16:
+ d.data = big.NewInt(int64(input)).Bytes()
+ case uint16:
+ buff := make([]byte, 8)
+ binary.BigEndian.PutUint16(buff, input)
+ d.data = buff
+ case int32:
+ d.data = big.NewInt(int64(input)).Bytes()
+ case uint32:
+ buff := make([]byte, 8)
+ binary.BigEndian.PutUint32(buff, input)
+ d.data = buff
case string: // hexstring
d.data = common.Big(input).Bytes()
default:
@@ -76,14 +124,15 @@ func newHexData(input interface{}) *hexdata {
}
type hexnum struct {
- data []byte
+ data []byte
+ isNil bool
}
func (d *hexnum) String() string {
// Get hex string from bytes
out := common.Bytes2Hex(d.data)
// Trim leading 0s
- out = strings.Trim(out, "0")
+ out = strings.TrimLeft(out, "0")
// Output "0x0" when value is 0
if len(out) == 0 {
out = "0"
@@ -92,6 +141,9 @@ func (d *hexnum) String() string {
}
func (d *hexnum) MarshalJSON() ([]byte, error) {
+ if d.isNil {
+ return json.Marshal(nil)
+ }
return json.Marshal(d.String())
}
diff --git a/rpc/messages_test.go b/rpc/types_test.go
similarity index 100%
rename from rpc/messages_test.go
rename to rpc/types_test.go
diff --git a/xeth/xeth.go b/xeth/xeth.go
index 0a813ec99c..b203e45dee 100644
--- a/xeth/xeth.go
+++ b/xeth/xeth.go
@@ -29,6 +29,9 @@ var (
defaultGas = big.NewInt(90000) //500000
)
+func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }
+func DefaultGasPrice() *big.Int { return new(big.Int).Set(defaultGasPrice) }
+
type XEth struct {
backend *eth.Ethereum
frontend Frontend
@@ -130,9 +133,6 @@ func cTopics(t [][]string) [][]common.Hash {
return topics
}
-func (self *XEth) DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }
-func (self *XEth) DefaultGasPrice() *big.Int { return new(big.Int).Set(defaultGasPrice) }
-
func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
func (self *XEth) AtStateNum(num int64) *XEth {
@@ -312,7 +312,7 @@ func (self *XEth) StorageAt(addr, storageAddr string) string {
}
func (self *XEth) BalanceAt(addr string) string {
- return self.State().state.GetBalance(common.HexToAddress(addr)).String()
+ return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
}
func (self *XEth) TxCountAt(address string) int {
@@ -323,6 +323,10 @@ func (self *XEth) CodeAt(address string) string {
return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
}
+func (self *XEth) CodeAtBytes(address string) []byte {
+ return self.State().SafeGet(address).Code()
+}
+
func (self *XEth) IsContract(address string) bool {
return len(self.State().SafeGet(address).Code()) > 0
}
@@ -566,11 +570,11 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
}
if msg.gas.Cmp(big.NewInt(0)) == 0 {
- msg.gas = self.DefaultGas()
+ msg.gas = DefaultGas()
}
if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
- msg.gasPrice = self.DefaultGasPrice()
+ msg.gasPrice = DefaultGasPrice()
}
block := self.CurrentBlock()
@@ -616,11 +620,11 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
// TODO: align default values to have the same type, e.g. not depend on
// common.Value conversions later on
if gas.Cmp(big.NewInt(0)) == 0 {
- gas = self.DefaultGas()
+ gas = DefaultGas()
}
if price.Cmp(big.NewInt(0)) == 0 {
- price = self.DefaultGasPrice()
+ price = DefaultGasPrice()
}
data = common.FromHex(codeStr)