diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fd82ddeec..454865b3d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -379,6 +379,7 @@ darwin: export PLATFORM=x86_64-apple-darwin cargo build -j 8 --features final --release #$CARGOFLAGS cargo build -j 8 --features final --release -p ethstore #$CARGOFLAGS + cargo build -j 8 --features final --release -p evmbin #$CARGOFLAGS rm -rf parity.md5 md5sum target/release/parity > parity.md5 export SHA3=$(target/release/parity tools hash target/release/parity) @@ -500,7 +501,7 @@ test-windows: - git submodule update --init --recursive script: - set RUST_BACKTRACE=1 - - echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release + - echo cargo test --features json-tests -p rlp -p ethash -p ethcore -p ethcore-bigint -p ethcore-dapps -p ethcore-rpc -p ethcore-signer -p ethcore-util -p ethcore-network -p ethcore-io -p ethkey -p ethstore -p evmbin -p ethsync -p ethcore-ipc -p ethcore-ipc-tests -p ethcore-ipc-nano -p parity %CARGOFLAGS% --verbose --release tags: - rust-windows allow_failure: true diff --git a/Cargo.lock b/Cargo.lock index e0c32a6db..f35531164 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,7 @@ dependencies = [ "ethcore-stratum 1.5.0", "ethcore-util 1.5.2", "ethsync 1.5.0", + "evmbin 1.5.0", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.14 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -766,6 +767,16 @@ dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "evmbin" +version = "1.5.0" +dependencies = [ + "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore 1.5.0", + "ethcore-util 1.5.2", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "evmjit" version = "1.5.0" diff --git a/Cargo.toml b/Cargo.toml index b2a0e0125..4e13a1ed8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ ethcore-ipc-hypervisor = { path = "ipc/hypervisor" } ethcore-logger = { path = "logger" } ethcore-stratum = { path = "stratum" } ethcore-dapps = { path = "dapps", optional = true } +evmbin = { path = "evmbin" } rpc-cli = { path = "rpc_cli" } parity-rpc-client = { path = "rpc_client" } ethcore-light = { path = "ethcore/light" } diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 64ee0c341..1ce99cbc8 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -312,7 +312,7 @@ impl Server { let special = Arc::new({ let mut special = HashMap::new(); - special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, panic_handler.clone())); + special.insert(router::SpecialEndpoint::Rpc, rpc::rpc(handler, cors_domains.clone(), panic_handler.clone())); special.insert(router::SpecialEndpoint::Utils, apps::utils()); special.insert( router::SpecialEndpoint::Api, diff --git a/dapps/src/rpc.rs b/dapps/src/rpc.rs index 27414f2be..d82c2e9c9 100644 --- a/dapps/src/rpc.rs +++ b/dapps/src/rpc.rs @@ -21,11 +21,15 @@ use jsonrpc_core::{IoHandler, ResponseHandler, Request, Response}; use jsonrpc_http_server::{ServerHandler, PanicHandler, AccessControlAllowOrigin, RpcHandler}; use endpoint::{Endpoint, EndpointPath, Handler}; -pub fn rpc(handler: Arc, panic_handler: Arc () + Send>>>>) -> Box { +pub fn rpc( + handler: Arc, + cors_domains: Vec, + panic_handler: Arc () + Send>>>>, +) -> Box { Box::new(RpcEndpoint { handler: Arc::new(RpcMiddleware::new(handler)), panic_handler: panic_handler, - cors_domain: None, + cors_domain: Some(cors_domains.into_iter().map(AccessControlAllowOrigin::Value).collect()), // NOTE [ToDr] We don't need to do any hosts validation here. It's already done in router. allowed_hosts: None, }) diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index ad2d69d57..07f87d7cf 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -1,7 +1,7 @@ [package] -name = "evm" +name = "evmbin" description = "Parity's EVM implementation" -version = "0.1.0" +version = "1.5.0" authors = ["Parity Technologies "] [lib] diff --git a/evmbin/src/ext.rs b/evmbin/src/ext.rs index af0836ad0..4f13de825 100644 --- a/evmbin/src/ext.rs +++ b/evmbin/src/ext.rs @@ -31,7 +31,7 @@ pub struct FakeExt { impl Default for FakeExt { fn default() -> Self { FakeExt { - schedule: Schedule::new_homestead_gas_fix(), + schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true), store: HashMap::new(), depth: 1, } @@ -51,8 +51,8 @@ impl Ext for FakeExt { unimplemented!(); } - fn exists_and_not_null(&self, address: &Address) -> bool { - unimplemented!(); + fn exists_and_not_null(&self, _address: &Address) -> bool { + unimplemented!(); } fn origin_balance(&self) -> U256 { diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index 743b517ec..3997427d9 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -21,7 +21,6 @@ extern crate ethcore; extern crate rustc_serialize; extern crate docopt; -#[macro_use] extern crate ethcore_util as util; mod ext; diff --git a/js/src/dapps/localtx/Transaction/transaction.js b/js/src/dapps/localtx/Transaction/transaction.js index a2f023902..08dca6c2b 100644 --- a/js/src/dapps/localtx/Transaction/transaction.js +++ b/js/src/dapps/localtx/Transaction/transaction.js @@ -260,7 +260,7 @@ export class LocalTransaction extends BaseTransaction { to: transaction.to, nonce: transaction.nonce, value: transaction.value, - data: transaction.data, + data: transaction.input, gasPrice, gas }; diff --git a/js/src/dapps/static/console.js b/js/src/dapps/static/console.js index 01d60e77a..b6faee7f0 100755 --- a/js/src/dapps/static/console.js +++ b/js/src/dapps/static/console.js @@ -1,4 +1,4 @@ -// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify @@ -14,200 +14,305 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -/* eslint-disable */ -// TODO: Fix linting issues +/* global web3 */ -if (typeof(window.parity) == 'object') +if (typeof (window.parent.secureApi) === 'object') { window.api = window.parent.secureApi; - window.parity.api.subscribe('eth_blockNumber', function (error, blockNumber) { + + if (typeof (window.Web3) === 'function') { + Promise.all([ + window.api.parity.dappsInterface(), + window.api.parity.dappsPort() + ]).then(res => { + window.web3 = new window.Web3(new window.Web3.providers.HttpProvider(`http://${res.join(':')}/rpc/`)); + }); + } +} else if (typeof (window.parity) === 'object') { + window.api = window.parity.api; +} + +if (typeof (window.api) === 'object') { + window.api.subscribe('eth_blockNumber', function (error, blockNumber) { if (error) { console.log('error', error); return; } refreshWatches(); }); - -function escapeHtml(str) { - var div = document.createElement('div'); - div.appendChild(document.createTextNode(str)); - return div.innerHTML; } -function getAllPropertyNames(obj) { - var props = {}; - do { - Object.getOwnPropertyNames(obj).forEach(n => props[n] = true); - } while (obj = Object.getPrototypeOf(obj)); - return Object.keys(props); +function escapeHtml (str) { + let div = document.createElement('div'); + + div.appendChild(document.createTextNode(str)); + return div.innerHTML; } -function htmlToElement(html) { - var template = document.createElement('template'); - template.innerHTML = html; - return template.content.firstChild; +function getAllPropertyNames (obj) { + let props = {}; + + do { + Object.getOwnPropertyNames(obj).forEach(n => { + props[n] = true; + }); + obj = Object.getPrototypeOf(obj); + } while (obj); + + return Object.keys(props); } -function evaluate(x) { +function evaluate (x) { try { - return eval(x); - } - catch (err) { - return eval('(()=>{var x = ' + x + "; return x;})()") + return eval(x); // eslint-disable-line no-eval + } catch (err) { + return eval('(()=>{let x = ' + x + '; return x;})()'); // eslint-disable-line no-eval } } -function displayReady(x) { - if (x === undefined) - return 'undefined'; - if (x === null) +function safeAccess (obj, prop) { + try { + return obj[prop]; + } catch (e) { + return '[Error] ' + e; + } +} + +function displayReady (x, visited = []) { + visited.push(x); + let toString = Object.prototype.toString; + + if (x === undefined) { return 'undefined'; } + if (x === null) { return 'null'; - if (typeof(x) == "string") - return `"${escapeHtml(x)}"`; - if (Object.prototype.toString.call(x) === '[object Array]') - return `[${x.map(displayReady).join(', ')}]`; - if (typeof(x) == "function") - return `function () { /* ... */ }`; - if (typeof(x) == "object") { - if (x.toString().indexOf('[object ') != 0) - return `${escapeHtml(x.toString())}`; - return `${x.constructor.name} {${Object.keys(x).map(f => `${escapeHtml(f)}: ${displayReady(x[f])}`).join(', ')}}`; } - return `${escapeHtml(JSON.stringify(x))}`; + if (typeof (x) === 'string') { + return `"${escapeHtml(x)}"`; + } + if (toString.call(x) === '[object Array]') { + return `[${x.map(el => displayReady(el, visited)).join(', ')}]`; + } + if (typeof (x) === 'function') { return `function () { /* ... */ }`; } + if (typeof (x) === 'object') { + let constructor = x.constructor || Object; + let objToString = typeof (x.toString) === 'function' ? x.toString : toString; + + if (objToString.call(x).indexOf('[object ') !== 0) { + return `${escapeHtml(objToString.call(x))}`; + } + + return ` + + ${constructor.name} { + ${Object.keys(x).filter(f => visited.indexOf(safeAccess(x, f)) === -1).map(f => ` + ${escapeHtml(f)}: ${displayReady(safeAccess(x, f), visited)} + `).join(', ')} + } + + `; + } + return `${escapeHtml(JSON.stringify(x))}`; } -if (!localStorage.history) - localStorage.history = "[]"; +if (!localStorage.history) { + localStorage.history = '[]'; +} window.historyData = JSON.parse(localStorage.history); window.historyIndex = window.historyData.length; -if (!localStorage.watches) - localStorage.watches = "[]"; +if (!localStorage.watches) { + localStorage.watches = '[]'; +} window.watches = {}; -function watch(name, f) { - let status = document.getElementById("status"); +function watch (name, f) { + let status = document.getElementById('status'); let cleanName = name.replace(/[^a-zA-Z0-9]/, ''); - status.innerHTML += `
${escapeHtml(name)}
`; + + status.innerHTML += ` +
+ ${escapeHtml(name)} + +
+ `; window.watches[name] = f; } -var savedWatches = JSON.parse(localStorage.watches); +let savedWatches = JSON.parse(localStorage.watches); + savedWatches.forEach(w => watch(w[1], () => evaluate(w[0]))); -if (typeof(window.web3) == 'object' && window.watches.latest == undefined) +if (typeof (window.web3) === 'object' && window.watches.latest === undefined) { watch('latest', () => window.web3.eth.blockNumber); +} - -function refreshWatches() { - for (n in window.watches) { +function refreshWatches () { + for (let n in window.watches) { let r = window.watches[n](); let cn = n.replace(/[^a-zA-Z0-9]/, ''); let e = document.getElementById(`res_${cn}`); - if (typeof(r) == 'object' && r.constructor.name == "Promise") - r.then(r => e.innerHTML = displayReady(r)); - else + + if (typeof (r) === 'object' && r.then && r.then.call) { + r.then(r => { + e.innerHTML = displayReady(r); + }); + } else { e.innerHTML = displayReady(r); + } } } -function removeWatch(name) { +function removeWatch (name) { let e = document.getElementById(`watch_${name}`); + e.parentNode.removeChild(e); delete window.watches[name]; } -function newLog(level, text) { +function newLog (level, text) { let icon = { - debug: " ", - log: " ", - warn: "⚠", - error: "✖", - info: "ℹ" + debug: ' ', + log: ' ', + warn: '⚠', + error: '✖', + info: 'ℹ' }; - pushLine('
' + icon[level] + '' + escapeHtml(text) + '
'); + + pushLine([ + '
', + icon[level], + '', + escapeHtml(text), + '
' + ].join('')); } -function exec() { - let command = document.getElementById("command"); +function exec () { + let command = document.getElementById('command'); let c = command.value; - if (c != '') { - command.value = ""; + if (c !== '') { + command.value = ''; window.historyData.push(c); - while (window.historyData.length > 1000) - window.historyData.shift; + while (window.historyData.length > 1000) { + window.historyData.shift(); + } + localStorage.history = JSON.stringify(window.historyData); window.historyIndex = window.historyData.length; - var html = ''; - if (c.indexOf("//") == 0) { + if (c.indexOf('//') === 0) { let n = c.substr(2); - savedWatches = savedWatches.filter(x => x[1] != n); + + savedWatches = savedWatches.filter(x => x[1] !== n); localStorage.watches = JSON.stringify(savedWatches); removeWatch(n); - } - else if (c.indexOf("//") != -1) { - x = c.split("//"); + } else if (c.indexOf('//') !== -1) { + let x = c.split('//'); let e = x[0]; + savedWatches.push(x); localStorage.watches = JSON.stringify(savedWatches); watch(x[1], () => evaluate(e)); - pushLine('
>' + escapeHtml(c) + '
'); - pushLine('
Watch added
'); - } - else { - pushLine('
>' + escapeHtml(c) + '
'); + + pushLine([ + '
>', + escapeHtml(c), + '
' + ].join('')); + + pushLine([ + '
', + 'Watch added', + '
' + ].join('')); + } else { + pushLine([ + '
>', + escapeHtml(c), + '
' + ].join('')); + let res; + try { res = evaluate(c); - if (typeof(res) == 'object' && res !== null && res.constructor.name == "Promise") { + if (typeof (res) === 'object' && res !== null && typeof res.then === 'function') { let id = window.historyData.length; - pushLine('
<...
'); - res.then(r => document.getElementById('pending' + id).innerHTML = displayReady(r)); + + pushLine([ + '
<...
' + ].join('')); + + res.then(r => { + document.getElementById('pending' + id).innerHTML = displayReady(r); + }); } else { - pushLine('
<' + displayReady(res) + '
'); + pushLine([ + '
<', + displayReady(res), + '
' + ].join('')); } - } - catch (err) { - pushLine('
Unhandled exception: ' + escapeHtml(err.message) + '
'); + } catch (err) { + pushLine([ + '
Unhandled exception: ', + escapeHtml(err.message), + '
' + ]); } } } + refreshWatches(); } -function pushLine(l) { - document.getElementById("history").innerHTML += l - var h = document.getElementById("history-wrap"); +function pushLine (l) { + document.getElementById('history').innerHTML += l; + let h = document.getElementById('history-wrap'); + h.scrollTop = h.scrollHeight; } -var autocompletes = []; -var currentAuto = null; -var currentPots = []; -var currentStem = null; +let autocompletes = []; +let currentAuto = null; +let currentPots = []; +let currentStem = null; -function updateAutocomplete() { - let v = document.getElementById("command").value; - if (v.length == 0) { +function updateAutocomplete () { + let v = document.getElementById('command').value; + + if (!v.length) { cancelAutocomplete(); return; } + let t = v.split('.'); let last = t.pop(); let tj = t.join('.'); let ex = t.length > 0 ? tj : 'window'; - if (currentStem != tj) { - autocompletes = eval('getAllPropertyNames('+ex+')'); + + if (currentStem !== tj) { + autocompletes = getAllPropertyNames(evaluate(ex)); currentStem = tj; } - let dl = document.getElementById("autocomplete"); + + let dl = document.getElementById('autocomplete'); + currentPots = autocompletes.filter(n => n.startsWith(last)); if (currentPots.length > 0) { - if (currentPots.indexOf(currentAuto) == -1) + if (currentPots.indexOf(currentAuto) === -1) { currentAuto = currentPots[0]; + } + dl.innerHTML = currentPots -// .map(n => `${tj != '' ? tj + '.' : ''}${n}`) - .map((n, i) => `
${escapeHtml(last)}${escapeHtml(n.substr(last.length))}
`) + .map((n, i) => ` +
+ ${escapeHtml(last)}${escapeHtml(n.substr(last.length))} +
` + ) .join(''); dl.hidden = false; } else { @@ -215,388 +320,411 @@ function updateAutocomplete() { } } -function enactAutocomplete() { +function enactAutocomplete () { if (currentAuto != null) { - document.getElementById("command").value = (currentStem != '' ? currentStem + '.' : '') + currentAuto; + document.getElementById('command').value = (currentStem !== '' ? currentStem + '.' : '') + currentAuto; cancelAutocomplete(); } } -function cancelAutocomplete() { - document.getElementById("autocomplete").hidden = true; +function cancelAutocomplete () { + document.getElementById('autocomplete').hidden = true; currentAuto = null; } -function scrollAutocomplete(positive) { +function scrollAutocomplete (positive) { if (currentAuto != null) { - var i = currentPots.indexOf(currentAuto); + let i = currentPots.indexOf(currentAuto); + document.getElementById('pot' + i).classList = ['ac-unselected']; - if (positive && i < currentPots.length - 1) + if (positive && i < currentPots.length - 1) { ++i; - else if (!positive && i > 0) + } else if (!positive && i > 0) { --i; + } currentAuto = currentPots[i]; let sel = document.getElementById('pot' + i); + sel.classList = ['ac-selected']; sel.scrollIntoViewIfNeeded(); } } -document.getElementById("command").addEventListener("paste", updateAutocomplete); -document.getElementById("command").addEventListener("input", updateAutocomplete); -document.getElementById("command").addEventListener("focusout", cancelAutocomplete); -document.getElementById("command").addEventListener("blur", cancelAutocomplete); +document.getElementById('command').addEventListener('paste', updateAutocomplete); +document.getElementById('command').addEventListener('input', updateAutocomplete); +document.getElementById('command').addEventListener('focusout', cancelAutocomplete); +document.getElementById('command').addEventListener('blur', cancelAutocomplete); + +document.getElementById('command').addEventListener('keydown', function (event) { + let el = document.getElementById('command'); -document.getElementById("command").addEventListener("keydown", function(event) { - let el = document.getElementById("command"); if (currentAuto != null) { - if (event.keyCode == 38 || event.keyCode == 40) { + if (event.keyCode === 38 || event.keyCode === 40) { event.preventDefault(); - scrollAutocomplete(event.keyCode == 40); - } - else if ((event.keyCode == 39 || event.keyCode == 9 || event.keyCode == 13) && el.selectionStart == el.value.length) { + scrollAutocomplete(event.keyCode === 40); + } else if ((event.keyCode === 39 || event.keyCode === 9 || event.keyCode === 13) && el.selectionStart === el.value.length) { event.preventDefault(); enactAutocomplete(); - } - else if (event.keyCode == 27) { + } else if (event.keyCode === 27) { event.preventDefault(); cancelAutocomplete(); } } else { - let command = document.getElementById("command"); - if (event.keyCode == 38 && window.historyIndex > 0) { + let command = document.getElementById('command'); + + if (event.keyCode === 38 && window.historyIndex > 0) { event.preventDefault(); window.historyIndex--; command.value = window.historyData[window.historyIndex]; } - if (event.keyCode == 40 && window.historyIndex < window.historyData.length) { + if (event.keyCode === 40 && window.historyIndex < window.historyData.length) { event.preventDefault(); window.historyIndex++; - command.value = window.historyIndex < window.historyData.length ? window.historyData[window.historyIndex] : ""; + command.value = window.historyIndex < window.historyData.length ? window.historyData[window.historyIndex] : ''; } } - if (event.keyCode >= 48 || event.keyCode == 8) { - let t = document.getElementById("command").value; + + if (event.keyCode >= 48 || event.keyCode === 8) { + let t = document.getElementById('command').value; + setTimeout(() => { - if (t != document.getElementById("command").value) + if (t !== document.getElementById('command').value) { updateAutocomplete(); + } }, 0); - } - else { + } else { setTimeout(() => { - if (el.selectionStart != el.value.length) + if (el.selectionStart !== el.value.length) { cancelAutocomplete(); + } }, 0); } }); -document.getElementById("command").addEventListener("keyup", function(event) { - if (event.keyCode == 13) { +document.getElementById('command').addEventListener('keyup', function (event) { + if (event.keyCode === 13) { event.preventDefault(); exec(); } }); -if (typeof(window.parity) == 'object') { - document.getElementById("command").focus(); +document.getElementById('command').focus(); +if (typeof (web3) === 'object') { window.web3 = web3; - window.parity = parity; } refreshWatches(); -["debug", "error", "info", "log", "warn"].forEach(n => { let old = window.console[n]; window.console[n] = x => { old(x); newLog(n, x); }; }); +['debug', 'error', 'info', 'log', 'warn'].forEach(n => { + let old = window.console[n].bind(window.console); - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -///// Home comforts. - - -// Usage example: -// web3.eth.traceCall({ -// to: theChicken.address, -// data: theChicken.withdraw.getData(100000000000000000), -// gas: 100000 -// }, -// `["trace", "vmTrace", "stateDiff"] -// ) -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'traceCall', - call: 'trace_call', - params: 2, - inputFormatter: [web3._extend.formatters.inputCallFormatter, null] - }) - ] + window.console[n] = x => { + old(x); + newLog(n, x); + }; }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'traceSendRawTransaction', - call: 'trace_rawTransaction', - params: 2, - inputFormatter: [null, null] - }) - ] -}); +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// /// Home comforts. -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'traceReplayTransaction', - call: 'trace_replayTransaction', - params: 2, - inputFormatter: [null, null] - }) - ] -}); +if (typeof (web3) === 'object') { + // Usage example: + // web3.eth.traceCall({ + // to: theChicken.address, + // data: theChicken.withdraw.getData(100000000000000000), + // gas: 100000 + // }, + // `["trace", "vmTrace", "stateDiff"] + // ) + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'traceCall', + call: 'trace_call', + params: 2, + inputFormatter: [web3._extend.formatters.inputCallFormatter, null] + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'setMode', - call: 'ethcore_setMode', - params: 1, - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'traceSendRawTransaction', + call: 'trace_rawTransaction', + params: 2, + inputFormatter: [null, null] + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'mode', - call: 'ethcore_mode', - params: 0, - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'traceReplayTransaction', + call: 'trace_replayTransaction', + params: 2, + inputFormatter: [null, null] + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'traceTransaction', - call: 'trace_Transaction', - params: 1, - inputFormatter: [null] - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'setMode', + call: 'parity_setMode', + params: 1 + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'gasPriceStatistics', - call: 'ethcore_gasPriceStatistics', - params: 0, - outputFormatter: function(a) { return a.map(web3.toBigNumber); } - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'mode', + call: 'parity_mode', + params: 0 + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'registryAddress', - call: 'ethcore_registryAddress', - params: 0 - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'traceTransaction', + call: 'trace_Transaction', + params: 1, + inputFormatter: [null] + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'accountsInfo', - call: 'personal_accountsInfo', - outputFormatter: function(m) { Object.keys(m).forEach(k => { - m[k].meta = JSON.parse(m[k].meta); - m[k].meta.name = m[k].name; - m[k].meta.uuid = m[k].uuid; - m[k] = m[k].meta; - }); return m; }, - params: 0 - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'gasPriceStatistics', + call: 'parity_gasPriceStatistics', + params: 0, + outputFormatter: function (a) { return a.map(web3.toBigNumber); } + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'setAccountName', - call: 'personal_setAccountName', - params: 2, - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'registryAddress', + call: 'parity_registryAddress', + params: 0 + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'setAccountMeta', - call: 'personal_setAccountMeta', - params: 2, - inputFormatter: [a => a, JSON.stringify] - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'accountsInfo', + call: 'personal_accountsInfo', + outputFormatter: function (m) { + Object.keys(m).forEach(k => { + m[k].meta = JSON.parse(m[k].meta); + m[k].meta.name = m[k].name; + m[k].meta.uuid = m[k].uuid; + m[k] = m[k].meta; + }); return m; + }, + params: 0 + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'postTransaction', - call: 'eth_postTransaction', - params: 1, - inputFormatter: [web3._extend.formatters.inputCallFormatter] - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'setAccountName', + call: 'personal_setAccountName', + params: 2 + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'postSign', - call: 'eth_postSign', - params: 1 - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'setAccountMeta', + call: 'personal_setAccountMeta', + params: 2, + inputFormatter: [a => a, JSON.stringify] + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'encryptMessage', - call: 'ethcore_encryptMessage', - params: 2 - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'postTransaction', + call: 'eth_postTransaction', + params: 1, + inputFormatter: [web3._extend.formatters.inputCallFormatter] + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'checkRequest', - call: 'eth_checkRequest', - params: 1 - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'postSign', + call: 'eth_postSign', + params: 1 + }) + ] + }); -web3._extend({ - property: 'eth', - methods: [ - new web3._extend.Method({ - name: 'listAccounts', - call: 'ethcore_listAccounts', - params: 0 - }) - ] -}); + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'encryptMessage', + call: 'parity_encryptMessage', + params: 2 + }) + ] + }); -{ - var postTransaction = web3.eth.postTransaction.bind(web3.eth); - var sendTransaction = web3.eth.sendTransaction.bind(web3.eth); - web3.eth.sendTransaction = function(options, f) { - // No callback - do sync API. - if (typeof f != "function") - return sendTransaction(options); - // Callback - use async API. - var id = postTransaction(options); - console.log("Posted trasaction id=" + id); - var timerId = window.setInterval(check, 500); - function check() { - try { - let r = web3.eth.checkRequest(id); - if (typeof r == 'string') { - clearInterval(timerId); - if (r == "0x0000000000000000000000000000000000000000000000000000000000000000") - f("Rejected", r); - else - f(null, r); - } else if (r !== null) { - console.log("checkRequest returned: " + r); - } - } - catch (e) { - clearInterval(timerId); - f("Rejected", null); - } - } - } + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'checkRequest', + call: 'eth_checkRequest', + params: 1 + }) + ] + }); + + web3._extend({ + property: 'eth', + methods: [ + new web3._extend.Method({ + name: 'listAccounts', + call: 'parity_listAccounts', + params: 0 + }) + ] + }); + + { + let postTransaction = web3.eth.postTransaction.bind(web3.eth); + let sendTransaction = web3.eth.sendTransaction.bind(web3.eth); + + web3.eth.sendTransaction = function (options, f) { + // No callback - do sync API. + if (typeof f !== 'function') { + return sendTransaction(options); + } + // Callback - use async API. + let id = postTransaction(options); + + console.log('Posted trasaction id=' + id); + let timerId = window.setInterval(check, 500); + + function check () { + try { + let r = web3.eth.checkRequest(id); + + if (typeof r === 'string') { + clearInterval(timerId); + if (r === '0x0000000000000000000000000000000000000000000000000000000000000000') { + f('Rejected', r); + } else { + f(null, r); + } + } else if (r !== null) { + console.log('checkRequest returned: ' + r); + } + } catch (e) { + clearInterval(timerId); + f('Rejected', null); + } + } + }; + } + + web3.eth.installInterceptor = function (interceptor) { + let oldSendTransaction = web3.eth.sendTransaction.bind(web3.eth); + + web3.eth.sendTransaction = function (options, f) { + if (!interceptor(options)) { + return '0x0000000000000000000000000000000000000000000000000000000000000000'; + } + + return oldSendTransaction(options, f); + }; + }; + + web3.eth.reporter = function (e, r) { + if (e) { + console.log('Error confirming transaction: ' + e); + } else { + let addr = r; + let confirmed = false; + let timerId = window.setInterval(function check () { + let receipt = web3.eth.getTransactionReceipt(addr); + + if (receipt != null) { + if (!confirmed) { + console.log('Transaction confirmed (' + r + '); used ' + receipt.gasUsed + ' gas; left ' + receipt.logs.length + ' logs; mining...'); + confirmed = true; + } + if (typeof receipt.blockHash === 'string') { + clearInterval(timerId); + console.log('Mined into block ' + receipt.blockNumber); + } + } + }, 500); + } + }; + + { + let oldSha3 = web3.sha3; + + web3.sha3 = function (data, format) { + if (typeof format !== 'string' || (format !== 'hex' && format !== 'bin')) { + format = data.startsWith('0x') ? 'hex' : 'bin'; + } + return oldSha3(data, { encoding: format }); + }; + } + + { + let Registry = web3.eth.contract([{ 'constant': false, 'inputs': [{ 'name': '_new', 'type': 'address' }], 'name': 'setOwner', 'outputs': [], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'string' }], 'name': 'confirmReverse', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }], 'name': 'reserve', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_key', 'type': 'string' }, { 'name': '_value', 'type': 'bytes32' }], 'name': 'set', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }], 'name': 'drop', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_key', 'type': 'string' }], 'name': 'getAddress', 'outputs': [{ 'name': '', 'type': 'address' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_amount', 'type': 'uint256' }], 'name': 'setFee', 'outputs': [], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_to', 'type': 'address' }], 'name': 'transfer', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': true, 'inputs': [], 'name': 'owner', 'outputs': [{ 'name': '', 'type': 'address' }], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }], 'name': 'reserved', 'outputs': [{ 'name': 'reserved', 'type': 'bool' }], 'type': 'function' }, { 'constant': false, 'inputs': [], 'name': 'drain', 'outputs': [], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'string' }, { 'name': '_who', 'type': 'address' }], 'name': 'proposeReverse', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_key', 'type': 'string' }], 'name': 'getUint', 'outputs': [{ 'name': '', 'type': 'uint256' }], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_key', 'type': 'string' }], 'name': 'get', 'outputs': [{ 'name': '', 'type': 'bytes32' }], 'type': 'function' }, { 'constant': true, 'inputs': [], 'name': 'fee', 'outputs': [{ 'name': '', 'type': 'uint256' }], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '', 'type': 'address' }], 'name': 'reverse', 'outputs': [{ 'name': '', 'type': 'string' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_key', 'type': 'string' }, { 'name': '_value', 'type': 'uint256' }], 'name': 'setUint', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'constant': false, 'inputs': [], 'name': 'removeReverse', 'outputs': [], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_name', 'type': 'bytes32' }, { 'name': '_key', 'type': 'string' }, { 'name': '_value', 'type': 'address' }], 'name': 'setAddress', 'outputs': [{ 'name': 'success', 'type': 'bool' }], 'type': 'function' }, { 'anonymous': false, 'inputs': [{ 'indexed': false, 'name': 'amount', 'type': 'uint256' }], 'name': 'Drained', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': false, 'name': 'amount', 'type': 'uint256' }], 'name': 'FeeChanged', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'bytes32' }, { 'indexed': true, 'name': 'owner', 'type': 'address' }], 'name': 'Reserved', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'bytes32' }, { 'indexed': true, 'name': 'oldOwner', 'type': 'address' }, { 'indexed': true, 'name': 'newOwner', 'type': 'address' }], 'name': 'Transferred', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'bytes32' }, { 'indexed': true, 'name': 'owner', 'type': 'address' }], 'name': 'Dropped', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'bytes32' }, { 'indexed': true, 'name': 'owner', 'type': 'address' }, { 'indexed': true, 'name': 'key', 'type': 'string' }, { 'indexed': false, 'name': 'plainKey', 'type': 'string' }], 'name': 'DataChanged', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'string' }, { 'indexed': true, 'name': 'reverse', 'type': 'address' }], 'name': 'ReverseProposed', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'string' }, { 'indexed': true, 'name': 'reverse', 'type': 'address' }], 'name': 'ReverseConfirmed', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'name', 'type': 'string' }, { 'indexed': true, 'name': 'reverse', 'type': 'address' }], 'name': 'ReverseRemoved', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'old', 'type': 'address' }, { 'indexed': true, 'name': 'current', 'type': 'address' }], 'name': 'NewOwner', 'type': 'event' }]); + + web3.eth.registry = Registry.at(web3.eth.registryAddress()); + web3.eth.registry.lookup = (name, field) => web3.eth.registry.get(web3.sha3(name), field); + web3.eth.registry.lookupAddress = (name, field) => web3.eth.registry.getAddress(web3.sha3(name), field); + web3.eth.registry.lookupUint = (name, field) => web3.eth.registry.getUint(web3.sha3(name), field); + + let TokenReg = web3.eth.contract([{ 'constant': true, 'inputs': [{ 'name': '_id', 'type': 'uint256' }], 'name': 'token', 'outputs': [{ 'name': 'addr', 'type': 'address' }, { 'name': 'tla', 'type': 'string' }, { 'name': 'base', 'type': 'uint256' }, { 'name': 'name', 'type': 'string' }, { 'name': 'owner', 'type': 'address' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_new', 'type': 'address' }], 'name': 'setOwner', 'outputs': [], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_addr', 'type': 'address' }, { 'name': '_tla', 'type': 'string' }, { 'name': '_base', 'type': 'uint256' }, { 'name': '_name', 'type': 'string' }], 'name': 'register', 'outputs': [{ 'name': '', 'type': 'bool' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_fee', 'type': 'uint256' }], 'name': 'setFee', 'outputs': [], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_id', 'type': 'uint256' }, { 'name': '_key', 'type': 'bytes32' }], 'name': 'meta', 'outputs': [{ 'name': '', 'type': 'bytes32' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_addr', 'type': 'address' }, { 'name': '_tla', 'type': 'string' }, { 'name': '_base', 'type': 'uint256' }, { 'name': '_name', 'type': 'string' }, { 'name': '_owner', 'type': 'address' }], 'name': 'registerAs', 'outputs': [{ 'name': '', 'type': 'bool' }], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_tla', 'type': 'string' }], 'name': 'fromTLA', 'outputs': [{ 'name': 'id', 'type': 'uint256' }, { 'name': 'addr', 'type': 'address' }, { 'name': 'base', 'type': 'uint256' }, { 'name': 'name', 'type': 'string' }, { 'name': 'owner', 'type': 'address' }], 'type': 'function' }, { 'constant': true, 'inputs': [], 'name': 'owner', 'outputs': [{ 'name': '', 'type': 'address' }], 'type': 'function' }, { 'constant': false, 'inputs': [], 'name': 'drain', 'outputs': [], 'type': 'function' }, { 'constant': true, 'inputs': [], 'name': 'tokenCount', 'outputs': [{ 'name': '', 'type': 'uint256' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_id', 'type': 'uint256' }], 'name': 'unregister', 'outputs': [], 'type': 'function' }, { 'constant': true, 'inputs': [{ 'name': '_addr', 'type': 'address' }], 'name': 'fromAddress', 'outputs': [{ 'name': 'id', 'type': 'uint256' }, { 'name': 'tla', 'type': 'string' }, { 'name': 'base', 'type': 'uint256' }, { 'name': 'name', 'type': 'string' }, { 'name': 'owner', 'type': 'address' }], 'type': 'function' }, { 'constant': false, 'inputs': [{ 'name': '_id', 'type': 'uint256' }, { 'name': '_key', 'type': 'bytes32' }, { 'name': '_value', 'type': 'bytes32' }], 'name': 'setMeta', 'outputs': [], 'type': 'function' }, { 'constant': true, 'inputs': [], 'name': 'fee', 'outputs': [{ 'name': '', 'type': 'uint256' }], 'type': 'function' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'tla', 'type': 'string' }, { 'indexed': true, 'name': 'id', 'type': 'uint256' }, { 'indexed': false, 'name': 'addr', 'type': 'address' }, { 'indexed': false, 'name': 'name', 'type': 'string' }], 'name': 'Registered', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'tla', 'type': 'string' }, { 'indexed': true, 'name': 'id', 'type': 'uint256' }], 'name': 'Unregistered', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'id', 'type': 'uint256' }, { 'indexed': true, 'name': 'key', 'type': 'bytes32' }, { 'indexed': false, 'name': 'value', 'type': 'bytes32' }], 'name': 'MetaChanged', 'type': 'event' }, { 'anonymous': false, 'inputs': [{ 'indexed': true, 'name': 'old', 'type': 'address' }, { 'indexed': true, 'name': 'current', 'type': 'address' }], 'name': 'NewOwner', 'type': 'event' }]); + + web3.eth.tokenReg = TokenReg.at(web3.eth.registry.lookupAddress('tokenreg', 'A')); + } } -web3.eth.installInterceptor = function(interceptor) { - var oldSendTransaction = web3.eth.sendTransaction.bind(web3.eth); - web3.eth.sendTransaction = function(options, f) { - if (interceptor(options) == false) - return "0x0000000000000000000000000000000000000000000000000000000000000000"; - return oldSendTransaction(options, f); - }; -} - -web3.eth.reporter = function(e, r) { - if (e) { - console.log("Error confirming transaction: " + e); - } else { - var addr = r; - var confirmed = false; - var timer_id = window.setInterval(check, 500); - function check() { - var receipt = web3.eth.getTransactionReceipt(addr); - if (receipt != null) { - if (!confirmed) { - console.log("Transaction confirmed (" + r + "); used " + receipt.gasUsed + " gas; left " + receipt.logs.length + " logs; mining..."); - confirmed = true; - } - if (typeof receipt.blockHash == 'string') { - clearInterval(timer_id); - console.log("Mined into block " + receipt.blockNumber); - } - } - } - } -} - -{ - var oldSha3 = web3.sha3 - web3.sha3 = function(data, format) { - if (typeof format !== 'string' || (format != 'hex' && format != 'bin')) - format = data.startsWith('0x') ? 'hex' : 'bin'; - return oldSha3(data, {encoding: format}); - } -} - -{ - var Registry = web3.eth.contract([{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"confirmReverse","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"bytes32"}],"name":"set","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"drop","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"setFee","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_to","type":"address"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserved","outputs":[{"name":"reserved","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_who","type":"address"}],"name":"proposeReverse","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"reverse","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"uint256"}],"name":"setUint","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"removeReverse","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"address"}],"name":"setAddress","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Drained","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"}],"name":"Reserved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"oldOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"Transferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"}],"name":"Dropped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"key","type":"string"},{"indexed":false,"name":"plainKey","type":"string"}],"name":"DataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":true,"name":"reverse","type":"address"}],"name":"ReverseProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":true,"name":"reverse","type":"address"}],"name":"ReverseConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":true,"name":"reverse","type":"address"}],"name":"ReverseRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]); - web3.eth.registry = Registry.at(web3.eth.registryAddress()); - web3.eth.registry.lookup = (name, field) => web3.eth.registry.get(web3.sha3(name), field); - web3.eth.registry.lookupAddress = (name, field) => web3.eth.registry.getAddress(web3.sha3(name), field); - web3.eth.registry.lookupUint = (name, field) => web3.eth.registry.getUint(web3.sha3(name), field); - - var TokenReg = web3.eth.contract([{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"token","outputs":[{"name":"addr","type":"address"},{"name":"tla","type":"string"},{"name":"base","type":"uint256"},{"name":"name","type":"string"},{"name":"owner","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_tla","type":"string"},{"name":"_base","type":"uint256"},{"name":"_name","type":"string"}],"name":"register","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"}],"name":"meta","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_tla","type":"string"},{"name":"_base","type":"uint256"},{"name":"_name","type":"string"},{"name":"_owner","type":"address"}],"name":"registerAs","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_tla","type":"string"}],"name":"fromTLA","outputs":[{"name":"id","type":"uint256"},{"name":"addr","type":"address"},{"name":"base","type":"uint256"},{"name":"name","type":"string"},{"name":"owner","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"tokenCount","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"}],"name":"unregister","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"fromAddress","outputs":[{"name":"id","type":"uint256"},{"name":"tla","type":"string"},{"name":"base","type":"uint256"},{"name":"name","type":"string"},{"name":"owner","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_key","type":"bytes32"},{"name":"_value","type":"bytes32"}],"name":"setMeta","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tla","type":"string"},{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"addr","type":"address"},{"indexed":false,"name":"name","type":"string"}],"name":"Registered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tla","type":"string"},{"indexed":true,"name":"id","type":"uint256"}],"name":"Unregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":true,"name":"key","type":"bytes32"},{"indexed":false,"name":"value","type":"bytes32"}],"name":"MetaChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}]); - web3.eth.tokenReg = TokenReg.at(web3.eth.registry.lookupAddress('tokenreg', 'A')); -} - -/* eslint-enable */ diff --git a/js/src/util/web3.extensions.js b/js/src/util/web3.extensions.js index 461b9b813..f7ee78a6d 100644 --- a/js/src/util/web3.extensions.js +++ b/js/src/util/web3.extensions.js @@ -14,54 +14,35 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +import parity from '~/jsonrpc/interfaces/parity'; +import signer from '~/jsonrpc/interfaces/signer'; +import trace from '~/jsonrpc/interfaces/trace'; + export default function web3extensions (web3) { - const { Method, formatters } = web3._extend; + const { Method } = web3._extend; + + // TODO [ToDr] Consider output/input formatters. + const methods = (object, name) => { + return Object.keys(object).map(method => { + return new Method({ + name: method, + call: `${name}_{method}`, + params: object[method].params.length + }); + }); + }; return [{ - property: 'personal', - methods: [ - new Method({ - name: 'sendTransaction', - call: 'personal_sendTransaction', - params: 2, - inputFormatter: [formatters.inputTransactionFormatter, null] - }), - new Method({ - name: 'signerEnabled', - call: 'personal_signerEnabled', - params: 0, - inputFormatter: [] - }) - ], + property: 'parity', + methods: methods(parity, 'parity'), properties: [] }, { - property: 'ethcore', - methods: [ - new Method({ - name: 'getNetPeers', - call: 'ethcore_netPeers', - params: 0, - outputFormatter: x => x - }), - new Method({ - name: 'getNetChain', - call: 'ethcore_netChain', - params: 0, - outputFormatter: x => x - }), - new Method({ - name: 'gasPriceStatistics', - call: 'ethcore_gasPriceStatistics', - params: 0, - outputFormatter: a => a.map(web3.toBigNumber) - }), - new Method({ - name: 'unsignedTransactionsCount', - call: 'ethcore_unsignedTransactionsCount', - params: 0, - inputFormatter: [] - }) - ], + property: 'signer', + methods: methods(signer, 'signer'), + properties: [] + }, { + property: 'trace', + methods: methods(trace, 'trace'), properties: [] }]; } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index a877879e7..2d8c574af 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -117,4 +117,9 @@ impl Personal for PersonalClient where C: MiningBl dispatch::SignWith::Password(password) ).map(|v| v.into_value().into()) } + + fn sign_and_send_transaction(&self, request: TransactionRequest, password: String) -> Result { + warn!("Using deprecated personal_signAndSendTransaction, use personal_sendTransaction instead."); + self.send_transaction(request, password) + } } diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index cc8372004..6c7daf89f 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -112,16 +112,25 @@ fn sign_and_send_transaction_with_invalid_password() { assert_eq!(tester.io.handle_request_sync(request.as_ref()), Some(response.into())); } +#[test] +fn send_transaction() { + sign_and_send_test("personal_sendTransaction"); +} + #[test] fn sign_and_send_transaction() { + sign_and_send_test("personal_signAndSendTransaction"); +} + +fn sign_and_send_test(method: &str) { let tester = setup(); let address = tester.accounts.new_account("password123").unwrap(); let request = r#"{ "jsonrpc": "2.0", - "method": "personal_sendTransaction", + "method": ""#.to_owned() + method + r#"", "params": [{ - "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"", + "from": ""# + format!("0x{:?}", address).as_ref() + r#"", "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", "gas": "0x76c0", "gasPrice": "0x9184e72a000", diff --git a/rpc/src/v1/traits/personal.rs b/rpc/src/v1/traits/personal.rs index ca9871f57..337a7e939 100644 --- a/rpc/src/v1/traits/personal.rs +++ b/rpc/src/v1/traits/personal.rs @@ -38,5 +38,9 @@ build_rpc_trait! { /// Sends transaction and signs it in single call. The account is not unlocked in such case. #[rpc(name = "personal_sendTransaction")] fn send_transaction(&self, TransactionRequest, String) -> Result; + + /// Deprecated alias for `personal_sendTransaction`. + #[rpc(name = "personal_signAndSendTransaction")] + fn sign_and_send_transaction(&self, TransactionRequest, String) -> Result; } }