Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into mix_dbg

cl-refactor
arkpar 10 years ago
parent
commit
2a535e0d81
  1. 4
      CMakeLists.txt
  2. 25
      libethereum/Client.cpp
  3. 5
      libethereum/Client.h
  4. 69
      libethereum/EthereumHost.cpp
  5. 8
      libethereum/EthereumHost.h
  6. 175
      libp2p/Session.cpp
  7. 2
      mix/qml.qrc
  8. 2
      mix/qml/Application.qml
  9. 448
      mix/qml/DeploymentDialog.qml
  10. 94
      mix/qml/NewProjectDialog.qml
  11. 564
      mix/qml/StateDialog.qml
  12. 74
      mix/qml/StateList.qml
  13. 379
      mix/qml/TransactionDialog.qml
  14. 1
      mix/qml/WebPreview.qml
  15. 5
      mix/qml/html/WebContainer.html
  16. 90
      mix/qml/js/Printer.js
  17. 106
      mix/qml/js/ansi2html.js
  18. 4
      test/SolidityEndToEndTest.cpp
  19. 940
      test/bcUncleHeaderValiditiyFiller.json
  20. 93
      test/bcUncleTestFiller.json
  21. 36
      test/blockchain.cpp
  22. 83
      test/stCallCreateCallCodeTestFiller.json
  23. 20
      test/ttTransactionTestFiller.json

4
CMakeLists.txt

@ -146,6 +146,10 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
else ()
set(DECENT_PLATFORM ON)
endif ()
# Backwards compatibility
if (HEADLESS)
set(BUNDLE "minimal")
endif ()
if (PARANOIA)
set(PARANOIA ON)

25
libethereum/Client.cpp

@ -505,13 +505,27 @@ void Client::doWork()
bool sgw;
tie(fresh, dead, sgw) = m_bc.sync(m_bq, db, 100);
// TODO: remove transactions from m_tq nicely rather than relying on out of date nonce later on.
// insert transactions that we are declaring the dead part of the chain
for (auto const& h: dead)
{
clog(ClientNote) << "Dead block:" << h.abridged();
for (auto const& t: m_bc.transactions(h))
{
clog(ClientNote) << "Resubmitting transaction " << Transaction(t, CheckSignature::None);
m_tq.import(t);
}
}
// remove transactions from m_tq nicely rather than relying on out of date nonce later on.
for (auto const& h: fresh)
{
clog(ClientChat) << "Mined block:" << h.abridged();
for (auto const& th: m_bc.transactionHashes(h))
{
clog(ClientNote) << "Safely dropping transaction " << th;
m_tq.drop(th);
}
}
stillGotWork = stillGotWork | sgw;
if (!fresh.empty())
@ -535,7 +549,7 @@ void Client::doWork()
// TODO: Move transactions pending from m_postMine back to transaction queue.
}
// returns h256s as blooms, once for each transaction.
// returns TransactionReceipts, once for each transaction.
cwork << "postSTATE <== TQ";
TransactionReceipts newPendingReceipts = m_postMine.sync(m_bc, m_tq, *m_gp);
if (newPendingReceipts.size())
@ -548,8 +562,15 @@ void Client::doWork()
if (isMining())
cnote << "Additional transaction ready: Restarting mining operation.";
resyncStateNeeded = true;
if (auto h = m_host.lock())
h->noteNewTransactions();
}
}
if (!changeds.empty())
if (auto h = m_host.lock())
h->noteNewBlocks();
if (resyncStateNeeded)
{
ReadGuard l(x_localMiners);

5
libethereum/Client.h

@ -114,6 +114,11 @@ private:
std::array<u256, 9> m_octiles;
};
struct ClientNote: public LogChannel { static const char* name() { return "*C*"; } static const int verbosity = 2; };
struct ClientChat: public LogChannel { static const char* name() { return "=C="; } static const int verbosity = 4; };
struct ClientTrace: public LogChannel { static const char* name() { return "-C-"; } static const int verbosity = 7; };
struct ClientDetail: public LogChannel { static const char* name() { return " C "; } static const int verbosity = 14; };
/**
* @brief Main API hub for interfacing with Ethereum.
*/

69
libethereum/EthereumHost.cpp

@ -159,8 +159,16 @@ void EthereumHost::doWork()
// If we've finished our initial sync (including getting all the blocks into the chain so as to reduce invalid transactions), start trading transactions & blocks
if (!isSyncing() && m_chain.isKnown(m_latestBlockSent))
{
maintainTransactions();
maintainBlocks(h);
if (m_newTransactions)
{
m_newTransactions = false;
maintainTransactions();
}
if (m_newBlocks)
{
m_newBlocks = false;
maintainBlocks(h);
}
}
for (auto p: peerSessions())
@ -175,18 +183,27 @@ void EthereumHost::doWork()
void EthereumHost::maintainTransactions()
{
// Send any new transactions.
map<std::shared_ptr<EthereumPeer>, h256s> peerTransactions;
auto ts = m_tq.transactions();
for (auto const& i: ts)
{
bool unsent = !m_transactionsSent.count(i.first);
for (auto const& p: randomSelection(25, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }))
peerTransactions[p].push_back(i.first);
}
for (auto p: peerSessions())
if (auto ep = p.first->cap<EthereumPeer>().get())
if (auto ep = p.first->cap<EthereumPeer>())
{
bytes b;
unsigned n = 0;
for (auto const& i: m_tq.transactions())
if (ep->m_requireTransactions || (!m_transactionsSent.count(i.first) && !ep->m_knownTransactions.count(i.first)))
{
b += i.second.rlp();
++n;
m_transactionsSent.insert(i.first);
}
for (auto const& h: peerTransactions[ep])
{
b += ts[h].rlp();
++n;
}
for (auto const& t: ts)
m_transactionsSent.insert(t.first);
ep->clearKnownTransactions();
if (n || ep->m_requireTransactions)
@ -199,6 +216,27 @@ void EthereumHost::maintainTransactions()
}
}
std::vector<std::shared_ptr<EthereumPeer>> EthereumHost::randomSelection(unsigned _percent, std::function<bool(EthereumPeer*)> const& _allow)
{
std::vector<std::shared_ptr<EthereumPeer>> candidates;
candidates.reserve(peerSessions().size());
for (auto const& j: peerSessions())
{
auto pp = j.first->cap<EthereumPeer>();
if (_allow(pp.get()))
candidates.push_back(pp);
}
std::vector<std::shared_ptr<EthereumPeer>> ret;
for (unsigned i = (peerSessions().size() * _percent + 99) / 100; i-- && candidates.size();)
{
unsigned n = rand() % candidates.size();
ret.push_back(std::move(candidates[n]));
candidates.erase(candidates.begin() + n);
}
return ret;
}
void EthereumHost::maintainBlocks(h256 _currentHash)
{
// Send any new blocks.
@ -206,17 +244,8 @@ void EthereumHost::maintainBlocks(h256 _currentHash)
{
clog(NetMessageSummary) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")";
std::vector<std::shared_ptr<EthereumPeer>> dispersal;
for (auto const& j: peerSessions())
if (!j.first->cap<EthereumPeer>()->m_knownBlocks.count(_currentHash))
dispersal.push_back(j.first->cap<EthereumPeer>());
for (unsigned i = (dispersal.size() + 3) / 4; i--;)
for (auto const& p: randomSelection(25, [&](EthereumPeer* p){return !p->m_knownBlocks.count(_currentHash); }))
{
unsigned n = rand() % dispersal.size();
auto p = std::move(dispersal[n]);
dispersal.erase(dispersal.begin() + n);
RLPStream ts;
p->prep(ts, NewBlockPacket, 2).appendRaw(m_chain.block(), 1).append(m_chain.details().totalDifficulty);

8
libethereum/EthereumHost.h

@ -76,7 +76,12 @@ public:
bool isBanned(p2p::NodeId _id) const { return !!m_banned.count(_id); }
void noteNewTransactions() { m_newTransactions = true; }
void noteNewBlocks() { m_newBlocks = true; }
private:
std::vector<std::shared_ptr<EthereumPeer>> randomSelection(unsigned _percent = 25, std::function<bool(EthereumPeer*)> const& _allow = [](EthereumPeer const*){ return true; });
/// Session is tell us that we may need (re-)syncing with the peer.
void noteNeedsSyncing(EthereumPeer* _who);
@ -119,6 +124,9 @@ private:
h256Set m_transactionsSent;
std::set<p2p::NodeId> m_banned;
bool m_newTransactions = false;
bool m_newBlocks = false;
};
}

175
libp2p/Session.cpp

@ -156,109 +156,104 @@ bool Session::interpret(PacketType _t, RLP const& _r)
clogS(NetRight) << _t << _r;
try // Generic try-catch block designed to capture RLP format errors - TODO: give decent diagnostics, make a bit more specific over what is caught.
{
switch (_t)
{
case DisconnectPacket:
{
string reason = "Unspecified";
auto r = (DisconnectReason)_r[0].toInt<int>();
if (!_r[0].isInt())
drop(BadProtocol);
else
switch (_t)
{
reason = reasonOf(r);
clogS(NetMessageSummary) << "Disconnect (reason: " << reason << ")";
drop(DisconnectRequested);
}
break;
}
case PingPacket:
{
clogS(NetTriviaSummary) << "Ping";
RLPStream s;
sealAndSend(prep(s, PongPacket));
break;
}
case PongPacket:
m_info.lastPing = std::chrono::steady_clock::now() - m_ping;
clogS(NetTriviaSummary) << "Latency: " << chrono::duration_cast<chrono::milliseconds>(m_info.lastPing).count() << " ms";
break;
case GetPeersPacket:
{
// Disabled for interop testing.
// GetPeers/PeersPacket will be modified to only exchange new nodes which it's peers are interested in.
break;
clogS(NetTriviaSummary) << "GetPeers";
m_theyRequestedNodes = true;
serviceNodesRequest();
break;
}
case PeersPacket:
// Disabled for interop testing.
// GetPeers/PeersPacket will be modified to only exchange new nodes which it's peers are interested in.
break;
clogS(NetTriviaSummary) << "Peers (" << dec << (_r.itemCount() - 1) << " entries)";
m_weRequestedNodes = false;
for (unsigned i = 0; i < _r.itemCount(); ++i)
case DisconnectPacket:
{
bi::address peerAddress;
if (_r[i][0].size() == 16)
peerAddress = bi::address_v6(_r[i][0].toHash<FixedHash<16>>().asArray());
else if (_r[i][0].size() == 4)
peerAddress = bi::address_v4(_r[i][0].toHash<FixedHash<4>>().asArray());
string reason = "Unspecified";
auto r = (DisconnectReason)_r[0].toInt<int>();
if (!_r[0].isInt())
drop(BadProtocol);
else
{
cwarn << "Received bad peer packet:" << _r;
disconnect(BadProtocol);
return true;
reason = reasonOf(r);
clogS(NetMessageSummary) << "Disconnect (reason: " << reason << ")";
drop(DisconnectRequested);
}
auto ep = bi::tcp::endpoint(peerAddress, _r[i][1].toInt<short>());
NodeId id = _r[i][2].toHash<NodeId>();
clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")";
break;
}
case PingPacket:
{
clogS(NetTriviaSummary) << "Ping";
RLPStream s;
sealAndSend(prep(s, PongPacket));
break;
}
case PongPacket:
m_info.lastPing = std::chrono::steady_clock::now() - m_ping;
clogS(NetTriviaSummary) << "Latency: " << chrono::duration_cast<chrono::milliseconds>(m_info.lastPing).count() << " ms";
break;
case GetPeersPacket:
// Disabled for interop testing.
// GetPeers/PeersPacket will be modified to only exchange new nodes which it's peers are interested in.
break;
clogS(NetTriviaSummary) << "GetPeers";
m_theyRequestedNodes = true;
serviceNodesRequest();
break;
case PeersPacket:
// Disabled for interop testing.
// GetPeers/PeersPacket will be modified to only exchange new nodes which it's peers are interested in.
break;
clogS(NetTriviaSummary) << "Peers (" << dec << (_r.itemCount() - 1) << " entries)";
m_weRequestedNodes = false;
for (unsigned i = 0; i < _r.itemCount(); ++i)
{
bi::address peerAddress;
if (_r[i][0].size() == 16)
peerAddress = bi::address_v6(_r[i][0].toHash<FixedHash<16>>().asArray());
else if (_r[i][0].size() == 4)
peerAddress = bi::address_v4(_r[i][0].toHash<FixedHash<4>>().asArray());
else
{
cwarn << "Received bad peer packet:" << _r;
disconnect(BadProtocol);
return true;
}
auto ep = bi::tcp::endpoint(peerAddress, _r[i][1].toInt<short>());
NodeId id = _r[i][2].toHash<NodeId>();
if (!isPublicAddress(peerAddress))
goto CONTINUE; // Private address. Ignore.
clogS(NetAllDetail) << "Checking: " << ep << "(" << id.abridged() << ")";
if (!id)
goto LAMEPEER; // Null identity. Ignore.
if (!isPublicAddress(peerAddress))
goto CONTINUE; // Private address. Ignore.
if (m_server->id() == id)
goto LAMEPEER; // Just our info - we already have that.
if (!id)
goto LAMEPEER; // Null identity. Ignore.
if (id == this->id())
goto LAMEPEER; // Just their info - we already have that.
if (m_server->id() == id)
goto LAMEPEER; // Just our info - we already have that.
if (!ep.port())
goto LAMEPEER; // Zero port? Don't think so.
if (id == this->id())
goto LAMEPEER; // Just their info - we already have that.
if (ep.port() >= /*49152*/32768)
goto LAMEPEER; // Private port according to IANA.
if (!ep.port())
goto LAMEPEER; // Zero port? Don't think so.
// OK passed all our checks. Assume it's good.
addRating(1000);
m_server->addNode(id, ep.address(), ep.port(), ep.port());
clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")";
CONTINUE:;
LAMEPEER:;
}
break;
default:
{
for (auto const& i: m_capabilities)
if (_t >= i.second->m_idOffset && _t - i.second->m_idOffset < i.second->hostCapability()->messageCount())
{
if (i.second->m_enabled)
return i.second->interpret(_t - i.second->m_idOffset, _r);
else
return true;
if (ep.port() >= /*49152*/32768)
goto LAMEPEER; // Private port according to IANA.
// OK passed all our checks. Assume it's good.
addRating(1000);
m_server->addNode(id, ep.address(), ep.port(), ep.port());
clogS(NetTriviaDetail) << "New peer: " << ep << "(" << id .abridged()<< ")";
CONTINUE:;
LAMEPEER:;
}
return false;
}
}
break;
default:
for (auto const& i: m_capabilities)
if (_t >= i.second->m_idOffset && _t - i.second->m_idOffset < i.second->hostCapability()->messageCount())
{
if (i.second->m_enabled)
return i.second->interpret(_t - i.second->m_idOffset, _r);
else
return true;
}
return false;
}
}
catch (std::exception const& _e)
{

2
mix/qml.qrc

@ -61,5 +61,7 @@
<file>qml/js/ProjectModel.js</file>
<file>qml/js/QEtherHelper.js</file>
<file>qml/js/TransactionHelper.js</file>
<file>qml/js/Printer.js</file>
<file>qml/js/ansi2html.js</file>
</qresource>
</RCC>

2
mix/qml/Application.qml

@ -178,7 +178,7 @@ ApplicationWindow {
id: editStatesAction
text: qsTr("Edit States")
shortcut: "Ctrl+Alt+E"
onTriggered: stateList.show();
onTriggered: stateList.open();
}
Connections {

448
mix/qml/DeploymentDialog.qml

@ -2,7 +2,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import QtQuick.Dialogs 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.3
import org.ethereum.qml.QEther 1.0
import "js/TransactionHelper.js" as TransactionHelper
@ -11,16 +11,11 @@ import "js/QEtherHelper.js" as QEtherHelper
import "."
Window {
Dialog {
id: modalDeploymentDialog
modality: Qt.ApplicationModal
width: 735
height: 320
maximumWidth: width
minimumWidth: width
maximumHeight: height
minimumHeight: height
height: 400
visible: false
property alias applicationUrlEth: applicationUrlEth.text
property alias applicationUrlHttp: applicationUrlHttp.text
@ -32,8 +27,6 @@ Window {
property string currentAccount
property alias gasToUse: gasToUseInput.text
color: appStyle.generic.layout.backgroundColor
function close()
{
visible = false;
@ -41,10 +34,7 @@ Window {
function open()
{
modalDeploymentDialog.setX((Screen.width - width) / 2);
modalDeploymentDialog.setY((Screen.height - height) / 2);
visible = true;
var requests = [{
//accounts
jsonrpc: "2.0",
@ -160,136 +150,140 @@ Window {
id: lightFont
}
Column
{
spacing: 5
contentItem: Rectangle {
color: appStyle.generic.layout.backgroundColor
anchors.fill: parent
anchors.margins: 10
ColumnLayout
Column
{
id: containerDeploy
Layout.fillWidth: true
Layout.preferredHeight: 500
RowLayout
spacing: 5
anchors.fill: parent
anchors.margins: 10
ColumnLayout
{
Rectangle
id: containerDeploy
Layout.fillWidth: true
Layout.preferredHeight: 500
RowLayout
{
Layout.preferredWidth: 357
DefaultLabel
Rectangle
{
text: qsTr("Deployment")
font.family: lightFont.name
font.underline: true
anchors.centerIn: parent
Layout.preferredWidth: 357
DefaultLabel
{
text: qsTr("Deployment")
font.family: lightFont.name
font.underline: true
anchors.centerIn: parent
}
}
}
Button
{
action: displayHelpAction
iconSource: "qrc:/qml/img/help.png"
}
Action {
id: displayHelpAction
tooltip: qsTr("Help")
onTriggered: {
Qt.openUrlExternally("https://github.com/ethereum/wiki/wiki/Mix:-The-DApp-IDE#deployment-to-network")
Button
{
action: displayHelpAction
iconSource: "qrc:/qml/img/help.png"
}
}
Button
{
action: openFolderAction
iconSource: "qrc:/qml/img/openedfolder.png"
}
Action {
id: openFolderAction
enabled: deploymentDialog.packageBase64 !== ""
tooltip: qsTr("Open Package Folder")
onTriggered: {
fileIo.openFileBrowser(projectModel.deploymentDir);
Action {
id: displayHelpAction
tooltip: qsTr("Help")
onTriggered: {
Qt.openUrlExternally("https://github.com/ethereum/wiki/wiki/Mix:-The-DApp-IDE#deployment-to-network")
}
}
}
Button
{
action: b64Action
iconSource: "qrc:/qml/img/b64.png"
}
Button
{
action: openFolderAction
iconSource: "qrc:/qml/img/openedfolder.png"
}
Action {
id: b64Action
enabled: deploymentDialog.packageBase64 !== ""
tooltip: qsTr("Copy Base64 conversion to ClipBoard")
onTriggered: {
clipboard.text = deploymentDialog.packageBase64;
Action {
id: openFolderAction
enabled: deploymentDialog.packageBase64 !== ""
tooltip: qsTr("Open Package Folder")
onTriggered: {
fileIo.openFileBrowser(projectModel.deploymentDir);
}
}
}
Button
{
action: exitAction
iconSource: "qrc:/qml/img/exit.png"
}
Button
{
action: b64Action
iconSource: "qrc:/qml/img/b64.png"
}
Action {
id: exitAction
tooltip: qsTr("Exit")
onTriggered: {
close()
Action {
id: b64Action
enabled: deploymentDialog.packageBase64 !== ""
tooltip: qsTr("Copy Base64 conversion to ClipBoard")
onTriggered: {
clipboard.text = deploymentDialog.packageBase64;
}
}
}
}
GridLayout
{
columns: 2
width: parent.width
Button
{
action: exitAction
iconSource: "qrc:/qml/img/exit.png"
}
DefaultLabel
{
text: qsTr("Root Registrar address:")
Action {
id: exitAction
tooltip: qsTr("Exit")
onTriggered: {
close()
}
}
}
DefaultTextField
GridLayout
{
Layout.preferredWidth: 350
id: registrarAddr
}
columns: 2
width: parent.width
DefaultLabel
{
text: qsTr("Account used to deploy:")
}
DefaultLabel
{
text: qsTr("Root Registrar address:")
}
Rectangle
{
width: 300
height: 25
color: "transparent"
ComboBox {
id: comboAccounts
property var balances: []
onCurrentIndexChanged : {
if (modelAccounts.count > 0)
{
currentAccount = modelAccounts.get(currentIndex).id;
balance.text = balances[currentIndex];
}
}
model: ListModel {
id: modelAccounts
}
DefaultTextField
{
Layout.preferredWidth: 350
id: registrarAddr
}
DefaultLabel
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: comboAccounts.right
anchors.leftMargin: 20
id: balance;
text: qsTr("Account used to deploy:")
}
Rectangle
{
width: 300
height: 25
color: "transparent"
ComboBox {
id: comboAccounts
property var balances: []
onCurrentIndexChanged : {
if (modelAccounts.count > 0)
{
currentAccount = modelAccounts.get(currentIndex).id;
balance.text = balances[currentIndex];
}
}
model: ListModel {
id: modelAccounts
}
}
DefaultLabel
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: comboAccounts.right
anchors.leftMargin: 20
id: balance;
}
}
}
@ -335,167 +329,119 @@ Window {
}
}
RowLayout
Rectangle
{
Layout.fillWidth: true
Rectangle
{
Layout.preferredWidth: 357
color: "transparent"
}
width: parent.width
height: 1
color: "#5891d3"
}
Button
ColumnLayout
{
id: containerRegister
Layout.fillWidth: true
Layout.preferredHeight: 500
RowLayout
{
id: deployButton
action: runAction
iconSource: "qrc:/qml/img/run.png"
}
Action {
id: runAction
tooltip: qsTr("Deploy contract(s) and Package resources files.")
onTriggered: {
var inError = [];
var ethUrl = ProjectModelCode.formatAppUrl(applicationUrlEth.text);
for (var k in ethUrl)
{
if (ethUrl[k].length > 32)
inError.push(qsTr("Member too long: " + ethUrl[k]) + "\n");
}
if (!stopForInputError(inError))
Layout.preferredHeight: 25
Rectangle
{
Layout.preferredWidth: 356
DefaultLabel
{
if (contractRedeploy.checked)
deployWarningDialog.open();
else
ProjectModelCode.startDeployProject(false);
text: qsTr("Registration")
font.family: lightFont.name
font.underline: true
anchors.centerIn: parent
}
}
}
CheckBox
GridLayout
{
anchors.left: deployButton.right
id: contractRedeploy
enabled: Object.keys(projectModel.deploymentAddresses).length > 0
checked: Object.keys(projectModel.deploymentAddresses).length == 0
text: qsTr("Deploy Contract(s)")
anchors.verticalCenter: parent.verticalCenter
}
}
}
Rectangle
{
width: parent.width
height: 1
color: "#5891d3"
}
columns: 2
Layout.fillWidth: true
ColumnLayout
{
id: containerRegister
Layout.fillWidth: true
Layout.preferredHeight: 500
RowLayout
{
Layout.preferredHeight: 25
Rectangle
{
Layout.preferredWidth: 356
DefaultLabel
{
text: qsTr("Registration")
font.family: lightFont.name
font.underline: true
anchors.centerIn: parent
Layout.preferredWidth: 355
text: qsTr("Local package URL")
}
}
}
GridLayout
{
columns: 2
Layout.fillWidth: true
DefaultLabel
{
Layout.preferredWidth: 355
text: qsTr("Local package URL")
}
DefaultTextField
{
Layout.preferredWidth: 350
id: localPackageUrl
readOnly: true
enabled: rowRegister.isOkToRegister()
}
DefaultTextField
{
Layout.preferredWidth: 350
id: localPackageUrl
readOnly: true
enabled: rowRegister.isOkToRegister()
}
DefaultLabel
{
Layout.preferredWidth: 355
text: qsTr("URL Hint contract address:")
}
DefaultLabel
{
Layout.preferredWidth: 355
text: qsTr("URL Hint contract address:")
}
DefaultTextField
{
Layout.preferredWidth: 350
id: urlHintAddr
enabled: rowRegister.isOkToRegister()
}
DefaultTextField
{
Layout.preferredWidth: 350
id: urlHintAddr
enabled: rowRegister.isOkToRegister()
}
DefaultLabel
{
Layout.preferredWidth: 355
text: qsTr("Web Application Resources URL: ")
}
DefaultLabel
{
Layout.preferredWidth: 355
text: qsTr("Web Application Resources URL: ")
DefaultTextField
{
Layout.preferredWidth: 350
id: applicationUrlHttp
enabled: rowRegister.isOkToRegister()
}
}
DefaultTextField
RowLayout
{
Layout.preferredWidth: 350
id: applicationUrlHttp
enabled: rowRegister.isOkToRegister()
}
}
RowLayout
{
id: rowRegister
Layout.fillWidth: true
id: rowRegister
Layout.fillWidth: true
Rectangle
{
Layout.preferredWidth: 357
color: "transparent"
}
Rectangle
{
Layout.preferredWidth: 357
color: "transparent"
}
function isOkToRegister()
{
return Object.keys(projectModel.deploymentAddresses).length > 0 && deploymentDialog.packageHash !== "";
}
function isOkToRegister()
{
return Object.keys(projectModel.deploymentAddresses).length > 0 && deploymentDialog.packageHash !== "";
}
Button {
action: registerAction
iconSource: "qrc:/qml/img/note.png"
}
Button {
action: registerAction
iconSource: "qrc:/qml/img/note.png"
}
Action {
id: registerAction
enabled: rowRegister.isOkToRegister()
tooltip: qsTr("Register hosted Web Application.")
onTriggered: {
if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "")
{
deployDialog.title = text;
deployDialog.text = qsTr("Please provide the link where the resources are stored and ensure the package is aleary built using the deployment step.")
deployDialog.open();
return;
Action {
id: registerAction
enabled: rowRegister.isOkToRegister()
tooltip: qsTr("Register hosted Web Application.")
onTriggered: {
if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "")
{
deployDialog.title = text;
deployDialog.text = qsTr("Please provide the link where the resources are stored and ensure the package is aleary built using the deployment step.")
deployDialog.open();
return;
}
var inError = [];
if (applicationUrlHttp.text.length > 32)
inError.push(qsTr(applicationUrlHttp.text));
if (!stopForInputError(inError))
ProjectModelCode.registerToUrlHint();
}
var inError = [];
if (applicationUrlHttp.text.length > 32)
inError.push(qsTr(applicationUrlHttp.text));
if (!stopForInputError(inError))
ProjectModelCode.registerToUrlHint();
}
}
}

94
mix/qml/NewProjectDialog.qml

@ -1,10 +1,11 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.0
import QtQuick.Dialogs 1.1
Window {
Dialog {
id: newProjectWin
modality: Qt.ApplicationModal
@ -33,62 +34,65 @@ Window {
close();
accepted();
}
GridLayout {
id: dialogContent
columns: 2
contentItem: Rectangle {
anchors.fill: parent
anchors.margins: 10
rowSpacing: 10
columnSpacing: 10
GridLayout
{
id: dialogContent
columns: 2
anchors.fill: parent
anchors.margins: 10
rowSpacing: 10
columnSpacing: 10
Label {
text: qsTr("Title")
}
TextField {
id: titleField
focus: true
Layout.fillWidth: true
Keys.onReturnPressed: {
if (okButton.enabled)
acceptAndClose();
Label {
text: qsTr("Title")
}
}
Label {
text: qsTr("Path")
}
RowLayout {
TextField {
id: pathField
id: titleField
focus: true
Layout.fillWidth: true
Keys.onReturnPressed: {
if (okButton.enabled)
acceptAndClose();
}
}
Button {
text: qsTr("Browse")
onClicked: createProjectFileDialog.open()
Label {
text: qsTr("Path")
}
RowLayout {
TextField {
id: pathField
Layout.fillWidth: true
Keys.onReturnPressed: {
if (okButton.enabled)
acceptAndClose();
}
}
Button {
text: qsTr("Browse")
onClicked: createProjectFileDialog.open()
}
}
}
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
Button {
id: okButton;
enabled: titleField.text != "" && pathField.text != ""
text: qsTr("OK");
onClicked: {
acceptAndClose();
Button {
id: okButton;
enabled: titleField.text != "" && pathField.text != ""
text: qsTr("OK");
onClicked: {
acceptAndClose();
}
}
Button {
text: qsTr("Cancel");
onClicked: close();
}
}
Button {
text: qsTr("Cancel");
onClicked: close();
}
}
}
@ -102,8 +106,8 @@ Window {
var u = createProjectFileDialog.fileUrl.toString();
if (u.indexOf("file://") == 0)
u = u.substring(7, u.length)
if (Qt.platform.os == "windows" && u.indexOf("/") == 0)
u = u.substring(1, u.length);
if (Qt.platform.os == "windows" && u.indexOf("/") == 0)
u = u.substring(1, u.length);
pathField.text = u;
}
}

564
mix/qml/StateDialog.qml

@ -1,6 +1,6 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import QtQuick.Controls.Styles 1.3
@ -9,7 +9,7 @@ import "js/QEtherHelper.js" as QEtherHelper
import "js/TransactionHelper.js" as TransactionHelper
import "."
Window {
Dialog {
id: modalStateDialog
modality: Qt.ApplicationModal
@ -17,7 +17,6 @@ Window {
height: 480
title: qsTr("Edit State")
visible: false
color: stateDialogStyle.generic.backgroundColor
property alias stateTitle: titleField.text
property alias isDefault: defaultCheckBox.checked
@ -28,6 +27,10 @@ Window {
property var stateAccounts: []
signal accepted
StateDialogStyle {
id: stateDialogStyle
}
function open(index, item, setDefault) {
stateIndex = index;
stateTitle = item.title;
@ -48,9 +51,6 @@ Window {
stateAccounts.push(item.accounts[k]);
}
modalStateDialog.setX((Screen.width - width) / 2);
modalStateDialog.setY((Screen.height - height) / 2);
visible = true;
isDefault = setDefault;
titleField.focus = true;
@ -77,338 +77,334 @@ Window {
item.accounts = stateAccounts;
return item;
}
StateDialogStyle {
id: stateDialogStyle
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
contentItem: Rectangle {
color: stateDialogStyle.generic.backgroundColor
ColumnLayout {
id: dialogContent
anchors.top: parent.top
RowLayout
{
Layout.fillWidth: true
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Title")
}
DefaultTextField
{
id: titleField
Layout.fillWidth: true
}
}
CommonSeparator
{
Layout.fillWidth: true
}
RowLayout
{
Layout.fillWidth: true
Rectangle
{
Layout.preferredWidth: 75
DefaultLabel {
id: accountsLabel
Layout.preferredWidth: 75
text: qsTr("Accounts")
anchors.fill: parent
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
ColumnLayout {
id: dialogContent
anchors.top: parent.top
RowLayout
{
Layout.fillWidth: true
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Title")
}
DefaultTextField
{
id: titleField
Layout.fillWidth: true
}
}
Button
CommonSeparator
{
anchors.top: accountsLabel.bottom
anchors.topMargin: 10
iconSource: "qrc:/qml/img/plus.png"
action: newAccountAction
Layout.fillWidth: true
}
Action {
id: newAccountAction
tooltip: qsTr("Add new Account")
onTriggered:
{
var account = stateListModel.newAccount("1000000", QEther.Ether);
stateAccounts.push(account);
accountsModel.append(account);
}
}
}
RowLayout
{
Layout.fillWidth: true
MessageDialog
{
id: alertAlreadyUsed
text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.")
icon: StandardIcon.Warning
standardButtons: StandardButton.Ok
}
Rectangle
{
Layout.preferredWidth: 75
DefaultLabel {
id: accountsLabel
Layout.preferredWidth: 75
text: qsTr("Accounts")
}
TableView
{
id: accountsView
Layout.fillWidth: true
model: accountsModel
headerVisible: false
TableViewColumn {
role: "name"
title: qsTr("Name")
width: 150
delegate: Item {
RowLayout
Button
{
height: 25
width: parent.width
Button
anchors.top: accountsLabel.bottom
anchors.topMargin: 10
iconSource: "qrc:/qml/img/plus.png"
action: newAccountAction
}
Action {
id: newAccountAction
tooltip: qsTr("Add new Account")
onTriggered:
{
iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteAccountAction
var account = stateListModel.newAccount("1000000", QEther.Ether);
stateAccounts.push(account);
accountsModel.append(account);
}
}
}
Action {
id: deleteAccountAction
tooltip: qsTr("Delete Account")
onTriggered:
MessageDialog
{
id: alertAlreadyUsed
text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.")
icon: StandardIcon.Warning
standardButtons: StandardButton.Ok
}
TableView
{
id: accountsView
Layout.fillWidth: true
model: accountsModel
headerVisible: false
TableViewColumn {
role: "name"
title: qsTr("Name")
width: 150
delegate: Item {
RowLayout
{
if (transactionsModel.isUsed(stateAccounts[styleData.row].secret))
alertAlreadyUsed.open();
else
height: 25
width: parent.width
Button
{
stateAccounts.splice(styleData.row, 1);
accountsModel.remove(styleData.row);
iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteAccountAction
}
Action {
id: deleteAccountAction
tooltip: qsTr("Delete Account")
onTriggered:
{
if (transactionsModel.isUsed(stateAccounts[styleData.row].secret))
alertAlreadyUsed.open();
else
{
stateAccounts.splice(styleData.row, 1);
accountsModel.remove(styleData.row);
}
}
}
DefaultTextField {
anchors.verticalCenter: parent.verticalCenter
onTextChanged: {
if (styleData.row > -1)
stateAccounts[styleData.row].name = text;
}
text: {
return styleData.value
}
}
}
}
}
DefaultTextField {
anchors.verticalCenter: parent.verticalCenter
onTextChanged: {
if (styleData.row > -1)
stateAccounts[styleData.row].name = text;
}
text: {
return styleData.value
TableViewColumn {
role: "balance"
title: qsTr("Balance")
width: 200
delegate: Item {
Ether {
id: balanceField
edit: true
displayFormattedValue: false
value: styleData.value
}
}
}
rowDelegate:
Rectangle {
color: styleData.alternate ? "transparent" : "#f0f0f0"
height: 30;
}
}
}
TableViewColumn {
role: "balance"
title: qsTr("Balance")
width: 200
delegate: Item {
Ether {
id: balanceField
edit: true
displayFormattedValue: false
value: styleData.value
}
CommonSeparator
{
Layout.fillWidth: true
}
RowLayout
{
Layout.fillWidth: true
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Default")
}
CheckBox {
id: defaultCheckBox
Layout.fillWidth: true
}
}
rowDelegate:
Rectangle {
color: styleData.alternate ? "transparent" : "#f0f0f0"
height: 30;
CommonSeparator
{
Layout.fillWidth: true
}
}
}
CommonSeparator
{
Layout.fillWidth: true
}
ColumnLayout {
anchors.top: dialogContent.bottom
anchors.topMargin: 5
spacing: 0
RowLayout
{
Layout.preferredWidth: 150
DefaultLabel {
text: qsTr("Transactions: ")
}
RowLayout
{
Layout.fillWidth: true
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Default")
}
CheckBox {
id: defaultCheckBox
Layout.fillWidth: true
}
}
Button
{
iconSource: "qrc:/qml/img/plus.png"
action: newTrAction
width: 10
height: 10
anchors.right: parent.right
}
CommonSeparator
{
Layout.fillWidth: true
}
}
Action {
id: newTrAction
tooltip: qsTr("Create a new transaction")
onTriggered: transactionsModel.addTransaction()
}
}
ColumnLayout {
anchors.top: dialogContent.bottom
anchors.topMargin: 5
spacing: 0
RowLayout
{
Layout.preferredWidth: 150
DefaultLabel {
text: qsTr("Transactions: ")
ScrollView
{
Layout.fillHeight: true
Layout.preferredWidth: 300
Column
{
Layout.fillHeight: true
Repeater
{
id: trRepeater
model: transactionsModel
delegate: transactionRenderDelegate
visible: transactionsModel.count > 0
height: 20 * transactionsModel.count
}
}
}
}
Button
RowLayout
{
iconSource: "qrc:/qml/img/plus.png"
action: newTrAction
width: 10
height: 10
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.right: parent.right;
Button {
text: qsTr("OK");
onClicked: {
close();
accepted();
}
}
Button {
text: qsTr("Cancel");
onClicked: close();
}
}
Action {
id: newTrAction
tooltip: qsTr("Create a new transaction")
onTriggered: transactionsModel.addTransaction()
}
}
ListModel {
id: accountsModel
ScrollView
{
Layout.fillHeight: true
Layout.preferredWidth: 300
Column
{
Layout.fillHeight: true
Repeater
function removeAccount(_i)
{
id: trRepeater
model: transactionsModel
delegate: transactionRenderDelegate
visible: transactionsModel.count > 0
height: 20 * transactionsModel.count
accountsModel.remove(_i);
stateAccounts.splice(_i, 1);
}
}
}
CommonSeparator
{
Layout.fillWidth: true
}
}
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
Button {
text: qsTr("OK");
onClicked: {
acceptAndClose();
}
}
Button {
text: qsTr("Cancel");
onClicked: close();
}
}
}
ListModel {
id: accountsModel
function removeAccount(_i)
{
accountsModel.remove(_i);
stateAccounts.splice(_i, 1);
}
}
ListModel {
id: transactionsModel
ListModel {
id: transactionsModel
function editTransaction(index) {
transactionDialog.stateAccounts = stateAccounts;
transactionDialog.open(index, transactionsModel.get(index));
}
function editTransaction(index) {
transactionDialog.stateAccounts = stateAccounts;
transactionDialog.open(index, transactionsModel.get(index));
}
function addTransaction() {
function addTransaction() {
// Set next id here to work around Qt bug
// https://bugreports.qt-project.org/browse/QTBUG-41327
// Second call to signal handler would just edit the item that was just created, no harm done
var item = TransactionHelper.defaultTransaction();
transactionDialog.stateAccounts = stateAccounts;
transactionDialog.open(transactionsModel.count, item);
}
// Set next id here to work around Qt bug
// https://bugreports.qt-project.org/browse/QTBUG-41327
// Second call to signal handler would just edit the item that was just created, no harm done
var item = TransactionHelper.defaultTransaction();
transactionDialog.stateAccounts = stateAccounts;
transactionDialog.open(transactionsModel.count, item);
}
function deleteTransaction(index) {
stateTransactions.splice(index, 1);
transactionsModel.remove(index);
}
function deleteTransaction(index) {
stateTransactions.splice(index, 1);
transactionsModel.remove(index);
}
function isUsed(secret)
{
for (var i in stateTransactions)
{
if (stateTransactions[i].sender === secret)
return true;
}
return false;
}
}
function isUsed(secret)
{
for (var i in stateTransactions)
{
if (stateTransactions[i].sender === secret)
return true;
}
return false;
}
}
Component {
id: transactionRenderDelegate
RowLayout {
DefaultLabel {
Layout.preferredWidth: 150
text: functionId
}
Component {
id: transactionRenderDelegate
RowLayout {
DefaultLabel {
Layout.preferredWidth: 150
text: functionId
}
Button
{
id: deleteBtn
iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteAction
width: 10
height: 10
Action {
id: deleteAction
tooltip: qsTr("Delete")
onTriggered: transactionsModel.deleteTransaction(index)
}
}
Button
{
id: deleteBtn
iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteAction
width: 10
height: 10
Action {
id: deleteAction
tooltip: qsTr("Delete")
onTriggered: transactionsModel.deleteTransaction(index)
Button
{
iconSource: "qrc:/qml/img/edit.png"
action: editAction
visible: stdContract === false
width: 10
height: 10
Action {
id: editAction
tooltip: qsTr("Edit")
onTriggered: transactionsModel.editTransaction(index)
}
}
}
}
}
Button
{
iconSource: "qrc:/qml/img/edit.png"
action: editAction
visible: stdContract === false
width: 10
height: 10
Action {
id: editAction
tooltip: qsTr("Edit")
onTriggered: transactionsModel.editTransaction(index)
TransactionDialog
{
id: transactionDialog
onAccepted:
{
var item = transactionDialog.getItem();
if (transactionDialog.transactionIndex < transactionsModel.count) {
transactionsModel.set(transactionDialog.transactionIndex, item);
stateTransactions[transactionDialog.transactionIndex] = item;
} else {
transactionsModel.append(item);
stateTransactions.push(item);
}
}
}
}
}
}
TransactionDialog
{
id: transactionDialog
onAccepted:
{
var item = transactionDialog.getItem();
if (transactionDialog.transactionIndex < transactionsModel.count) {
transactionsModel.set(transactionDialog.transactionIndex, item);
stateTransactions[transactionDialog.transactionIndex] = item;
} else {
transactionsModel.append(item);
stateTransactions.push(item);
}
}
}
}

74
mix/qml/StateList.qml

@ -1,39 +1,50 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import "."
Window {
Dialog {
id: stateListContainer
modality: Qt.WindowModal
width: 640
height: 480
visible: false
ColumnLayout
{
contentItem: Rectangle {
anchors.fill: parent
TableView {
id: list
Layout.fillHeight: true
Layout.fillWidth: true
model: projectModel.stateListModel
itemDelegate: renderDelegate
headerDelegate: null
TableViewColumn {
role: "title"
title: qsTr("State")
width: list.width
ColumnLayout
{
anchors.fill: parent
TableView {
id: list
Layout.fillHeight: true
Layout.fillWidth: true
model: projectModel.stateListModel
itemDelegate: renderDelegate
headerDelegate: null
frameVisible: false
TableViewColumn {
role: "title"
title: qsTr("State")
width: list.width
}
}
}
Button {
anchors.bottom: parent.bottom
action: addStateAction
Row{
spacing: 5
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 10
Button {
action: addStateAction
}
Button {
action: closeAction
}
}
}
}
@ -69,12 +80,21 @@ Window {
}
}
Action {
id: addStateAction
text: "&Add State"
shortcut: "Ctrl+T"
enabled: codeModel.hasContract && !clientModel.running;
onTriggered: list.model.addState();
Row
{
Action {
id: addStateAction
text: qsTr("Add State")
shortcut: "Ctrl+T"
enabled: codeModel.hasContract && !clientModel.running;
onTriggered: list.model.addState();
}
Action {
id: closeAction
text: qsTr("Close")
onTriggered: stateListContainer.close();
}
}
}

379
mix/qml/TransactionDialog.qml

@ -1,19 +1,19 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.0
import QtQuick.Controls.Styles 1.3
import org.ethereum.qml.QEther 1.0
import "js/TransactionHelper.js" as TransactionHelper
import "."
Window {
Dialog {
id: modalTransactionDialog
modality: Qt.ApplicationModal
width: 520
height: 500;
height: 500
visible: false
color: transactionDialogStyle.generic.backgroundColor
title: qsTr("Edit Transaction")
property int transactionIndex
property alias gas: gasValueEdit.gasValue;
@ -27,6 +27,10 @@ Window {
property alias stateAccounts: senderComboBox.model
signal accepted;
StateDialogStyle {
id: transactionDialogStyle
}
function open(index, item) {
rowFunction.visible = !useTransactionDefaultValue;
rowValue.visible = !useTransactionDefaultValue;
@ -73,8 +77,6 @@ Window {
}
}
initTypeLoader();
modalTransactionDialog.setX((Screen.width - width) / 2);
modalTransactionDialog.setY((Screen.height - height) / 2);
visible = true;
valueField.focus = true;
@ -178,214 +180,219 @@ Window {
item.parameters = paramValues;
return item;
}
StateDialogStyle {
id: transactionDialogStyle
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
contentItem: Rectangle {
color: transactionDialogStyle.generic.backgroundColor
ColumnLayout {
id: dialogContent
anchors.top: parent.top
spacing: 10
RowLayout
{
id: rowSender
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Sender")
}
ComboBox {
function select(secret)
anchors.fill: parent
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
ColumnLayout {
id: dialogContent
anchors.top: parent.top
spacing: 10
RowLayout
{
for (var i in model)
if (model[i].secret === secret)
id: rowSender
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Sender")
}
ComboBox {
function select(secret)
{
currentIndex = i;
break;
for (var i in model)
if (model[i].secret === secret)
{
currentIndex = i;
break;
}
}
}
id: senderComboBox
Layout.preferredWidth: 350
currentIndex: 0
textRole: "name"
editable: false
}
}
id: senderComboBox
Layout.preferredWidth: 350
currentIndex: 0
textRole: "name"
editable: false
}
}
RowLayout
{
id: rowContract
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Contract")
}
ComboBox {
id: contractComboBox
function currentValue() {
return (currentIndex >=0 && currentIndex < contractsModel.count) ? contractsModel.get(currentIndex).cid : "";
RowLayout
{
id: rowContract
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Contract")
}
ComboBox {
id: contractComboBox
function currentValue() {
return (currentIndex >=0 && currentIndex < contractsModel.count) ? contractsModel.get(currentIndex).cid : "";
}
Layout.preferredWidth: 350
currentIndex: -1
textRole: "text"
editable: false
model: ListModel {
id: contractsModel
}
onCurrentIndexChanged: {
loadFunctions(currentValue());
}
}
}
Layout.preferredWidth: 350
currentIndex: -1
textRole: "text"
editable: false
model: ListModel {
id: contractsModel
RowLayout
{
id: rowFunction
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Function")
}
ComboBox {
id: functionComboBox
Layout.preferredWidth: 350
currentIndex: -1
textRole: "text"
editable: false
model: ListModel {
id: functionsModel
}
onCurrentIndexChanged: {
loadParameters();
}
}
}
onCurrentIndexChanged: {
loadFunctions(currentValue());
CommonSeparator
{
Layout.fillWidth: true
}
}
}
RowLayout
{
id: rowFunction
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Function")
}
ComboBox {
id: functionComboBox
Layout.preferredWidth: 350
currentIndex: -1
textRole: "text"
editable: false
model: ListModel {
id: functionsModel
RowLayout
{
id: rowValue
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Value")
}
Ether {
id: valueField
edit: true
displayFormattedValue: true
}
}
onCurrentIndexChanged: {
loadParameters();
CommonSeparator
{
Layout.fillWidth: true
}
}
}
CommonSeparator
{
Layout.fillWidth: true
}
RowLayout
{
id: rowGas
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Gas")
}
DefaultTextField
{
property variant gasValue
onGasValueChanged: text = gasValue.value();
onTextChanged: gasValue.setValue(text);
implicitWidth: 200
id: gasValueEdit;
}
}
RowLayout
{
id: rowValue
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Value")
}
Ether {
id: valueField
edit: true
displayFormattedValue: true
}
}
CommonSeparator
{
Layout.fillWidth: true
}
CommonSeparator
{
Layout.fillWidth: true
}
RowLayout
{
id: rowGasPrice
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Gas Price")
}
Ether {
id: gasPriceField
edit: true
displayFormattedValue: true
}
}
RowLayout
{
id: rowGas
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Gas")
}
CommonSeparator
{
Layout.fillWidth: true
}
DefaultTextField
{
property variant gasValue
onGasValueChanged: text = gasValue.value();
onTextChanged: gasValue.setValue(text);
implicitWidth: 200
id: gasValueEdit;
}
}
DefaultLabel {
id: paramLabel
text: qsTr("Parameters:")
Layout.preferredWidth: 75
}
CommonSeparator
{
Layout.fillWidth: true
}
ScrollView
{
id: paramScroll
anchors.top: paramLabel.bottom
anchors.topMargin: 10
Layout.fillWidth: true
Layout.fillHeight: true
StructView
{
id: typeLoader
Layout.preferredWidth: 150
members: paramsModel;
}
}
RowLayout
{
id: rowGasPrice
Layout.fillWidth: true
height: 150
DefaultLabel {
Layout.preferredWidth: 75
text: qsTr("Gas Price")
}
Ether {
id: gasPriceField
edit: true
displayFormattedValue: true
CommonSeparator
{
Layout.fillWidth: true
visible: paramsModel.length > 0
}
}
}
CommonSeparator
{
Layout.fillWidth: true
}
DefaultLabel {
id: paramLabel
text: qsTr("Parameters:")
Layout.preferredWidth: 75
}
ScrollView
RowLayout
{
id: paramScroll
anchors.top: paramLabel.bottom
anchors.topMargin: 10
Layout.fillWidth: true
Layout.fillHeight: true
StructView
{
id: typeLoader
Layout.preferredWidth: 150
members: paramsModel;
anchors.bottom: parent.bottom
anchors.right: parent.right;
Button {
text: qsTr("OK");
onClicked: {
close();
accepted();
}
}
}
CommonSeparator
{
Layout.fillWidth: true
visible: paramsModel.length > 0
}
}
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
Button {
text: qsTr("OK");
onClicked: {
acceptAndClose();
Button {
text: qsTr("Cancel");
onClicked: close();
Layout.fillWidth: true
}
}
Button {
text: qsTr("Cancel");
onClicked: close();
}
}
}
}

1
mix/qml/WebPreview.qml

@ -433,6 +433,7 @@ Item {
id: resultTextArea
width: expressionPanel.width
wrapMode: Text.Wrap
textFormat: Text.RichText
font.family: webPreviewStyle.general.fontName
font.pointSize: appStyle.absoluteSize(-3)
backgroundVisible: true

5
mix/qml/html/WebContainer.html

@ -3,6 +3,8 @@
<head>
<script src="qrc:///js/bignumber.min.js"></script>
<script src="qrc:///js/webthree.js"></script>
<script src="qrc:///qml/js/Printer.js"></script>
<script src="qrc:///qml/js/ansi2html.js"></script>
<script>
loadPage = function(url) {
var preview = document.getElementById('preview');
@ -40,7 +42,8 @@ init = function(url) {
executeJavaScript = function(script) {
var preview = document.getElementById('preview');
var obj = preview.contentWindow.eval(script);
return JSON.stringify(obj, null, 2);
var printed = prettyPrint(obj);
return ansi2html(printed);
}
getContent = function() {

90
mix/qml/js/Printer.js

@ -0,0 +1,90 @@
var prettyPrint = (function () {
function pp(object, indent) {
try {
JSON.stringify(object, null, 2);
} catch (e) {
return pp(e, indent);
}
var str = "";
if(object instanceof Array) {
str += "[";
for(var i = 0, l = object.length; i < l; i++) {
str += pp(object[i], indent);
if(i < l-1) {
str += ", ";
}
}
str += " ]";
} else if (object instanceof Error) {
str += "\e[31m" + "Error:\e[0m " + object.message;
} else if (isBigNumber(object)) {
str += "\e[32m'" + object.toString(10) + "'";
} else if(typeof(object) === "object") {
str += "{\n";
indent += " ";
var last = getFields(object).pop()
getFields(object).forEach(function (k) {
str += indent + k + ": ";
try {
str += pp(object[k], indent);
} catch (e) {
str += pp(e, indent);
}
if(k !== last) {
str += ",";
}
str += "\n";
});
str += indent.substr(2, indent.length) + "}";
} else if(typeof(object) === "string") {
str += "\e[32m'" + object + "'";
} else if(typeof(object) === "undefined") {
str += "\e[1m\e[30m" + object;
} else if(typeof(object) === "number") {
str += "\e[31m" + object;
} else if(typeof(object) === "function") {
str += "\e[35m[Function]";
} else {
str += object;
}
str += "\e[0m";
return str;
}
var redundantFields = [
'valueOf',
'toString',
'toLocaleString',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor',
'__defineGetter__',
'__defineSetter__',
'__lookupGetter__',
'__lookupSetter__',
'__proto__'
];
var getFields = function (object) {
var result = Object.getOwnPropertyNames(object);
if (object.constructor && object.constructor.prototype) {
result = result.concat(Object.getOwnPropertyNames(object.constructor.prototype));
}
return result.filter(function (field) {
return redundantFields.indexOf(field) === -1;
});
};
var isBigNumber = function (object) {
return typeof BigNumber !== 'undefined' && object instanceof BigNumber;
};
function prettyPrintI(/* */) {
var args = arguments;
var ret = "";
for (var i = 0, l = args.length; i < l; i++) {
ret += pp(args[i], "") + "\n";
}
return ret;
}
return prettyPrintI;
})();

106
mix/qml/js/ansi2html.js

@ -0,0 +1,106 @@
var ansi2html = (function(){
function ansi2htmlI(str) {
// this lib do not support \e
str = str.replace(/e\[/g, '[');
// nor line breaks
str = '<div>' + str.replace(/\n/g, '</div><div>') + '</div>';
var props = {}
, open = false
var stylemap =
{ bold: "font-weight"
, underline: "text-decoration"
, color: "color"
, background: "background"
}
function style() {
var key, val, style = []
for (var key in props) {
val = props[key]
if (!val) continue
if (val == true) {
style.push(stylemap[key] + ':' + key)
} else {
style.push(stylemap[key] + ':' + val)
}
}
return style.join(';')
}
function tag(code) {
var i
, tag = ''
, n = ansi2htmlI.table[code]
if (open) tag += '</span>'
open = false
if (n) {
for (i in n) props[i] = n[i]
tag += '<span style="' + style() + '">'
open = true
} else {
props = {}
}
return tag
}
return str.replace(/\[(\d+;)?(\d+)*m/g, function(match, b1, b2) {
var i, code, res = ''
if (b2 == '' || b2 == null) b2 = '0'
for (i = 1; i < arguments.length - 2; i++) {
if (!arguments[i]) continue
code = parseInt(arguments[i])
res += tag(code)
}
return res
}) + tag()
}
/* not implemented:
* italic
* blink
* invert
* strikethrough
*/
ansi2htmlI.table =
{ 0: null
, 1: { bold: true }
, 3: { italic: true }
, 4: { underline: true }
, 5: { blink: true }
, 6: { blink: true }
, 7: { invert: true }
, 9: { strikethrough: true }
, 23: { italic: false }
, 24: { underline: false }
, 25: { blink: false }
, 27: { invert: false }
, 29: { strikethrough: false }
, 30: { color: 'black' }
, 31: { color: 'red' }
, 32: { color: 'green' }
, 33: { color: 'yellow' }
, 34: { color: 'blue' }
, 35: { color: 'magenta' }
, 36: { color: 'cyan' }
, 37: { color: 'white' }
, 39: { color: null }
, 40: { background: 'black' }
, 41: { background: 'red' }
, 42: { background: 'green' }
, 43: { background: 'yellow' }
, 44: { background: 'blue' }
, 45: { background: 'magenta' }
, 46: { background: 'cyan' }
, 47: { background: 'white' }
, 49: { background: null }
}
return ansi2htmlI;
})();

4
test/SolidityEndToEndTest.cpp

@ -1414,6 +1414,8 @@ BOOST_AUTO_TEST_CASE(sha3)
testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
}
#ifdef PRECOMPILED_CONTRACTS_GAS_FIXED_IN_SOLIDITY
BOOST_AUTO_TEST_CASE(sha256)
{
char const* sourceCode = "contract test {\n"
@ -1468,6 +1470,8 @@ BOOST_AUTO_TEST_CASE(ecrecover)
BOOST_CHECK(callContractFunction("a(bytes32,uint8,bytes32,bytes32)", h, v, r, s) == encodeArgs(addr));
}
#endif
BOOST_AUTO_TEST_CASE(inter_contract_calls)
{
char const* sourceCode = R"(

940
test/bcUncleHeaderValiditiyFiller.json

@ -0,0 +1,940 @@
{
"correct" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "131072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "131071",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "142813170",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"diffTooLow" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "131072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "difficulty",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "131071",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "142813170",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"diffTooHigh" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "131072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "difficulty",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "131073",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "142813170",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"diffTooLow2" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "difficulty",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230847",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "142813170",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"gasLimitTooHigh" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "gasLimit",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230847",
"extraData" : "0x",
"gasLimit" : "3141593",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "142813170",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"gasLimitTooLow" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "gasLimit",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230847",
"extraData" : "0x",
"gasLimit" : "3141591",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "142813170",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"wrongParentHash" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "parentHash",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230848",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "bad4fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "bad40b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "1528353694",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"wrongStateRoot" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "stateRoot",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230848",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "bad40b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "1528353694",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"timestampTooLow" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "timestamp",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230848",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "1428353694",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"timestampTooHigh" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "231072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"overwriteAndRedoPoW" : "timestamp",
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "acde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "230848",
"extraData" : "0x",
"gasLimit" : "4141592",
"gasUsed" : "150000",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "2",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "1528353694",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
}
}

93
test/bcUncleTestFiller.json

@ -263,6 +263,99 @@
]
},
"uncleWithSameBlockNumber" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "131072",
"extraData" : "0x42",
"gasLimit" : "3141592",
"gasUsed" : "0",
"number" : "0",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a",
"timestamp" : "0x54c98c81",
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"nonce" : "0x0102030405060708",
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"blocks" : [
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "1",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
]
},
{
"transactions" : [
{
"data" : "",
"gasLimit" : "314159",
"gasPrice" : "1",
"nonce" : "2",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10"
}
],
"uncleHeaders" : [
{
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "131072",
"extraData" : "0x",
"gasLimit" : "3141592",
"gasUsed" : "0",
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04",
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770",
"nonce" : "18a524c1790fa83b",
"number" : "3",
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd",
"timestamp" : "0x54c98c82",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
]
},
"InChainUncle" : {
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",

36
test/blockchain.cpp

@ -126,6 +126,12 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
vBiUncles.push_back(vBiBlocks[(size_t)toInt(uncleHeaderObj["sameAsBlock"])]);
continue;
}
string overwrite = "false";
if (uncleHeaderObj.count("overwriteAndRedoPoW"))
{
overwrite = uncleHeaderObj["overwriteAndRedoPoW"].get_str();
uncleHeaderObj.erase("overwriteAndRedoPoW");
}
BlockInfo uncleBlockFromFields = constructBlock(uncleHeaderObj);
@ -141,6 +147,20 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
else
continue;
if (overwrite != "false")
{
uncleBlockFromFields.difficulty = overwrite == "difficulty" ? toInt(uncleHeaderObj["difficulty"]) : uncleBlockFromFields.difficulty;
uncleBlockFromFields.gasLimit = overwrite == "gasLimit" ? toInt(uncleHeaderObj["gasLimit"]) : uncleBlockFromFields.gasLimit;
uncleBlockFromFields.gasUsed = overwrite == "gasUsed" ? toInt(uncleHeaderObj["gasUsed"]) : uncleBlockFromFields.gasUsed;
uncleBlockFromFields.parentHash = overwrite == "parentHash" ? h256(uncleHeaderObj["parentHash"].get_str()) : uncleBlockFromFields.parentHash;
uncleBlockFromFields.stateRoot = overwrite == "stateRoot" ? h256(uncleHeaderObj["stateRoot"].get_str()) : uncleBlockFromFields.stateRoot;
if (overwrite == "timestamp")
{
uncleBlockFromFields.timestamp = toInt(uncleHeaderObj["timestamp"]);
uncleBlockFromFields.difficulty = uncleBlockFromFields.calculateDifficulty(vBiBlocks[(size_t)uncleBlockFromFields.number - 1]);
}
}
updatePoW(uncleBlockFromFields);
writeBlockHeaderToJson(uncleHeaderObj, uncleBlockFromFields);
@ -148,8 +168,16 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
vBiUncles.push_back(uncleBlockFromFields);
cnote << "import uncle in blockQueue";
RLPStream uncle = createFullBlockFromHeader(uncleBlockFromFields);
uncleBlockQueue.import(&uncle.out(), bc);
try
{
uncleBlockQueue.import(&uncle.out(), bc);
}
catch(...)
{
cnote << "error in importing uncle! This produces an invalid block (May be by purpose for testing).";
}
uncleHeaderObj_pre = uncleHeaderObj;
}
@ -402,7 +430,6 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin)
for (auto const& uBlHeaderObj: blObj["uncleHeaders"].get_array())
{
mObject uBlH = uBlHeaderObj.get_obj();
cout << "uBlH.size(): " << uBlH.size() << endl;
BOOST_REQUIRE(uBlH.size() == 16);
bytes uncleRLP = createBlockRLPFromFields(uBlH);
const RLP c_uRLP(uncleRLP);
@ -664,6 +691,11 @@ BOOST_AUTO_TEST_CASE(bcUncleTest)
dev::test::executeTests("bcUncleTest", "/BlockTests", dev::test::doBlockchainTests);
}
BOOST_AUTO_TEST_CASE(bcUncleHeaderValiditiy)
{
dev::test::executeTests("bcUncleHeaderValiditiy", "/BlockTests", dev::test::doBlockchainTests);
}
BOOST_AUTO_TEST_CASE(userDefinedFile)
{
dev::test::userDefinedTest("--singletest", dev::test::doBlockchainTests);

83
test/stCallCreateCallCodeTestFiller.json

@ -125,6 +125,48 @@
}
},
"callWithHighValueOOGinCall": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "30000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"nonce" : "0",
"code" : "{ [[ 0 ]] (ADD (CALL 10000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0 ) 1) }",
"storage": {}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : "0x6001600155603760005360026000f3",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"nonce" : "0",
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "3000000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"Callcode1024BalanceTooLow" : {
"env" : {
"currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
@ -530,5 +572,46 @@
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"createJS_ExampleContract": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"6295ee1b4f6dd65047762f924ecd367c17eabf8f" : {
"balance" : "100000",
"code" : "0x60003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b5056",
"nonce" : "0",
"storage" : {
"0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"0x01" : "0x42",
"0x02" : "0x23",
"0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"0x05" : "0x54c98c81"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "600000",
"to" : "",
"value" : "100000",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023"
}
}
}

20
test/ttTransactionTestFiller.json

@ -347,7 +347,7 @@
}
},
"TransactionWithSvalueWrongSize" : {
"TransactionWithSvalueWrongSize" : {
"transaction" :
{
"data" : "",
@ -407,7 +407,7 @@
}
},
"TransactionWithHihghGasPrice" : {
"TransactionWithHihghGasPrice" : {
"transaction" :
{
"data" : "",
@ -422,7 +422,7 @@
}
},
"TransactionWithGasLimitxPriceOverflow" : {
"TransactionWithGasLimitxPriceOverflow" : {
"transaction" :
{
"data" : "",
@ -598,5 +598,19 @@
"v": "27",
"value": ""
}
},
"dataTx_bcValidBlockTest": {
"transaction": {
"nonce": "0",
"gasPrice": "50",
"gasLimit": "50000",
"to": "",
"data": "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56",
"r" : "0xc5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0",
"s" : "0xe221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884",
"v": "28",
"value": "0"
}
}
}

Loading…
Cancel
Save