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.
|
||||
|
||||
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).
|
||||
|
||||
|
@@ -14,6 +14,26 @@ ApplicationWindow {
|
||||
width: 1290
|
||||
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 {
|
||||
anchors.fill: parent
|
||||
property var asmModel: ListModel {
|
||||
@@ -150,6 +170,7 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toolBar: ToolBar {
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
@@ -158,7 +179,7 @@ ApplicationWindow {
|
||||
property var enabled: true
|
||||
id: debugStart
|
||||
onClicked: {
|
||||
dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text, rawDataField.text)
|
||||
debugCurrent()
|
||||
}
|
||||
text: "Debug"
|
||||
}
|
||||
@@ -174,6 +195,10 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
function debugCurrent() {
|
||||
dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text, rawDataField.text)
|
||||
}
|
||||
|
||||
function setAsm(asm) {
|
||||
asmModel.append({asm: asm})
|
||||
}
|
||||
@@ -184,7 +209,7 @@ ApplicationWindow {
|
||||
|
||||
function setInstruction(num) {
|
||||
asmTableView.selection.clear()
|
||||
asmTableView.selection.select(num-1)
|
||||
asmTableView.selection.select(num)
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,23 @@ import (
|
||||
"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 {
|
||||
win *qml.Window
|
||||
engine *qml.Engine
|
||||
@@ -41,21 +58,18 @@ func (self *DebuggerWindow) Show() {
|
||||
}()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
func (self *DebuggerWindow) SetCode(code string) {
|
||||
self.win.Set("codeText", code)
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -63,22 +77,28 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
|
||||
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() {
|
||||
if r := recover(); r != nil {
|
||||
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 {
|
||||
ethutil.Config.Log.Debugln(err)
|
||||
|
||||
@@ -91,11 +111,13 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
|
||||
for _, str := range dis {
|
||||
self.win.Root().Call("setAsm", str)
|
||||
}
|
||||
|
||||
// Contract addr as test address
|
||||
keyPair := ethutil.GetKeyRing().Get(0)
|
||||
callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), script)
|
||||
callerTx.Sign(keyPair.PrivateKey)
|
||||
|
||||
state := self.lib.eth.BlockChain().CurrentBlock.State()
|
||||
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
|
||||
contract := ethchain.MakeContract(callerTx, state)
|
||||
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) {
|
||||
const version = "0.5.0 RC10"
|
||||
const version = "0.5.0 RC11"
|
||||
|
||||
defer gui.txDb.Close()
|
||||
|
||||
|
@@ -24,8 +24,9 @@ type UiLib struct {
|
||||
connected bool
|
||||
assetPath string
|
||||
// The main application window
|
||||
win *qml.Window
|
||||
Db *Debugger
|
||||
win *qml.Window
|
||||
Db *Debugger
|
||||
DbWindow *DebuggerWindow
|
||||
}
|
||||
|
||||
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 {
|
||||
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() {
|
||||
dbWindow := NewDebuggerWindow(self)
|
||||
//self.DbWindow = dbWindow
|
||||
|
||||
dbWindow.Show()
|
||||
}
|
||||
|
Reference in New Issue
Block a user