Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2114218ed8 | ||
|
58032d60e7 | ||
|
d4f9daa631 | ||
|
1eda1d25b0 | ||
|
aaeb268522 | ||
|
540d39220d | ||
|
09728bf43c | ||
|
d4af5a5763 | ||
|
198ef97108 | ||
|
138b7fe2d8 | ||
|
87a669aeda | ||
|
969b4a4a36 | ||
|
118860abb2 |
@@ -5,7 +5,7 @@ Ethereum
|
|||||||
|
|
||||||
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
||||||
|
|
||||||
Current state: Proof of Concept 5.0 RC10.
|
Current state: Proof of Concept 5.0 RC11.
|
||||||
|
|
||||||
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).
|
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).
|
||||||
|
|
||||||
|
@@ -14,6 +14,26 @@ ApplicationWindow {
|
|||||||
width: 1290
|
width: 1290
|
||||||
height: 900
|
height: 900
|
||||||
|
|
||||||
|
property alias codeText: codeEditor.text
|
||||||
|
property alias dataText: rawDataField.text
|
||||||
|
|
||||||
|
MenuBar {
|
||||||
|
Menu {
|
||||||
|
title: "Debugger"
|
||||||
|
MenuItem {
|
||||||
|
text: "Run"
|
||||||
|
shortcut: "Ctrl+r"
|
||||||
|
onTriggered: debugCurrent()
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Next"
|
||||||
|
shortcut: "Ctrl+n"
|
||||||
|
onTriggered: dbg.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property var asmModel: ListModel {
|
property var asmModel: ListModel {
|
||||||
@@ -150,6 +170,7 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toolBar: ToolBar {
|
toolBar: ToolBar {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 5
|
spacing: 5
|
||||||
@@ -158,7 +179,7 @@ ApplicationWindow {
|
|||||||
property var enabled: true
|
property var enabled: true
|
||||||
id: debugStart
|
id: debugStart
|
||||||
onClicked: {
|
onClicked: {
|
||||||
dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text, rawDataField.text)
|
debugCurrent()
|
||||||
}
|
}
|
||||||
text: "Debug"
|
text: "Debug"
|
||||||
}
|
}
|
||||||
@@ -174,6 +195,10 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function debugCurrent() {
|
||||||
|
dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text, rawDataField.text)
|
||||||
|
}
|
||||||
|
|
||||||
function setAsm(asm) {
|
function setAsm(asm) {
|
||||||
asmModel.append({asm: asm})
|
asmModel.append({asm: asm})
|
||||||
}
|
}
|
||||||
@@ -184,7 +209,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
function setInstruction(num) {
|
function setInstruction(num) {
|
||||||
asmTableView.selection.clear()
|
asmTableView.selection.clear()
|
||||||
asmTableView.selection.select(num-1)
|
asmTableView.selection.select(num)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMem(mem) {
|
function setMem(mem) {
|
||||||
|
@@ -1,196 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: newContract
|
|
||||||
Column {
|
|
||||||
id: mainContractColumn
|
|
||||||
function contractFormReady(){
|
|
||||||
if(codeView.text.length > 0 && txValue.text.length > 0 && txGas.text.length > 0 && txGasPrice.length > 0) {
|
|
||||||
txButton.state = "READY"
|
|
||||||
}else{
|
|
||||||
txButton.state = "NOTREADY"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
states: [
|
|
||||||
State{
|
|
||||||
name: "ERROR"
|
|
||||||
PropertyChanges { target: txResult; visible:true}
|
|
||||||
PropertyChanges { target: codeView; visible:true}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "DONE"
|
|
||||||
PropertyChanges { target: txValue; visible:false}
|
|
||||||
PropertyChanges { target: txGas; visible:false}
|
|
||||||
PropertyChanges { target: txGasPrice; visible:false}
|
|
||||||
PropertyChanges { target: codeView; visible:false}
|
|
||||||
PropertyChanges { target: txButton; visible:false}
|
|
||||||
PropertyChanges { target: txDataLabel; visible:false}
|
|
||||||
|
|
||||||
PropertyChanges { target: txResult; visible:true}
|
|
||||||
PropertyChanges { target: txOutput; visible:true}
|
|
||||||
PropertyChanges { target: newTxButton; visible:true}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "SETUP"
|
|
||||||
PropertyChanges { target: txValue; visible:true; text: ""}
|
|
||||||
PropertyChanges { target: txGas; visible:true; text: ""}
|
|
||||||
PropertyChanges { target: txGasPrice; visible:true; text: ""}
|
|
||||||
PropertyChanges { target: codeView; visible:true; text: ""}
|
|
||||||
PropertyChanges { target: txButton; visible:true}
|
|
||||||
PropertyChanges { target: txDataLabel; visible:true}
|
|
||||||
|
|
||||||
PropertyChanges { target: txResult; visible:false}
|
|
||||||
PropertyChanges { target: txOutput; visible:false}
|
|
||||||
PropertyChanges { target: newTxButton; visible:false}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
width: 400
|
|
||||||
spacing: 5
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.leftMargin: 5
|
|
||||||
anchors.topMargin: 5
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: txValue
|
|
||||||
width: 200
|
|
||||||
placeholderText: "Amount"
|
|
||||||
validator: RegExpValidator { regExp: /\d*/ }
|
|
||||||
onTextChanged: {
|
|
||||||
contractFormReady()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: txGas
|
|
||||||
width: 200
|
|
||||||
validator: RegExpValidator { regExp: /\d*/ }
|
|
||||||
placeholderText: "Gas"
|
|
||||||
onTextChanged: {
|
|
||||||
contractFormReady()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: txGasPrice
|
|
||||||
width: 200
|
|
||||||
placeholderText: "Gas price"
|
|
||||||
validator: RegExpValidator { regExp: /\d*/ }
|
|
||||||
onTextChanged: {
|
|
||||||
contractFormReady()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: rowContract
|
|
||||||
ExclusiveGroup { id: contractTypeGroup }
|
|
||||||
RadioButton {
|
|
||||||
id: createContractRadio
|
|
||||||
text: "Create contract"
|
|
||||||
checked: true
|
|
||||||
exclusiveGroup: contractTypeGroup
|
|
||||||
onClicked: {
|
|
||||||
txFuelRecipient.visible = false
|
|
||||||
txDataLabel.text = "Contract code"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RadioButton {
|
|
||||||
id: runContractRadio
|
|
||||||
text: "Run contract"
|
|
||||||
exclusiveGroup: contractTypeGroup
|
|
||||||
onClicked: {
|
|
||||||
txFuelRecipient.visible = true
|
|
||||||
txDataLabel.text = "Contract arguments"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: txDataLabel
|
|
||||||
text: "Contract code"
|
|
||||||
}
|
|
||||||
|
|
||||||
TextArea {
|
|
||||||
id: codeView
|
|
||||||
height: 300
|
|
||||||
anchors.topMargin: 5
|
|
||||||
Layout.fillWidth: true
|
|
||||||
width: parent.width /2
|
|
||||||
onTextChanged: {
|
|
||||||
contractFormReady()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: txFuelRecipient
|
|
||||||
placeholderText: "Contract address"
|
|
||||||
validator: RegExpValidator { regExp: /[a-f0-9]{40}/ }
|
|
||||||
visible: false
|
|
||||||
width: 530
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: txButton
|
|
||||||
/* enabled: false */
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "READY"
|
|
||||||
PropertyChanges { target: txButton; /*enabled: true*/}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "NOTREADY"
|
|
||||||
PropertyChanges { target: txButton; /*enabled:false*/}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
text: "Send"
|
|
||||||
onClicked: {
|
|
||||||
//this.enabled = false
|
|
||||||
var res = eth.create(txFuelRecipient.text, txValue.text, txGas.text, txGasPrice.text, codeView.text)
|
|
||||||
if(res[1]) {
|
|
||||||
txResult.text = "Your contract <b>could not</b> be send over the network:\n<b>"
|
|
||||||
txResult.text += res[1].error()
|
|
||||||
txResult.text += "</b>"
|
|
||||||
mainContractColumn.state = "ERROR"
|
|
||||||
} else {
|
|
||||||
txResult.text = "Your transaction has been submitted:\n"
|
|
||||||
txOutput.text = res[0].address
|
|
||||||
mainContractColumn.state = "DONE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
id: txResult
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: txOutput
|
|
||||||
visible: false
|
|
||||||
width: 530
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
id: newTxButton
|
|
||||||
visible: false
|
|
||||||
text: "Create an other contract"
|
|
||||||
onClicked: {
|
|
||||||
this.visible = false
|
|
||||||
txResult.text = ""
|
|
||||||
txOutput.text = ""
|
|
||||||
mainContractColumn.state = "SETUP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: debugButton
|
|
||||||
text: "Debug"
|
|
||||||
onClicked: {
|
|
||||||
var res = ui.debugTx("", txValue.text, txGas.text, txGasPrice.text, codeView.text)
|
|
||||||
debugWindow.visible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,112 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: newTransaction
|
|
||||||
Column {
|
|
||||||
id: simpleSendColumn
|
|
||||||
states: [
|
|
||||||
State{
|
|
||||||
name: "ERROR"
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "DONE"
|
|
||||||
PropertyChanges { target: txSimpleValue; visible:false}
|
|
||||||
PropertyChanges { target: txSimpleRecipient; visible:false}
|
|
||||||
PropertyChanges { target:newSimpleTxButton; visible:false}
|
|
||||||
|
|
||||||
PropertyChanges { target: txSimpleResult; visible:true}
|
|
||||||
PropertyChanges { target: txSimpleOutput; visible:true}
|
|
||||||
PropertyChanges { target:newSimpleTxButton; visible:true}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "SETUP"
|
|
||||||
PropertyChanges { target: txSimpleValue; visible:true; text: ""}
|
|
||||||
PropertyChanges { target: txSimpleRecipient; visible:true; text: ""}
|
|
||||||
PropertyChanges { target: txSimpleButton; visible:true}
|
|
||||||
PropertyChanges { target:newSimpleTxButton; visible:false}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
spacing: 5
|
|
||||||
anchors.leftMargin: 5
|
|
||||||
anchors.topMargin: 5
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
|
|
||||||
function checkFormState(){
|
|
||||||
if(txSimpleRecipient.text.length == 40 && txSimpleValue.text.length > 0) {
|
|
||||||
txSimpleButton.state = "READY"
|
|
||||||
}else{
|
|
||||||
txSimpleButton.state = "NOTREADY"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: txSimpleRecipient
|
|
||||||
placeholderText: "Recipient address"
|
|
||||||
Layout.fillWidth: true
|
|
||||||
validator: RegExpValidator { regExp: /[a-f0-9]{40}/ }
|
|
||||||
width: 530
|
|
||||||
onTextChanged: { checkFormState() }
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: txSimpleValue
|
|
||||||
width: 200
|
|
||||||
placeholderText: "Amount"
|
|
||||||
anchors.rightMargin: 5
|
|
||||||
validator: RegExpValidator { regExp: /\d*/ }
|
|
||||||
onTextChanged: { checkFormState() }
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
id: txSimpleButton
|
|
||||||
/*enabled: false*/
|
|
||||||
states: [
|
|
||||||
State {
|
|
||||||
name: "READY"
|
|
||||||
PropertyChanges { target: txSimpleButton; /*enabled: true*/}
|
|
||||||
},
|
|
||||||
State {
|
|
||||||
name: "NOTREADY"
|
|
||||||
PropertyChanges { target: txSimpleButton; /*enabled: false*/}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
text: "Send"
|
|
||||||
onClicked: {
|
|
||||||
//this.enabled = false
|
|
||||||
var res = eth.transact(txSimpleRecipient.text, txSimpleValue.text,"","","")
|
|
||||||
if(res[1]) {
|
|
||||||
txSimpleResult.text = "There has been an error broadcasting your transaction:" + res[1].error()
|
|
||||||
} else {
|
|
||||||
txSimpleResult.text = "Your transaction has been broadcasted over the network.\nYour transaction id is:"
|
|
||||||
txSimpleOutput.text = res[0].hash
|
|
||||||
this.visible = false
|
|
||||||
simpleSendColumn.state = "DONE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
id: txSimpleResult
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: txSimpleOutput
|
|
||||||
visible: false
|
|
||||||
width: 530
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
id: newSimpleTxButton
|
|
||||||
visible: false
|
|
||||||
text: "Create an other transaction"
|
|
||||||
onClicked: {
|
|
||||||
this.visible = false
|
|
||||||
simpleSendColumn.state = "SETUP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -24,11 +24,21 @@ ApplicationWindow {
|
|||||||
shortcut: "Ctrl+o"
|
shortcut: "Ctrl+o"
|
||||||
onTriggered: openAppDialog.open()
|
onTriggered: openAppDialog.open()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "Tools"
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: "Muted"
|
text: "Muted"
|
||||||
shortcut: "Ctrl+e"
|
shortcut: "Ctrl+e"
|
||||||
onTriggered: ui.muted("")
|
onTriggered: ui.muted("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Debugger"
|
||||||
|
shortcut: "Ctrl+d"
|
||||||
|
onTriggered: ui.startDebugger()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
@@ -178,12 +188,6 @@ ApplicationWindow {
|
|||||||
anchors.bottomMargin: 5
|
anchors.bottomMargin: 5
|
||||||
id: newTransactionTab
|
id: newTransactionTab
|
||||||
Component.onCompleted:{
|
Component.onCompleted:{
|
||||||
var component = Qt.createComponent("newTransaction/_simple_send.qml")
|
|
||||||
var newTransaction = component.createObject("newTransaction")
|
|
||||||
|
|
||||||
component = Qt.createComponent("newTransaction/_new_contract.qml")
|
|
||||||
var newContract = component.createObject("newContract")
|
|
||||||
|
|
||||||
addTab("Simple send", newTransaction)
|
addTab("Simple send", newTransaction)
|
||||||
addTab("Contracts", newContract)
|
addTab("Contracts", newContract)
|
||||||
}
|
}
|
||||||
@@ -336,10 +340,8 @@ ApplicationWindow {
|
|||||||
id: popup
|
id: popup
|
||||||
visible: false
|
visible: false
|
||||||
property var block
|
property var block
|
||||||
width: 800
|
width: root.width
|
||||||
height: 280
|
height: 240
|
||||||
x: root.x
|
|
||||||
y: root.y + root.height
|
|
||||||
Component{
|
Component{
|
||||||
id: blockDetailsDelegate
|
id: blockDetailsDelegate
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -385,17 +387,27 @@ ApplicationWindow {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
var tx = transactionModel.get(row)
|
var tx = transactionModel.get(row)
|
||||||
if(tx.data) {
|
if(tx.data) {
|
||||||
popup.showContractData(tx.data)
|
popup.showContractData(tx)
|
||||||
}else{
|
}else{
|
||||||
popup.height = 230
|
popup.height = 230
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function showContractData(data) {
|
|
||||||
contractData.text = data
|
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 = 400
|
popup.height = 400
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: txDetails
|
||||||
width: popup.width
|
width: popup.width
|
||||||
height: 300
|
height: 300
|
||||||
anchors.left: listViewThing.left
|
anchors.left: listViewThing.left
|
||||||
@@ -407,11 +419,28 @@ ApplicationWindow {
|
|||||||
id: contractLabel
|
id: contractLabel
|
||||||
anchors.leftMargin: 10
|
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: {
|
||||||
|
if(tx.createsContract){
|
||||||
|
ui.startDbWithCode(tx.rawData)
|
||||||
|
}else {
|
||||||
|
ui.startDbWithContractAndData(tx.address, tx.rawData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
TextArea {
|
TextArea {
|
||||||
id: contractData
|
id: contractData
|
||||||
text: "Contract"
|
text: "Contract"
|
||||||
anchors.top: contractLabel.bottom
|
anchors.top: contractLabel.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: popup.bottom
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
width: parent.width - 30
|
width: parent.width - 30
|
||||||
height: 80
|
height: 80
|
||||||
@@ -433,7 +462,7 @@ ApplicationWindow {
|
|||||||
transactionModel.insert(0, block.txs.get(i))
|
transactionModel.insert(0, block.txs.get(i))
|
||||||
}
|
}
|
||||||
if(block.txs.get(0).data){
|
if(block.txs.get(0).data){
|
||||||
popup.showContractData(block.txs.get(0).data)
|
popup.showContractData(block.txs.get(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
txView.forceActiveFocus()
|
txView.forceActiveFocus()
|
||||||
@@ -680,4 +709,304 @@ ApplicationWindow {
|
|||||||
var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ;
|
var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ;
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
// *******************************************
|
||||||
|
// Components
|
||||||
|
// *******************************************
|
||||||
|
|
||||||
|
// New Contract component
|
||||||
|
Component {
|
||||||
|
id: newContract
|
||||||
|
Column {
|
||||||
|
id: mainContractColumn
|
||||||
|
function contractFormReady(){
|
||||||
|
if(codeView.text.length > 0 && txValue.text.length > 0 && txGas.text.length > 0 && txGasPrice.length > 0) {
|
||||||
|
txButton.state = "READY"
|
||||||
|
}else{
|
||||||
|
txButton.state = "NOTREADY"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
states: [
|
||||||
|
State{
|
||||||
|
name: "ERROR"
|
||||||
|
PropertyChanges { target: txResult; visible:true}
|
||||||
|
PropertyChanges { target: codeView; visible:true}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "DONE"
|
||||||
|
PropertyChanges { target: txValue; visible:false}
|
||||||
|
PropertyChanges { target: txGas; visible:false}
|
||||||
|
PropertyChanges { target: txGasPrice; visible:false}
|
||||||
|
PropertyChanges { target: codeView; visible:false}
|
||||||
|
PropertyChanges { target: txButton; visible:false}
|
||||||
|
PropertyChanges { target: txDataLabel; visible:false}
|
||||||
|
|
||||||
|
PropertyChanges { target: txResult; visible:true}
|
||||||
|
PropertyChanges { target: txOutput; visible:true}
|
||||||
|
PropertyChanges { target: newTxButton; visible:true}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "SETUP"
|
||||||
|
PropertyChanges { target: txValue; visible:true; text: ""}
|
||||||
|
PropertyChanges { target: txGas; visible:true; text: ""}
|
||||||
|
PropertyChanges { target: txGasPrice; visible:true; text: ""}
|
||||||
|
PropertyChanges { target: codeView; visible:true; text: ""}
|
||||||
|
PropertyChanges { target: txButton; visible:true}
|
||||||
|
PropertyChanges { target: txDataLabel; visible:true}
|
||||||
|
|
||||||
|
PropertyChanges { target: txResult; visible:false}
|
||||||
|
PropertyChanges { target: txOutput; visible:false}
|
||||||
|
PropertyChanges { target: newTxButton; visible:false}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
width: 400
|
||||||
|
spacing: 5
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
anchors.topMargin: 5
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: txValue
|
||||||
|
width: 200
|
||||||
|
placeholderText: "Amount"
|
||||||
|
validator: RegExpValidator { regExp: /\d*/ }
|
||||||
|
onTextChanged: {
|
||||||
|
contractFormReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: txGas
|
||||||
|
width: 200
|
||||||
|
validator: RegExpValidator { regExp: /\d*/ }
|
||||||
|
placeholderText: "Gas"
|
||||||
|
onTextChanged: {
|
||||||
|
contractFormReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: txGasPrice
|
||||||
|
width: 200
|
||||||
|
placeholderText: "Gas price"
|
||||||
|
validator: RegExpValidator { regExp: /\d*/ }
|
||||||
|
onTextChanged: {
|
||||||
|
contractFormReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: rowContract
|
||||||
|
ExclusiveGroup { id: contractTypeGroup }
|
||||||
|
RadioButton {
|
||||||
|
id: createContractRadio
|
||||||
|
text: "Create contract"
|
||||||
|
checked: true
|
||||||
|
exclusiveGroup: contractTypeGroup
|
||||||
|
onClicked: {
|
||||||
|
txFuelRecipient.visible = false
|
||||||
|
txDataLabel.text = "Contract code"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RadioButton {
|
||||||
|
id: runContractRadio
|
||||||
|
text: "Run contract"
|
||||||
|
exclusiveGroup: contractTypeGroup
|
||||||
|
onClicked: {
|
||||||
|
txFuelRecipient.visible = true
|
||||||
|
txDataLabel.text = "Contract arguments"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: txDataLabel
|
||||||
|
text: "Contract code"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
id: codeView
|
||||||
|
height: 300
|
||||||
|
anchors.topMargin: 5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
width: parent.width /2
|
||||||
|
onTextChanged: {
|
||||||
|
contractFormReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: txFuelRecipient
|
||||||
|
placeholderText: "Contract address"
|
||||||
|
validator: RegExpValidator { regExp: /[a-f0-9]{40}/ }
|
||||||
|
visible: false
|
||||||
|
width: 530
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: txButton
|
||||||
|
/* enabled: false */
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "READY"
|
||||||
|
PropertyChanges { target: txButton; /*enabled: true*/}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "NOTREADY"
|
||||||
|
PropertyChanges { target: txButton; /*enabled:false*/}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
text: "Send"
|
||||||
|
onClicked: {
|
||||||
|
//this.enabled = false
|
||||||
|
var res = eth.create(txFuelRecipient.text, txValue.text, txGas.text, txGasPrice.text, codeView.text)
|
||||||
|
if(res[1]) {
|
||||||
|
txResult.text = "Your contract <b>could not</b> be send over the network:\n<b>"
|
||||||
|
txResult.text += res[1].error()
|
||||||
|
txResult.text += "</b>"
|
||||||
|
mainContractColumn.state = "ERROR"
|
||||||
|
} else {
|
||||||
|
txResult.text = "Your transaction has been submitted:\n"
|
||||||
|
txOutput.text = res[0].address
|
||||||
|
mainContractColumn.state = "DONE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: txResult
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: txOutput
|
||||||
|
visible: false
|
||||||
|
width: 530
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: newTxButton
|
||||||
|
visible: false
|
||||||
|
text: "Create an other contract"
|
||||||
|
onClicked: {
|
||||||
|
this.visible = false
|
||||||
|
txResult.text = ""
|
||||||
|
txOutput.text = ""
|
||||||
|
mainContractColumn.state = "SETUP"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: debugButton
|
||||||
|
text: "Debug"
|
||||||
|
onClicked: {
|
||||||
|
var res = ui.debugTx("", txValue.text, txGas.text, txGasPrice.text, codeView.text)
|
||||||
|
debugWindow.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New Transaction component
|
||||||
|
Component {
|
||||||
|
id: newTransaction
|
||||||
|
Column {
|
||||||
|
id: simpleSendColumn
|
||||||
|
states: [
|
||||||
|
State{
|
||||||
|
name: "ERROR"
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "DONE"
|
||||||
|
PropertyChanges { target: txSimpleValue; visible:false}
|
||||||
|
PropertyChanges { target: txSimpleRecipient; visible:false}
|
||||||
|
PropertyChanges { target:newSimpleTxButton; visible:false}
|
||||||
|
|
||||||
|
PropertyChanges { target: txSimpleResult; visible:true}
|
||||||
|
PropertyChanges { target: txSimpleOutput; visible:true}
|
||||||
|
PropertyChanges { target:newSimpleTxButton; visible:true}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "SETUP"
|
||||||
|
PropertyChanges { target: txSimpleValue; visible:true; text: ""}
|
||||||
|
PropertyChanges { target: txSimpleRecipient; visible:true; text: ""}
|
||||||
|
PropertyChanges { target: txSimpleButton; visible:true}
|
||||||
|
PropertyChanges { target:newSimpleTxButton; visible:false}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
spacing: 5
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
|
||||||
|
function checkFormState(){
|
||||||
|
if(txSimpleRecipient.text.length == 40 && txSimpleValue.text.length > 0) {
|
||||||
|
txSimpleButton.state = "READY"
|
||||||
|
}else{
|
||||||
|
txSimpleButton.state = "NOTREADY"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: txSimpleRecipient
|
||||||
|
placeholderText: "Recipient address"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
validator: RegExpValidator { regExp: /[a-f0-9]{40}/ }
|
||||||
|
width: 530
|
||||||
|
onTextChanged: { checkFormState() }
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: txSimpleValue
|
||||||
|
width: 200
|
||||||
|
placeholderText: "Amount"
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
validator: RegExpValidator { regExp: /\d*/ }
|
||||||
|
onTextChanged: { checkFormState() }
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: txSimpleButton
|
||||||
|
/*enabled: false*/
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "READY"
|
||||||
|
PropertyChanges { target: txSimpleButton; /*enabled: true*/}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "NOTREADY"
|
||||||
|
PropertyChanges { target: txSimpleButton; /*enabled: false*/}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
text: "Send"
|
||||||
|
onClicked: {
|
||||||
|
//this.enabled = false
|
||||||
|
var res = eth.transact(txSimpleRecipient.text, txSimpleValue.text,"","","")
|
||||||
|
if(res[1]) {
|
||||||
|
txSimpleResult.text = "There has been an error broadcasting your transaction:" + res[1].error()
|
||||||
|
} else {
|
||||||
|
txSimpleResult.text = "Your transaction has been broadcasted over the network.\nYour transaction id is:"
|
||||||
|
txSimpleOutput.text = res[0].hash
|
||||||
|
this.visible = false
|
||||||
|
simpleSendColumn.state = "DONE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: txSimpleResult
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: txSimpleOutput
|
||||||
|
visible: false
|
||||||
|
width: 530
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: newSimpleTxButton
|
||||||
|
visible: false
|
||||||
|
text: "Create an other transaction"
|
||||||
|
onClicked: {
|
||||||
|
this.visible = false
|
||||||
|
simpleSendColumn.state = "SETUP"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,23 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func formatData(data string) []byte {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Simple stupid
|
||||||
|
d := new(big.Int)
|
||||||
|
if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
|
||||||
|
d.SetBytes([]byte(data[1 : len(data)-1]))
|
||||||
|
} else if data[:2] == "0x" {
|
||||||
|
d.SetBytes(ethutil.FromHex(data[2:]))
|
||||||
|
} else {
|
||||||
|
d.SetString(data, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ethutil.BigToBytes(d, 256)
|
||||||
|
}
|
||||||
|
|
||||||
type DebuggerWindow struct {
|
type DebuggerWindow struct {
|
||||||
win *qml.Window
|
win *qml.Window
|
||||||
engine *qml.Engine
|
engine *qml.Engine
|
||||||
@@ -41,21 +58,18 @@ func (self *DebuggerWindow) Show() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatData(data string) []byte {
|
func (self *DebuggerWindow) SetCode(code string) {
|
||||||
if len(data) == 0 {
|
self.win.Set("codeText", code)
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
// Simple stupid
|
|
||||||
d := new(big.Int)
|
|
||||||
if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
|
|
||||||
d.SetBytes([]byte(data[1 : len(data)-1]))
|
|
||||||
} else if data[:2] == "0x" {
|
|
||||||
d.SetBytes(ethutil.FromHex(data[2:]))
|
|
||||||
} else {
|
|
||||||
d.SetString(data, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ethutil.BigToBytes(d, 256)
|
func (self *DebuggerWindow) SetData(data string) {
|
||||||
|
self.win.Set("dataText", data)
|
||||||
|
}
|
||||||
|
func (self *DebuggerWindow) SetAsm(data string) {
|
||||||
|
dis := ethchain.Disassemble(ethutil.FromHex(data))
|
||||||
|
for _, str := range dis {
|
||||||
|
self.win.Root().Call("setAsm", str)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) {
|
func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) {
|
||||||
@@ -63,22 +77,28 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
|
|||||||
self.Db.Q <- true
|
self.Db.Q <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSlice := strings.Split(dataStr, "\n")
|
|
||||||
var data []byte
|
|
||||||
for _, dataItem := range dataSlice {
|
|
||||||
d := formatData(dataItem)
|
|
||||||
data = append(data, d...)
|
|
||||||
}
|
|
||||||
|
|
||||||
state := self.lib.eth.BlockChain().CurrentBlock.State()
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
|
self.Db.done = true
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
script, err := ethutil.Compile(scriptStr)
|
data := ethutil.StringToByteFunc(dataStr, func(s string) (ret []byte) {
|
||||||
|
slice := strings.Split(dataStr, "\n")
|
||||||
|
for _, dataItem := range slice {
|
||||||
|
d := formatData(dataItem)
|
||||||
|
ret = append(ret, d...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
|
var err error
|
||||||
|
script := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) {
|
||||||
|
ret, err = ethutil.Compile(s)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln(err)
|
ethutil.Config.Log.Debugln(err)
|
||||||
|
|
||||||
@@ -91,11 +111,13 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
|
|||||||
for _, str := range dis {
|
for _, str := range dis {
|
||||||
self.win.Root().Call("setAsm", str)
|
self.win.Root().Call("setAsm", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contract addr as test address
|
// Contract addr as test address
|
||||||
keyPair := ethutil.GetKeyRing().Get(0)
|
keyPair := ethutil.GetKeyRing().Get(0)
|
||||||
callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), script)
|
callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), script)
|
||||||
callerTx.Sign(keyPair.PrivateKey)
|
callerTx.Sign(keyPair.PrivateKey)
|
||||||
|
|
||||||
|
state := self.lib.eth.BlockChain().CurrentBlock.State()
|
||||||
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
|
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
|
||||||
contract := ethchain.MakeContract(callerTx, state)
|
contract := ethchain.MakeContract(callerTx, state)
|
||||||
callerClosure := ethchain.NewClosure(account, contract, script, state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr))
|
callerClosure := ethchain.NewClosure(account, contract, script, state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr))
|
||||||
|
@@ -54,7 +54,7 @@ func New(ethereum *eth.Ethereum) *Gui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) Start(assetPath string) {
|
func (gui *Gui) Start(assetPath string) {
|
||||||
const version = "0.5.0 RC10"
|
const version = "0.5.0 RC11"
|
||||||
|
|
||||||
defer gui.txDb.Close()
|
defer gui.txDb.Close()
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@ type UiLib struct {
|
|||||||
// The main application window
|
// The main application window
|
||||||
win *qml.Window
|
win *qml.Window
|
||||||
Db *Debugger
|
Db *Debugger
|
||||||
|
DbWindow *DebuggerWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
|
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
|
||||||
@@ -88,9 +89,26 @@ func (ui *UiLib) ConnectToPeer(addr string) {
|
|||||||
func (ui *UiLib) AssetPath(p string) string {
|
func (ui *UiLib) AssetPath(p string) string {
|
||||||
return path.Join(ui.assetPath, p)
|
return path.Join(ui.assetPath, p)
|
||||||
}
|
}
|
||||||
|
func (self *UiLib) StartDbWithContractAndData(contractHash, data string) {
|
||||||
|
dbWindow := NewDebuggerWindow(self)
|
||||||
|
object := self.eth.StateManager().CurrentState().GetStateObject(ethutil.FromHex(contractHash))
|
||||||
|
if len(object.Script()) > 0 {
|
||||||
|
dbWindow.SetCode("0x" + ethutil.Hex(object.Script()))
|
||||||
|
}
|
||||||
|
dbWindow.SetData(data)
|
||||||
|
|
||||||
|
dbWindow.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *UiLib) StartDbWithCode(code string) {
|
||||||
|
dbWindow := NewDebuggerWindow(self)
|
||||||
|
dbWindow.SetCode("0x" + code)
|
||||||
|
dbWindow.Show()
|
||||||
|
}
|
||||||
|
|
||||||
func (self *UiLib) StartDebugger() {
|
func (self *UiLib) StartDebugger() {
|
||||||
dbWindow := NewDebuggerWindow(self)
|
dbWindow := NewDebuggerWindow(self)
|
||||||
|
//self.DbWindow = dbWindow
|
||||||
|
|
||||||
dbWindow.Show()
|
dbWindow.Show()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user