2014-08-12 12:02:33 +03:00
|
|
|
import QtQuick 2.0
|
|
|
|
import QtQuick.Controls 1.0;
|
|
|
|
import QtQuick.Layouts 1.0;
|
|
|
|
import QtQuick.Dialogs 1.0;
|
|
|
|
import QtQuick.Window 2.1;
|
|
|
|
import QtQuick.Controls.Styles 1.1
|
|
|
|
import Ethereum 1.0
|
|
|
|
|
|
|
|
Rectangle {
|
2014-08-17 22:07:09 +03:00
|
|
|
id: root
|
2014-10-23 00:50:47 +03:00
|
|
|
property var title: "Block Chain"
|
2014-08-17 22:07:09 +03:00
|
|
|
property var menuItem
|
2014-08-12 12:02:33 +03:00
|
|
|
|
|
|
|
objectName: "chainView"
|
|
|
|
visible: false
|
|
|
|
anchors.fill: parent
|
|
|
|
|
|
|
|
TableView {
|
|
|
|
id: blockTable
|
|
|
|
width: parent.width
|
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
TableViewColumn{ role: "number" ; title: "#" ; width: 100 }
|
|
|
|
TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 }
|
|
|
|
TableViewColumn{ role: "txAmount" ; title: "Tx amount" ; width: 100 }
|
|
|
|
|
|
|
|
model: blockModel
|
|
|
|
|
2014-08-17 13:41:23 +03:00
|
|
|
itemDelegate: Item {
|
|
|
|
Text {
|
|
|
|
anchors {
|
|
|
|
left: parent.left
|
|
|
|
right: parent.right
|
|
|
|
leftMargin: 10
|
|
|
|
verticalCenter: parent.verticalCenter
|
|
|
|
}
|
|
|
|
color: styleData.textColor
|
|
|
|
elide: styleData.elideMode
|
|
|
|
text: styleData.value
|
|
|
|
font.pixelSize: 11
|
|
|
|
MouseArea {
|
2014-08-17 14:05:43 +03:00
|
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
2014-08-17 13:41:23 +03:00
|
|
|
propagateComposedEvents: true
|
|
|
|
anchors.fill: parent
|
|
|
|
onClicked: {
|
|
|
|
blockTable.selection.clear()
|
|
|
|
blockTable.selection.select(styleData.row)
|
|
|
|
|
2014-08-17 14:05:43 +03:00
|
|
|
if(mouse.button == Qt.RightButton) {
|
|
|
|
contextMenu.row = styleData.row;
|
|
|
|
contextMenu.popup()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onDoubleClicked: {
|
|
|
|
popup.visible = true
|
|
|
|
popup.setDetails(blockModel.get(styleData.row))
|
2014-08-17 13:41:23 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Menu {
|
|
|
|
id: contextMenu
|
2014-10-23 00:50:47 +03:00
|
|
|
property var row
|
2014-08-17 13:41:23 +03:00
|
|
|
MenuItem {
|
|
|
|
text: "Details"
|
|
|
|
onTriggered: {
|
|
|
|
popup.visible = true
|
2014-10-23 00:50:47 +03:00
|
|
|
popup.setDetails(blockModel.get(contextMenu.row))
|
2014-08-17 13:41:23 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MenuSeparator{}
|
|
|
|
|
2014-08-17 14:49:46 +03:00
|
|
|
MenuItem {
|
|
|
|
text: "Copy"
|
|
|
|
onTriggered: {
|
2014-10-23 00:50:47 +03:00
|
|
|
copyToClipboard(blockModel.get(contextMenu.row).hash)
|
2014-08-17 14:49:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-17 13:41:23 +03:00
|
|
|
MenuItem {
|
|
|
|
text: "Dump State"
|
|
|
|
onTriggered: {
|
|
|
|
generalFileDialog.show(false, function(path) {
|
2014-10-23 00:50:47 +03:00
|
|
|
var hash = blockModel.get(contextMenu.row).hash;
|
2014-08-17 13:41:23 +03:00
|
|
|
|
|
|
|
gui.dumpState(hash, path);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-17 22:07:09 +03:00
|
|
|
|
|
|
|
|
2014-08-12 12:02:33 +03:00
|
|
|
function addBlock(block, initial) {
|
|
|
|
if(initial == undefined){
|
|
|
|
initial = false
|
|
|
|
}
|
|
|
|
|
2014-09-08 01:50:25 +03:00
|
|
|
var amount = block.transactions.length;
|
2014-10-07 12:18:34 +03:00
|
|
|
var txs = [];
|
|
|
|
for(var i = 0; i < block.transactions.length; i++) {
|
|
|
|
var tx = JSON.parse(block.transactions.getAsJson(i));
|
|
|
|
txs.push(tx);
|
|
|
|
}
|
2014-08-12 12:02:33 +03:00
|
|
|
|
|
|
|
if(initial){
|
2014-11-10 02:17:31 +02:00
|
|
|
blockModel.append({raw: block.raw, bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
|
2014-08-12 12:02:33 +03:00
|
|
|
} else {
|
2015-02-03 05:58:58 +02:00
|
|
|
blockModel.insert(0, {raw: block.raw, bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Window {
|
|
|
|
id: popup
|
|
|
|
visible: false
|
|
|
|
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
|
|
|
|
property var block
|
|
|
|
width: root.width
|
|
|
|
height: 300
|
|
|
|
Component{
|
|
|
|
id: blockDetailsDelegate
|
|
|
|
Rectangle {
|
|
|
|
color: "#252525"
|
|
|
|
width: popup.width
|
|
|
|
height: 150
|
|
|
|
Column {
|
|
|
|
anchors.leftMargin: 10
|
|
|
|
anchors.topMargin: 5
|
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.left: parent.left
|
|
|
|
Text { text: '<h3>Block details</h3>'; color: "#F2F2F2"}
|
2014-08-25 13:53:17 +03:00
|
|
|
Text { text: '<b>Block number:</b> ' + number + " (Size: " + size + ")"; color: "#F2F2F2"}
|
2014-08-12 12:02:33 +03:00
|
|
|
Text { text: '<b>Hash:</b> ' + hash; color: "#F2F2F2"}
|
2014-11-10 02:17:31 +02:00
|
|
|
Text { text: '<b>Bloom:</b> ' + bloom; color: "#F2F2F2"}
|
2014-08-12 12:02:33 +03:00
|
|
|
Text { text: '<b>Coinbase:</b> <' + name + '> ' + coinbase; color: "#F2F2F2"}
|
|
|
|
Text { text: '<b>Block found at:</b> ' + prettyTime; color: "#F2F2F2"}
|
|
|
|
Text { text: '<b>Gas used:</b> ' + gasUsed + " / " + gasLimit; color: "#F2F2F2"}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ListView {
|
|
|
|
model: singleBlock
|
|
|
|
delegate: blockDetailsDelegate
|
|
|
|
anchors.top: parent.top
|
|
|
|
height: 100
|
|
|
|
anchors.leftMargin: 20
|
|
|
|
id: listViewThing
|
|
|
|
Layout.maximumHeight: 40
|
|
|
|
}
|
|
|
|
TableView {
|
|
|
|
id: txView
|
|
|
|
anchors.top: listViewThing.bottom
|
|
|
|
anchors.topMargin: 50
|
|
|
|
width: parent.width
|
|
|
|
|
|
|
|
TableViewColumn{width: 90; role: "value" ; title: "Value" }
|
|
|
|
TableViewColumn{width: 200; role: "hash" ; title: "Hash" }
|
|
|
|
TableViewColumn{width: 200; role: "sender" ; title: "Sender" }
|
|
|
|
TableViewColumn{width: 200;role: "address" ; title: "Receiver" }
|
|
|
|
TableViewColumn{width: 60; role: "gas" ; title: "Gas" }
|
|
|
|
TableViewColumn{width: 60; role: "gasPrice" ; title: "Gas Price" }
|
|
|
|
TableViewColumn{width: 60; role: "isContract" ; title: "Contract" }
|
|
|
|
|
|
|
|
model: transactionModel
|
|
|
|
onClicked: {
|
|
|
|
var tx = transactionModel.get(row)
|
|
|
|
if(tx.data) {
|
|
|
|
popup.showContractData(tx)
|
|
|
|
}else{
|
|
|
|
popup.height = 440
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function showContractData(tx) {
|
|
|
|
txDetailsDebugButton.tx = tx
|
|
|
|
if(tx.createsContract) {
|
|
|
|
contractData.text = tx.data
|
|
|
|
contractLabel.text = "<h4> Transaction created contract " + tx.address + "</h4>"
|
|
|
|
}else{
|
|
|
|
contractLabel.text = "<h4> Transaction ran contract " + tx.address + "</h4>"
|
|
|
|
contractData.text = tx.rawData
|
|
|
|
}
|
|
|
|
popup.height = 540
|
|
|
|
}
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
id: txDetails
|
|
|
|
width: popup.width
|
|
|
|
height: 300
|
|
|
|
anchors.left: listViewThing.left
|
|
|
|
anchors.top: txView.bottom
|
|
|
|
Label {
|
|
|
|
text: "<h4>Contract data</h4>"
|
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.left: parent.left
|
|
|
|
id: contractLabel
|
|
|
|
anchors.leftMargin: 10
|
|
|
|
}
|
|
|
|
Button {
|
|
|
|
property var tx
|
|
|
|
id: txDetailsDebugButton
|
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.rightMargin: 10
|
|
|
|
anchors.top: parent.top
|
|
|
|
anchors.topMargin: 10
|
|
|
|
text: "Debug contract"
|
|
|
|
onClicked: {
|
2014-10-22 12:11:12 +03:00
|
|
|
if(tx && tx.createsContract){
|
2014-08-12 13:16:21 +03:00
|
|
|
eth.startDbWithCode(tx.rawData)
|
2014-08-12 12:02:33 +03:00
|
|
|
}else {
|
2014-08-12 13:16:21 +03:00
|
|
|
eth.startDbWithContractAndData(tx.address, tx.rawData)
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TextArea {
|
|
|
|
id: contractData
|
|
|
|
text: "Contract"
|
|
|
|
anchors.top: contractLabel.bottom
|
|
|
|
anchors.left: parent.left
|
2014-11-10 02:17:31 +02:00
|
|
|
anchors.right: parent.right
|
2014-08-12 12:02:33 +03:00
|
|
|
wrapMode: Text.Wrap
|
|
|
|
height: 80
|
2014-11-10 02:17:31 +02:00
|
|
|
}
|
|
|
|
TextArea {
|
|
|
|
id: dumpData
|
|
|
|
anchors.top: contractData.bottom
|
|
|
|
anchors.left: parent.left
|
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
height: 300
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
property var transactionModel: ListModel {
|
|
|
|
id: transactionModel
|
|
|
|
}
|
|
|
|
property var singleBlock: ListModel {
|
|
|
|
id: singleBlock
|
|
|
|
}
|
2014-10-07 12:18:34 +03:00
|
|
|
function setDetails(bl){
|
|
|
|
singleBlock.set(0, bl)
|
2014-08-12 12:02:33 +03:00
|
|
|
popup.height = 300
|
|
|
|
transactionModel.clear()
|
2014-10-07 12:18:34 +03:00
|
|
|
if(bl.txs !== undefined){
|
|
|
|
for(var i = 0; i < bl.txs.count; i++) {
|
|
|
|
transactionModel.insert(0, bl.txs.get(i))
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
2014-10-07 12:18:34 +03:00
|
|
|
if(bl.txs.count > 0 && bl.txs.get(0).data){
|
|
|
|
popup.showContractData(bl.txs.get(0))
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
txView.forceActiveFocus()
|
2014-11-10 02:17:31 +02:00
|
|
|
dumpData.text = bl.raw;
|
2014-08-12 12:02:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|