161 changed files with 7438 additions and 3379 deletions
@ -0,0 +1,40 @@ |
|||||
|
|
||||
|
#include "Instruction.h" |
||||
|
#include <llvm/ADT/APInt.h> |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace eth |
||||
|
{ |
||||
|
namespace jit |
||||
|
{ |
||||
|
|
||||
|
llvm::APInt readPushData(bytes::const_iterator& _curr, bytes::const_iterator _end) |
||||
|
{ |
||||
|
auto pushInst = *_curr; |
||||
|
assert(Instruction(pushInst) >= Instruction::PUSH1 && Instruction(pushInst) <= Instruction::PUSH32); |
||||
|
auto numBytes = pushInst - static_cast<size_t>(Instruction::PUSH1) + 1; |
||||
|
llvm::APInt value(256, 0); |
||||
|
++_curr; // Point the data
|
||||
|
for (decltype(numBytes) i = 0; i < numBytes; ++i) |
||||
|
{ |
||||
|
byte b = (_curr != _end) ? *_curr++ : 0; |
||||
|
value <<= 8; |
||||
|
value |= b; |
||||
|
} |
||||
|
--_curr; // Point the last real byte read
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
void skipPushData(bytes::const_iterator& _curr, bytes::const_iterator _end) |
||||
|
{ |
||||
|
auto pushInst = *_curr; |
||||
|
assert(Instruction(pushInst) >= Instruction::PUSH1 && Instruction(pushInst) <= Instruction::PUSH32); |
||||
|
auto numBytes = pushInst - static_cast<size_t>(Instruction::PUSH1) + 1; |
||||
|
--_end; |
||||
|
for (decltype(numBytes) i = 0; i < numBytes && _curr < _end; ++i, ++_curr) {} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
cd ethereumjs |
||||
|
export PATH=$PATH:$1:$2 |
||||
|
npm install |
||||
|
npm run-script build |
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +0,0 @@ |
|||||
var web3 = require('./lib/main'); |
|
||||
web3.providers.QtProvider = require('./lib/qt'); |
|
||||
web3.contract = require('./lib/contract'); |
|
||||
|
|
||||
module.exports = web3; |
|
@ -0,0 +1,37 @@ |
|||||
|
var assert = require('assert'); |
||||
|
var abi = require('../lib/abi.js'); |
||||
|
|
||||
|
describe('abi', function() { |
||||
|
describe('inputParser', function() { |
||||
|
it('should parse ...', function() { |
||||
|
|
||||
|
var desc = [{ |
||||
|
"name": "multiply", |
||||
|
"inputs": [ |
||||
|
{ |
||||
|
"name": "a", |
||||
|
"type": "uint256" |
||||
|
} |
||||
|
], |
||||
|
"outputs": [ |
||||
|
{ |
||||
|
"name": "d", |
||||
|
"type": "uint256" |
||||
|
} |
||||
|
] |
||||
|
}]; |
||||
|
|
||||
|
var iParser = abi.inputParser(desc); |
||||
|
assert.equal(iParser.multiply(1), "0x000000000000000000000000000000000000000000000000000000000000000001"); |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
describe('outputParser', function() { |
||||
|
it('parse ...', function() { |
||||
|
|
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
@ -0,0 +1,18 @@ |
|||||
|
require('es6-promise').polyfill(); |
||||
|
|
||||
|
var assert = require('assert'); |
||||
|
var web3 = require('../index.js'); |
||||
|
var u = require('./utils.js'); |
||||
|
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
|
||||
|
|
||||
|
describe('web3', function() { |
||||
|
describe('db', function() { |
||||
|
it('should have all methods implemented', function() { |
||||
|
u.methodExists(web3.db, 'put'); |
||||
|
u.methodExists(web3.db, 'get'); |
||||
|
u.methodExists(web3.db, 'putString'); |
||||
|
u.methodExists(web3.db, 'getString'); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
@ -0,0 +1,42 @@ |
|||||
|
require('es6-promise').polyfill(); |
||||
|
|
||||
|
var assert = require('assert'); |
||||
|
var web3 = require('../index.js'); |
||||
|
var u = require('./utils.js'); |
||||
|
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
|
||||
|
|
||||
|
describe('web3', function() { |
||||
|
describe('eth', function() { |
||||
|
it('should have all methods implemented', function() { |
||||
|
u.methodExists(web3.eth, 'balanceAt'); |
||||
|
u.methodExists(web3.eth, 'stateAt'); |
||||
|
u.methodExists(web3.eth, 'storageAt'); |
||||
|
u.methodExists(web3.eth, 'countAt'); |
||||
|
u.methodExists(web3.eth, 'codeAt'); |
||||
|
u.methodExists(web3.eth, 'transact'); |
||||
|
u.methodExists(web3.eth, 'call'); |
||||
|
u.methodExists(web3.eth, 'block'); |
||||
|
u.methodExists(web3.eth, 'transaction'); |
||||
|
u.methodExists(web3.eth, 'uncle'); |
||||
|
u.methodExists(web3.eth, 'compilers'); |
||||
|
u.methodExists(web3.eth, 'lll'); |
||||
|
u.methodExists(web3.eth, 'solidity'); |
||||
|
u.methodExists(web3.eth, 'serpent'); |
||||
|
u.methodExists(web3.eth, 'logs'); |
||||
|
}); |
||||
|
|
||||
|
it('should have all properties implemented', function () { |
||||
|
u.propertyExists(web3.eth, 'coinbase'); |
||||
|
u.propertyExists(web3.eth, 'listening'); |
||||
|
u.propertyExists(web3.eth, 'mining'); |
||||
|
u.propertyExists(web3.eth, 'gasPrice'); |
||||
|
u.propertyExists(web3.eth, 'account'); |
||||
|
u.propertyExists(web3.eth, 'accounts'); |
||||
|
u.propertyExists(web3.eth, 'peerCount'); |
||||
|
u.propertyExists(web3.eth, 'defaultBlock'); |
||||
|
u.propertyExists(web3.eth, 'number'); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
|
@ -0,0 +1,2 @@ |
|||||
|
--reporter Spec |
||||
|
|
@ -0,0 +1,19 @@ |
|||||
|
require('es6-promise').polyfill(); |
||||
|
|
||||
|
var assert = require('assert'); |
||||
|
var web3 = require('../index.js'); |
||||
|
var u = require('./utils.js'); |
||||
|
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
|
||||
|
|
||||
|
describe('web3', function() { |
||||
|
describe('shh', function() { |
||||
|
it('should have all methods implemented', function() { |
||||
|
u.methodExists(web3.shh, 'post'); |
||||
|
u.methodExists(web3.shh, 'newIdentity'); |
||||
|
u.methodExists(web3.shh, 'haveIdentity'); |
||||
|
u.methodExists(web3.shh, 'newGroup'); |
||||
|
u.methodExists(web3.shh, 'addToGroup'); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
@ -0,0 +1,15 @@ |
|||||
|
var assert = require('assert'); |
||||
|
|
||||
|
var methodExists = function (object, method) { |
||||
|
assert.equal('function', typeof object[method], 'method ' + method + ' is not implemented'); |
||||
|
}; |
||||
|
|
||||
|
var propertyExists = function (object, property) { |
||||
|
assert.equal('object', typeof object[property], 'property ' + property + ' is not implemented'); |
||||
|
}; |
||||
|
|
||||
|
module.exports = { |
||||
|
methodExists: methodExists, |
||||
|
propertyExists: propertyExists |
||||
|
}; |
||||
|
|
@ -0,0 +1,18 @@ |
|||||
|
require('es6-promise').polyfill(); |
||||
|
|
||||
|
var assert = require('assert'); |
||||
|
var web3 = require('../index.js'); |
||||
|
var u = require('./utils.js'); |
||||
|
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
|
||||
|
|
||||
|
describe('web3', function() { |
||||
|
it('should have all methods implemented', function() { |
||||
|
u.methodExists(web3, 'sha3'); |
||||
|
u.methodExists(web3, 'toAscii'); |
||||
|
u.methodExists(web3, 'fromAscii'); |
||||
|
u.methodExists(web3, 'toFixed'); |
||||
|
u.methodExists(web3, 'fromFixed'); |
||||
|
u.methodExists(web3, 'offset'); |
||||
|
}); |
||||
|
}); |
||||
|
|
@ -1,7 +1,7 @@ |
|||||
<RCC version="1.0"> |
<RCC> |
||||
<qresource prefix="/js"> |
<qresource prefix="/js"> |
||||
<file>es6-promise-2.0.0.js</file> |
<file>es6-promise-2.0.0.js</file> |
||||
<file>setup.js</file> |
<file>setup.js</file> |
||||
<file alias="ethereum.js">ethereumjs/dist/ethereum.js</file> |
<file alias="webthree.js">ethereumjs/dist/ethereum.js</file> |
||||
</qresource> |
</qresource> |
||||
</RCC> |
</RCC> |
||||
|
@ -0,0 +1,665 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file WebThreeStubServerBase.cpp
|
||||
|
* @authors: |
||||
|
* Gav Wood <i@gavwood.com> |
||||
|
* Marek Kotewicz <marek@ethdev.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include <libsolidity/CompilerStack.h> |
||||
|
#include <libsolidity/Scanner.h> |
||||
|
#include <libsolidity/SourceReferenceFormatter.h> |
||||
|
#include <libevmcore/Instruction.h> |
||||
|
#include <liblll/Compiler.h> |
||||
|
#include <libethereum/Client.h> |
||||
|
#include <libwebthree/WebThree.h> |
||||
|
#include <libdevcore/CommonJS.h> |
||||
|
#include <libwhisper/Message.h> |
||||
|
#include <libwhisper/WhisperHost.h> |
||||
|
#include <libserpent/funcs.h> |
||||
|
#include "WebThreeStubServerBase.h" |
||||
|
|
||||
|
using namespace std; |
||||
|
using namespace dev; |
||||
|
using namespace dev::eth; |
||||
|
|
||||
|
static Json::Value toJson(dev::eth::BlockInfo const& _bi) |
||||
|
{ |
||||
|
Json::Value res; |
||||
|
res["hash"] = boost::lexical_cast<string>(_bi.hash); |
||||
|
res["parentHash"] = toJS(_bi.parentHash); |
||||
|
res["sha3Uncles"] = toJS(_bi.sha3Uncles); |
||||
|
res["miner"] = toJS(_bi.coinbaseAddress); |
||||
|
res["stateRoot"] = toJS(_bi.stateRoot); |
||||
|
res["transactionsRoot"] = toJS(_bi.transactionsRoot); |
||||
|
res["difficulty"] = toJS(_bi.difficulty); |
||||
|
res["number"] = (int)_bi.number; |
||||
|
res["gasLimit"] = (int)_bi.gasLimit; |
||||
|
res["timestamp"] = (int)_bi.timestamp; |
||||
|
res["extraData"] = jsFromBinary(_bi.extraData); |
||||
|
res["nonce"] = toJS(_bi.nonce); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
static Json::Value toJson(dev::eth::Transaction const& _t) |
||||
|
{ |
||||
|
Json::Value res; |
||||
|
res["hash"] = toJS(_t.sha3()); |
||||
|
res["input"] = jsFromBinary(_t.data()); |
||||
|
res["to"] = toJS(_t.receiveAddress()); |
||||
|
res["from"] = toJS(_t.sender()); |
||||
|
res["gas"] = (int)_t.gas(); |
||||
|
res["gasPrice"] = toJS(_t.gasPrice()); |
||||
|
res["nonce"] = toJS(_t.nonce()); |
||||
|
res["value"] = toJS(_t.value()); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
static Json::Value toJson(dev::eth::LocalisedLogEntry const& _e) |
||||
|
{ |
||||
|
Json::Value res; |
||||
|
|
||||
|
res["data"] = jsFromBinary(_e.data); |
||||
|
res["address"] = toJS(_e.address); |
||||
|
for (auto const& t: _e.topics) |
||||
|
res["topics"].append(toJS(t)); |
||||
|
res["number"] = _e.number; |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
static Json::Value toJson(dev::eth::LocalisedLogEntries const& _es) // commented to avoid warning. Uncomment once in use @ poC-7.
|
||||
|
{ |
||||
|
Json::Value res; |
||||
|
for (dev::eth::LocalisedLogEntry const& e: _es) |
||||
|
res.append(toJson(e)); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
static Json::Value toJson(std::map<u256, u256> const& _storage) |
||||
|
{ |
||||
|
Json::Value res(Json::objectValue); |
||||
|
for (auto i: _storage) |
||||
|
res[toJS(i.first)] = toJS(i.second); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
static dev::eth::LogFilter toLogFilter(Json::Value const& _json) // commented to avoid warning. Uncomment once in use @ PoC-7.
|
||||
|
{ |
||||
|
dev::eth::LogFilter filter; |
||||
|
if (!_json.isObject() || _json.empty()) |
||||
|
return filter; |
||||
|
|
||||
|
if (_json["earliest"].isInt()) |
||||
|
filter.withEarliest(_json["earliest"].asInt()); |
||||
|
if (_json["latest"].isInt()) |
||||
|
filter.withLatest(_json["lastest"].asInt()); |
||||
|
if (_json["max"].isInt()) |
||||
|
filter.withMax(_json["max"].asInt()); |
||||
|
if (_json["skip"].isInt()) |
||||
|
filter.withSkip(_json["skip"].asInt()); |
||||
|
if (!_json["address"].empty()) |
||||
|
{ |
||||
|
if (_json["address"].isArray()) |
||||
|
{ |
||||
|
for (auto i : _json["address"]) |
||||
|
if (i.isString()) |
||||
|
filter.address(jsToAddress(i.asString())); |
||||
|
} |
||||
|
else if (_json["address"].isString()) |
||||
|
filter.address(jsToAddress(_json["address"].asString())); |
||||
|
} |
||||
|
if (!_json["topics"].empty()) |
||||
|
{ |
||||
|
if (_json["topics"].isArray()) |
||||
|
{ |
||||
|
for (auto i: _json["topics"]) |
||||
|
if (i.isString()) |
||||
|
filter.topic(jsToU256(i.asString())); |
||||
|
} |
||||
|
else if(_json["topics"].isString()) |
||||
|
filter.topic(jsToU256(_json["topics"].asString())); |
||||
|
} |
||||
|
return filter; |
||||
|
} |
||||
|
|
||||
|
static shh::Message toMessage(Json::Value const& _json) |
||||
|
{ |
||||
|
shh::Message ret; |
||||
|
if (_json["from"].isString()) |
||||
|
ret.setFrom(jsToPublic(_json["from"].asString())); |
||||
|
if (_json["to"].isString()) |
||||
|
ret.setTo(jsToPublic(_json["to"].asString())); |
||||
|
if (_json["payload"].isString()) |
||||
|
ret.setPayload(jsToBytes(_json["payload"].asString())); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
static shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, Secret _from) |
||||
|
{ |
||||
|
unsigned ttl = 50; |
||||
|
unsigned workToProve = 50; |
||||
|
shh::BuildTopic bt; |
||||
|
|
||||
|
if (_json["ttl"].isInt()) |
||||
|
ttl = _json["ttl"].asInt(); |
||||
|
if (_json["workToProve"].isInt()) |
||||
|
workToProve = _json["workToProve"].asInt(); |
||||
|
if (!_json["topic"].empty()) |
||||
|
{ |
||||
|
if (_json["topic"].isString()) |
||||
|
bt.shift(jsToBytes(_json["topic"].asString())); |
||||
|
else if (_json["topic"].isArray()) |
||||
|
for (auto i: _json["topic"]) |
||||
|
if (i.isString()) |
||||
|
bt.shift(jsToBytes(i.asString())); |
||||
|
} |
||||
|
return _m.seal(_from, bt, ttl, workToProve); |
||||
|
} |
||||
|
|
||||
|
static pair<shh::TopicMask, Public> toWatch(Json::Value const& _json) |
||||
|
{ |
||||
|
shh::BuildTopicMask bt; |
||||
|
Public to; |
||||
|
|
||||
|
if (_json["to"].isString()) |
||||
|
to = jsToPublic(_json["to"].asString()); |
||||
|
|
||||
|
if (!_json["topic"].empty()) |
||||
|
{ |
||||
|
if (_json["topic"].isString()) |
||||
|
bt.shift(jsToBytes(_json["topic"].asString())); |
||||
|
else if (_json["topic"].isArray()) |
||||
|
for (auto i: _json["topic"]) |
||||
|
if (i.isString()) |
||||
|
bt.shift(jsToBytes(i.asString())); |
||||
|
} |
||||
|
return make_pair(bt.toTopicMask(), to); |
||||
|
} |
||||
|
|
||||
|
static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message const& _m) |
||||
|
{ |
||||
|
Json::Value res; |
||||
|
res["hash"] = toJS(_h); |
||||
|
res["expiry"] = (int)_e.expiry(); |
||||
|
res["sent"] = (int)_e.sent(); |
||||
|
res["ttl"] = (int)_e.ttl(); |
||||
|
res["workProved"] = (int)_e.workProved(); |
||||
|
for (auto const& t: _e.topics()) |
||||
|
res["topics"].append(toJS(t)); |
||||
|
res["payload"] = toJS(_m.payload()); |
||||
|
res["from"] = toJS(_m.from()); |
||||
|
res["to"] = toJS(_m.to()); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
WebThreeStubServerBase::WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts): |
||||
|
AbstractWebThreeStubServer(_conn) |
||||
|
{ |
||||
|
setAccounts(_accounts); |
||||
|
} |
||||
|
|
||||
|
void WebThreeStubServerBase::setAccounts(std::vector<dev::KeyPair> const& _accounts) |
||||
|
{ |
||||
|
m_accounts.clear(); |
||||
|
for (auto i: _accounts) |
||||
|
m_accounts[i.address()] = i.secret(); |
||||
|
} |
||||
|
|
||||
|
void WebThreeStubServerBase::setIdentities(std::vector<dev::KeyPair> const& _ids) |
||||
|
{ |
||||
|
m_ids.clear(); |
||||
|
for (auto i: _ids) |
||||
|
m_ids[i.pub()] = i.secret(); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::web3_sha3(std::string const& _param1) |
||||
|
{ |
||||
|
return toJS(sha3(jsToBytes(_param1))); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_accounts() |
||||
|
{ |
||||
|
Json::Value ret(Json::arrayValue); |
||||
|
for (auto i: m_accounts) |
||||
|
ret.append(toJS(i.first)); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::shh_addToGroup(std::string const& _group, std::string const& _who) |
||||
|
{ |
||||
|
(void)_group; |
||||
|
(void)_who; |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_balanceAt(string const& _address) |
||||
|
{ |
||||
|
return toJS(client()->balanceAt(jsToAddress(_address), client()->getDefault())); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_blockByHash(std::string const& _hash) |
||||
|
{ |
||||
|
return toJson(client()->blockInfo(jsToFixed<32>(_hash))); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_blockByNumber(int const& _number) |
||||
|
{ |
||||
|
return toJson(client()->blockInfo(client()->hashFromNumber(_number))); |
||||
|
} |
||||
|
|
||||
|
static TransactionSkeleton toTransaction(Json::Value const& _json) |
||||
|
{ |
||||
|
TransactionSkeleton ret; |
||||
|
if (!_json.isObject() || _json.empty()) |
||||
|
return ret; |
||||
|
|
||||
|
if (_json["from"].isString()) |
||||
|
ret.from = jsToAddress(_json["from"].asString()); |
||||
|
if (_json["to"].isString()) |
||||
|
ret.to = jsToAddress(_json["to"].asString()); |
||||
|
if (!_json["value"].empty()) |
||||
|
{ |
||||
|
if (_json["value"].isString()) |
||||
|
ret.value = jsToU256(_json["value"].asString()); |
||||
|
else if (_json["value"].isInt()) |
||||
|
ret.value = u256(_json["value"].asInt()); |
||||
|
} |
||||
|
if (!_json["gas"].empty()) |
||||
|
{ |
||||
|
if (_json["gas"].isString()) |
||||
|
ret.gas = jsToU256(_json["gas"].asString()); |
||||
|
else if (_json["gas"].isInt()) |
||||
|
ret.gas = u256(_json["gas"].asInt()); |
||||
|
} |
||||
|
if (!_json["gasPrice"].empty()) |
||||
|
{ |
||||
|
if (_json["gasPrice"].isString()) |
||||
|
ret.gasPrice = jsToU256(_json["gasPrice"].asString()); |
||||
|
else if (_json["gasPrice"].isInt()) |
||||
|
ret.gas = u256(_json["gas"].asInt()); |
||||
|
} |
||||
|
if (!_json["data"].empty()) |
||||
|
{ |
||||
|
if (_json["data"].isString()) // ethereum.js has preconstructed the data array
|
||||
|
ret.data = jsToBytes(_json["data"].asString()); |
||||
|
else if (_json["data"].isArray()) // old style: array of 32-byte-padded values. TODO: remove PoC-8
|
||||
|
for (auto i: _json["data"]) |
||||
|
dev::operator +=(ret.data, padded(jsToBytes(i.asString()), 32)); |
||||
|
} |
||||
|
|
||||
|
if (_json["code"].isString()) |
||||
|
ret.data = jsToBytes(_json["code"].asString()); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_call(Json::Value const& _json) |
||||
|
{ |
||||
|
std::string ret; |
||||
|
TransactionSkeleton t = toTransaction(_json); |
||||
|
if (!t.from && m_accounts.size()) |
||||
|
{ |
||||
|
auto b = m_accounts.begin()->first; |
||||
|
for (auto a: m_accounts) |
||||
|
if (client()->balanceAt(a.first) > client()->balanceAt(b)) |
||||
|
b = a.first; |
||||
|
t.from = b; |
||||
|
} |
||||
|
if (!m_accounts.count(t.from)) |
||||
|
return ret; |
||||
|
if (!t.gasPrice) |
||||
|
t.gasPrice = 10 * dev::eth::szabo; |
||||
|
if (!t.gas) |
||||
|
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); |
||||
|
ret = toJS(client()->call(m_accounts[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice)); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_changed(int const& _id) |
||||
|
{ |
||||
|
return toJson(client()->checkWatch(_id)); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_codeAt(string const& _address) |
||||
|
{ |
||||
|
return jsFromBinary(client()->codeAt(jsToAddress(_address), client()->getDefault())); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_coinbase() |
||||
|
{ |
||||
|
return toJS(client()->address()); |
||||
|
} |
||||
|
|
||||
|
double WebThreeStubServerBase::eth_countAt(string const& _address) |
||||
|
{ |
||||
|
return (double)(uint64_t)client()->countAt(jsToAddress(_address), client()->getDefault()); |
||||
|
} |
||||
|
|
||||
|
int WebThreeStubServerBase::eth_defaultBlock() |
||||
|
{ |
||||
|
return client()->getDefault(); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_gasPrice() |
||||
|
{ |
||||
|
return toJS(10 * dev::eth::szabo); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::db_get(std::string const& _name, std::string const& _key) |
||||
|
{ |
||||
|
string ret = db()->get(_name, _key); |
||||
|
return toJS(dev::asBytes(ret)); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_filterLogs(int const& _id) |
||||
|
{ |
||||
|
return toJson(client()->logs(_id)); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_logs(Json::Value const& _json) |
||||
|
{ |
||||
|
return toJson(client()->logs(toLogFilter(_json))); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::db_getString(std::string const& _name, std::string const& _key) |
||||
|
{ |
||||
|
return db()->get(_name, _key);; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::shh_haveIdentity(std::string const& _id) |
||||
|
{ |
||||
|
return m_ids.count(jsToPublic(_id)) > 0; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_listening() |
||||
|
{ |
||||
|
return network()->isNetworkStarted(); |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_mining() |
||||
|
{ |
||||
|
return client()->isMining(); |
||||
|
} |
||||
|
|
||||
|
int WebThreeStubServerBase::eth_newFilter(Json::Value const& _json) |
||||
|
{ |
||||
|
unsigned ret = -1; |
||||
|
ret = client()->installWatch(toLogFilter(_json)); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
int WebThreeStubServerBase::eth_newFilterString(std::string const& _filter) |
||||
|
{ |
||||
|
unsigned ret = -1; |
||||
|
if (_filter.compare("chain") == 0) |
||||
|
ret = client()->installWatch(dev::eth::ChainChangedFilter); |
||||
|
else if (_filter.compare("pending") == 0) |
||||
|
ret = client()->installWatch(dev::eth::PendingChangedFilter); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::shh_newGroup(std::string const& _id, std::string const& _who) |
||||
|
{ |
||||
|
(void)_id; |
||||
|
(void)_who; |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::shh_newIdentity() |
||||
|
{ |
||||
|
// cnote << this << m_ids;
|
||||
|
KeyPair kp = KeyPair::create(); |
||||
|
m_ids[kp.pub()] = kp.secret(); |
||||
|
return toJS(kp.pub()); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_compilers() |
||||
|
{ |
||||
|
Json::Value ret(Json::arrayValue); |
||||
|
ret.append("lll"); |
||||
|
ret.append("solidity"); |
||||
|
ret.append("serpent"); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_lll(std::string const& _code) |
||||
|
{ |
||||
|
string res; |
||||
|
vector<string> errors; |
||||
|
res = toJS(dev::eth::compileLLL(_code, true, &errors)); |
||||
|
cwarn << "LLL compilation errors: " << errors; |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_serpent(std::string const& _code) |
||||
|
{ |
||||
|
string res; |
||||
|
try |
||||
|
{ |
||||
|
res = toJS(dev::asBytes(::compile(_code))); |
||||
|
} |
||||
|
catch (string err) |
||||
|
{ |
||||
|
cwarn << "Solidity compilation error: " << err; |
||||
|
} |
||||
|
catch (...) |
||||
|
{ |
||||
|
cwarn << "Uncought serpent compilation exception"; |
||||
|
} |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_solidity(std::string const& _code) |
||||
|
{ |
||||
|
string res; |
||||
|
dev::solidity::CompilerStack compiler; |
||||
|
try |
||||
|
{ |
||||
|
res = toJS(compiler.compile(_code, true)); |
||||
|
} |
||||
|
catch (dev::Exception const& exception) |
||||
|
{ |
||||
|
ostringstream error; |
||||
|
solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); |
||||
|
cwarn << "Solidity compilation error: " << error.str(); |
||||
|
} |
||||
|
catch (...) |
||||
|
{ |
||||
|
cwarn << "Uncought solidity compilation exception"; |
||||
|
} |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
int WebThreeStubServerBase::eth_number() |
||||
|
{ |
||||
|
return client()->number() + 1; |
||||
|
} |
||||
|
|
||||
|
int WebThreeStubServerBase::eth_peerCount() |
||||
|
{ |
||||
|
return network()->peerCount(); |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::shh_post(Json::Value const& _json) |
||||
|
{ |
||||
|
shh::Message m = toMessage(_json); |
||||
|
Secret from; |
||||
|
|
||||
|
if (m.from() && m_ids.count(m.from())) |
||||
|
{ |
||||
|
cwarn << "Silently signing message from identity" << m.from().abridged() << ": User validation hook goes here."; |
||||
|
// TODO: insert validification hook here.
|
||||
|
from = m_ids[m.from()]; |
||||
|
} |
||||
|
|
||||
|
face()->inject(toSealed(_json, m, from)); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::db_put(std::string const& _name, std::string const& _key, std::string const& _value) |
||||
|
{ |
||||
|
string v = asString(jsToBytes(_value)); |
||||
|
db()->put(_name, _key, v); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::db_putString(std::string const& _name, std::string const& _key, std::string const& _value) |
||||
|
{ |
||||
|
db()->put(_name, _key,_value); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_setCoinbase(std::string const& _address) |
||||
|
{ |
||||
|
client()->setAddress(jsToAddress(_address)); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_setDefaultBlock(int const& _block) |
||||
|
{ |
||||
|
client()->setDefault(_block); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_setListening(bool const& _listening) |
||||
|
{ |
||||
|
if (_listening) |
||||
|
network()->startNetwork(); |
||||
|
else |
||||
|
network()->stopNetwork(); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_setMining(bool const& _mining) |
||||
|
{ |
||||
|
if (_mining) |
||||
|
client()->startMining(); |
||||
|
else |
||||
|
client()->stopMining(); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::shh_changed(int const& _id) |
||||
|
{ |
||||
|
Json::Value ret(Json::arrayValue); |
||||
|
auto pub = m_shhWatches[_id]; |
||||
|
if (!pub || m_ids.count(pub)) |
||||
|
for (h256 const& h: face()->checkWatch(_id)) |
||||
|
{ |
||||
|
auto e = face()->envelope(h); |
||||
|
shh::Message m; |
||||
|
if (pub) |
||||
|
{ |
||||
|
cwarn << "Silently decrypting message from identity" << pub.abridged() << ": User validation hook goes here."; |
||||
|
m = e.open(m_ids[pub]); |
||||
|
if (!m) |
||||
|
continue; |
||||
|
} |
||||
|
else |
||||
|
m = e.open(); |
||||
|
ret.append(toJson(h, e, m)); |
||||
|
} |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
int WebThreeStubServerBase::shh_newFilter(Json::Value const& _json) |
||||
|
{ |
||||
|
auto w = toWatch(_json); |
||||
|
auto ret = face()->installWatch(w.first); |
||||
|
m_shhWatches.insert(make_pair(ret, w.second)); |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::shh_uninstallFilter(int const& _id) |
||||
|
{ |
||||
|
face()->uninstallWatch(_id); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_stateAt(string const& _address, string const& _storage) |
||||
|
{ |
||||
|
return toJS(client()->stateAt(jsToAddress(_address), jsToU256(_storage), client()->getDefault())); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_storageAt(string const& _address) |
||||
|
{ |
||||
|
return toJson(client()->storageAt(jsToAddress(_address))); |
||||
|
} |
||||
|
|
||||
|
std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json) |
||||
|
{ |
||||
|
std::string ret; |
||||
|
TransactionSkeleton t = toTransaction(_json); |
||||
|
if (!t.from && m_accounts.size()) |
||||
|
{ |
||||
|
auto b = m_accounts.begin()->first; |
||||
|
for (auto a: m_accounts) |
||||
|
if (client()->balanceAt(a.first) > client()->balanceAt(b)) |
||||
|
b = a.first; |
||||
|
t.from = b; |
||||
|
} |
||||
|
if (!m_accounts.count(t.from)) |
||||
|
return ret; |
||||
|
if (!t.gasPrice) |
||||
|
t.gasPrice = 10 * dev::eth::szabo; |
||||
|
if (!t.gas) |
||||
|
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); |
||||
|
if (authenticate(t)) |
||||
|
{ |
||||
|
if (t.to) |
||||
|
// TODO: from qethereum, insert validification hook here.
|
||||
|
client()->transact(m_accounts[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice); |
||||
|
else |
||||
|
ret = toJS(client()->transact(m_accounts[t.from].secret(), t.value, t.data, t.gas, t.gasPrice)); |
||||
|
client()->flushTransactions(); |
||||
|
} |
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t) const |
||||
|
{ |
||||
|
cwarn << "Silently signing transaction from address" << _t.from.abridged() << ": User validation hook goes here."; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_transactionByHash(std::string const& _hash, int const& _i) |
||||
|
{ |
||||
|
return toJson(client()->transaction(jsToFixed<32>(_hash), _i)); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_transactionByNumber(int const& _number, int const& _i) |
||||
|
{ |
||||
|
return toJson(client()->transaction(client()->hashFromNumber(_number), _i)); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_uncleByHash(std::string const& _hash, int const& _i) |
||||
|
{ |
||||
|
return toJson(client()->uncle(jsToFixed<32>(_hash), _i)); |
||||
|
} |
||||
|
|
||||
|
Json::Value WebThreeStubServerBase::eth_uncleByNumber(int const& _number, int const& _i) |
||||
|
{ |
||||
|
return toJson(client()->uncle(client()->hashFromNumber(_number), _i)); |
||||
|
} |
||||
|
|
||||
|
bool WebThreeStubServerBase::eth_uninstallFilter(int const& _id) |
||||
|
{ |
||||
|
client()->uninstallWatch(_id); |
||||
|
return true; |
||||
|
} |
||||
|
|
@ -0,0 +1,138 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file WebThreeStubServer.h
|
||||
|
* @authors: |
||||
|
* Gav Wood <i@gavwood.com> |
||||
|
* Marek Kotewicz <marek@ethdev.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <iostream> |
||||
|
#include <jsonrpccpp/server.h> |
||||
|
#include <libdevcrypto/Common.h> |
||||
|
#pragma GCC diagnostic push |
||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter" |
||||
|
#include "abstractwebthreestubserver.h" |
||||
|
#pragma GCC diagnostic pop |
||||
|
|
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
class WebThreeNetworkFace; |
||||
|
class KeyPair; |
||||
|
struct TransactionSkeleton; |
||||
|
namespace eth |
||||
|
{ |
||||
|
class Interface; |
||||
|
} |
||||
|
namespace shh |
||||
|
{ |
||||
|
class Interface; |
||||
|
} |
||||
|
|
||||
|
class WebThreeStubDatabaseFace |
||||
|
{ |
||||
|
public: |
||||
|
virtual std::string get(std::string const& _name, std::string const& _key) = 0; |
||||
|
virtual void put(std::string const& _name, std::string const& _key, std::string const& _value) = 0; |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* @brief JSON-RPC api implementation |
||||
|
* @todo filters should work on unsigned instead of int |
||||
|
* unsigned are not supported in json-rpc-cpp and there are bugs with double in json-rpc-cpp version 0.2.1 |
||||
|
* @todo split these up according to subprotocol (eth, shh, db, p2p, web3) and make it /very/ clear about how to add other subprotocols. |
||||
|
* @todo modularise everything so additional subprotocols don't need to change this file. |
||||
|
*/ |
||||
|
class WebThreeStubServerBase: public AbstractWebThreeStubServer |
||||
|
{ |
||||
|
public: |
||||
|
WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts); |
||||
|
|
||||
|
virtual std::string web3_sha3(std::string const& _param1); |
||||
|
virtual Json::Value eth_accounts(); |
||||
|
virtual std::string eth_balanceAt(std::string const& _address); |
||||
|
virtual Json::Value eth_blockByHash(std::string const& _hash); |
||||
|
virtual Json::Value eth_blockByNumber(int const& _number); |
||||
|
virtual std::string eth_call(Json::Value const& _json); |
||||
|
virtual Json::Value eth_changed(int const& _id); |
||||
|
virtual std::string eth_codeAt(std::string const& _address); |
||||
|
virtual std::string eth_coinbase(); |
||||
|
virtual Json::Value eth_compilers(); |
||||
|
virtual double eth_countAt(std::string const& _address); |
||||
|
virtual int eth_defaultBlock(); |
||||
|
virtual std::string eth_gasPrice(); |
||||
|
virtual Json::Value eth_filterLogs(int const& _id); |
||||
|
virtual Json::Value eth_logs(Json::Value const& _json); |
||||
|
virtual bool eth_listening(); |
||||
|
virtual bool eth_mining(); |
||||
|
virtual int eth_newFilter(Json::Value const& _json); |
||||
|
virtual int eth_newFilterString(std::string const& _filter); |
||||
|
virtual int eth_number(); |
||||
|
virtual int eth_peerCount(); |
||||
|
virtual bool eth_setCoinbase(std::string const& _address); |
||||
|
virtual bool eth_setDefaultBlock(int const& _block); |
||||
|
virtual bool eth_setListening(bool const& _listening); |
||||
|
virtual std::string eth_lll(std::string const& _s); |
||||
|
virtual std::string eth_serpent(std::string const& _s); |
||||
|
virtual bool eth_setMining(bool const& _mining); |
||||
|
virtual std::string eth_solidity(std::string const& _code); |
||||
|
virtual std::string eth_stateAt(std::string const& _address, std::string const& _storage); |
||||
|
virtual Json::Value eth_storageAt(std::string const& _address); |
||||
|
virtual std::string eth_transact(Json::Value const& _json); |
||||
|
virtual Json::Value eth_transactionByHash(std::string const& _hash, int const& _i); |
||||
|
virtual Json::Value eth_transactionByNumber(int const& _number, int const& _i); |
||||
|
virtual Json::Value eth_uncleByHash(std::string const& _hash, int const& _i); |
||||
|
virtual Json::Value eth_uncleByNumber(int const& _number, int const& _i); |
||||
|
virtual bool eth_uninstallFilter(int const& _id); |
||||
|
|
||||
|
virtual std::string db_get(std::string const& _name, std::string const& _key); |
||||
|
virtual std::string db_getString(std::string const& _name, std::string const& _key); |
||||
|
virtual bool db_put(std::string const& _name, std::string const& _key, std::string const& _value); |
||||
|
virtual bool db_putString(std::string const& _name, std::string const& _key, std::string const& _value); |
||||
|
|
||||
|
virtual std::string shh_addToGroup(std::string const& _group, std::string const& _who); |
||||
|
virtual Json::Value shh_changed(int const& _id); |
||||
|
virtual bool shh_haveIdentity(std::string const& _id); |
||||
|
virtual int shh_newFilter(Json::Value const& _json); |
||||
|
virtual std::string shh_newGroup(std::string const& _id, std::string const& _who); |
||||
|
virtual std::string shh_newIdentity(); |
||||
|
virtual bool shh_post(Json::Value const& _json); |
||||
|
virtual bool shh_uninstallFilter(int const& _id); |
||||
|
|
||||
|
void setAccounts(std::vector<dev::KeyPair> const& _accounts); |
||||
|
void setIdentities(std::vector<dev::KeyPair> const& _ids); |
||||
|
std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; } |
||||
|
|
||||
|
protected: |
||||
|
virtual bool authenticate(dev::TransactionSkeleton const& _t) const; |
||||
|
|
||||
|
protected: |
||||
|
virtual dev::eth::Interface* client() = 0; |
||||
|
virtual std::shared_ptr<dev::shh::Interface> face() = 0; |
||||
|
virtual dev::WebThreeNetworkFace* network() = 0; |
||||
|
virtual dev::WebThreeStubDatabaseFace* db() = 0; |
||||
|
|
||||
|
std::map<dev::Address, dev::KeyPair> m_accounts; |
||||
|
|
||||
|
std::map<dev::Public, dev::Secret> m_ids; |
||||
|
std::map<unsigned, dev::Public> m_shhWatches; |
||||
|
}; |
||||
|
|
||||
|
} //namespace dev
|
@ -1,119 +0,0 @@ |
|||||
/*
|
|
||||
This file is part of cpp-ethereum. |
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify |
|
||||
it under the terms of the GNU General Public License as published by |
|
||||
the Free Software Foundation, either version 3 of the License, or |
|
||||
(at your option) any later version. |
|
||||
cpp-ethereum is distributed in the hope that it will be useful, |
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
GNU General Public License for more details. |
|
||||
You should have received a copy of the GNU General Public License |
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
||||
*/ |
|
||||
/** @file AssemblyDebuggerModel.cpp
|
|
||||
* @author Yann yann@ethdev.com |
|
||||
* @date 2014 |
|
||||
* used as a model to debug contract assembly code. |
|
||||
*/ |
|
||||
|
|
||||
#include <QApplication> |
|
||||
#include <libdevcore/Common.h> |
|
||||
#include <libevm/VM.h> |
|
||||
#include <libethereum/Executive.h> |
|
||||
#include <libethereum/Transaction.h> |
|
||||
#include <libethereum/ExtVM.h> |
|
||||
#include "AssemblyDebuggerModel.h" |
|
||||
#include "AppContext.h" |
|
||||
#include "DebuggingStateWrapper.h" |
|
||||
|
|
||||
using namespace std; |
|
||||
using namespace dev; |
|
||||
using namespace dev::eth; |
|
||||
|
|
||||
namespace dev |
|
||||
{ |
|
||||
namespace mix |
|
||||
{ |
|
||||
|
|
||||
AssemblyDebuggerModel::AssemblyDebuggerModel(): |
|
||||
m_userAccount(KeyPair::create()) |
|
||||
{ |
|
||||
resetState(10000000 * ether); |
|
||||
} |
|
||||
|
|
||||
DebuggingContent AssemblyDebuggerModel::executeTransaction(bytesConstRef const& _rawTransaction) |
|
||||
{ |
|
||||
QList<DebuggingState> machineStates; |
|
||||
eth::Executive execution(m_executiveState, LastHashes(), 0); |
|
||||
execution.setup(_rawTransaction); |
|
||||
std::vector<DebuggingState const*> levels; |
|
||||
bytes code; |
|
||||
bytesConstRef data; |
|
||||
bool firstIteration = true; |
|
||||
auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, void* voidVM, void const* voidExt) |
|
||||
{ |
|
||||
VM& vm = *(VM*)voidVM; |
|
||||
ExtVM const& ext = *(ExtVM const*)voidExt; |
|
||||
|
|
||||
if (firstIteration) |
|
||||
{ |
|
||||
code = ext.code; |
|
||||
data = ext.data; |
|
||||
firstIteration = false; |
|
||||
} |
|
||||
|
|
||||
if (levels.size() < ext.depth) |
|
||||
levels.push_back(&machineStates.back()); |
|
||||
else |
|
||||
levels.resize(ext.depth); |
|
||||
|
|
||||
machineStates.append(DebuggingState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), |
|
||||
vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); |
|
||||
}; |
|
||||
|
|
||||
execution.go(onOp); |
|
||||
execution.finalize(); |
|
||||
|
|
||||
DebuggingContent d; |
|
||||
d.returnValue = execution.out().toVector(); |
|
||||
d.machineStates = machineStates; |
|
||||
d.executionCode = code; |
|
||||
d.executionData = data; |
|
||||
d.contentAvailable = true; |
|
||||
d.message = "ok"; |
|
||||
return d; |
|
||||
} |
|
||||
|
|
||||
DebuggingContent AssemblyDebuggerModel::deployContract(bytes const& _code) |
|
||||
{ |
|
||||
u256 gasPrice = 10000000000000; |
|
||||
u256 gas = 1000000; |
|
||||
u256 amount = 100; |
|
||||
Transaction _tr(amount, gasPrice, min(gas, m_executiveState.gasLimitRemaining()), _code, m_executiveState.transactionsFrom(dev::toAddress(m_userAccount.secret())), m_userAccount.secret()); |
|
||||
bytes b = _tr.rlp(); |
|
||||
dev::bytesConstRef bytesRef = &b; |
|
||||
DebuggingContent d = executeTransaction(bytesRef); |
|
||||
h256 th = sha3(rlpList(_tr.sender(), _tr.nonce())); |
|
||||
d.contractAddress = right160(th); |
|
||||
return d; |
|
||||
} |
|
||||
|
|
||||
DebuggingContent AssemblyDebuggerModel::callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr) |
|
||||
{ |
|
||||
Transaction tr = Transaction(_tr.value, _tr.gasPrice, min(_tr.gas, m_executiveState.gasLimitRemaining()), _contract, _data, m_executiveState.transactionsFrom(dev::toAddress(m_userAccount.secret())), m_userAccount.secret()); |
|
||||
bytes b = tr.rlp(); |
|
||||
dev::bytesConstRef bytesRef = &b; |
|
||||
DebuggingContent d = executeTransaction(bytesRef); |
|
||||
d.contractAddress = tr.receiveAddress(); |
|
||||
return d; |
|
||||
} |
|
||||
|
|
||||
void AssemblyDebuggerModel::resetState(u256 _balance) |
|
||||
{ |
|
||||
m_executiveState = eth::State(Address(), m_overlayDB, BaseState::Empty); |
|
||||
m_executiveState.addBalance(m_userAccount.address(), _balance); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue