Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
50fdfb12
Commit
50fdfb12
authored
Jun 14, 2014
by
zelig
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of github.com:ethereum/go-ethereum into develop
parents
72df038d
1d300bbc
Changes
19
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1392 additions
and
595 deletions
+1392
-595
README.md
README.md
+8
-6
debugger.qml
ethereal/assets/debugger/debugger.qml
+264
-0
ethereum.js
ethereal/assets/ext/ethereum.js
+4
-0
heart.png
ethereal/assets/heart.png
+0
-0
_new_contract.qml
ethereal/assets/qml/newTransaction/_new_contract.qml
+0
-196
_simple_send.qml
ethereal/assets/qml/newTransaction/_simple_send.qml
+0
-112
wallet.qml
ethereal/assets/qml/wallet.qml
+624
-182
webapp.qml
ethereal/assets/qml/webapp.qml
+30
-1
samplecoin.html
ethereal/assets/samplecoin/samplecoin.html
+1
-1
config.go
ethereal/config.go
+14
-13
ethereum.go
ethereal/ethereum.go
+17
-4
debugger.go
ethereal/ui/debugger.go
+225
-0
gui.go
ethereal/ui/gui.go
+109
-18
ui_lib.go
ethereal/ui/ui_lib.go
+38
-48
config.go
ethereum/config.go
+12
-10
ethereum.go
ethereum/ethereum.go
+11
-1
javascript_runtime.go
ethereum/javascript_runtime.go
+19
-0
repl.go
ethereum/repl.go
+9
-1
cmd.go
utils/cmd.go
+7
-2
No files found.
README.md
View file @
50fdfb12
...
...
@@ -5,7 +5,7 @@ Ethereum
Ethereum Go Client © 2014 Jeffrey Wilcke.
Current state: Proof of Concept 5.0 RC
8
.
Current state: Proof of Concept 5.0 RC
12
.
For the development package please see the
[
eth-go package
](
https://github.com/ethereum/eth-go
)
.
...
...
@@ -27,20 +27,22 @@ General command line options
```
Shared between ethereum and ethereal
-m Start mining blocks
-genaddr Generates a new address and private key (destructive action)
-p Port on which the server will accept incomming connections
-id Set the custom identifier of the client (shows up on other clients)
-port Port on which the server will accept incomming connections
-upnp Enable UPnP
-x Desired amount of peers
-r Start JSON RPC
-maxpeer Desired amount of peers
-rpc Start JSON RPC
-dir Data directory used to store configs and databases
-import Import a private key
-genaddr Generates a new address and private key (destructive action)
-h This
Ethereum only
ethereum [options] [filename]
-js Start the JavaScript REPL
filename Load the given file and interpret as JavaScript
-m Start mining blocks
Etheral only
-asset_path absolute path to GUI assets directory
...
...
ethereal/assets/debugger/debugger.qml
0 → 100644
View file @
50fdfb12
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
ApplicationWindow
{
visible
:
false
title
:
"IceCREAM"
minimumWidth
:
1280
minimumHeight
:
900
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
{
id
:
asmModel
}
TableView
{
id
:
asmTableView
width
:
200
TableViewColumn
{
role
:
"value"
;
title
:
""
;
width
:
100
}
model
:
asmModel
}
Rectangle
{
color
:
"#00000000"
anchors.left
:
asmTableView
.
right
anchors.right
:
parent
.
right
SplitView
{
orientation
:
Qt
.
Vertical
anchors.fill
:
parent
Rectangle
{
color
:
"#00000000"
height
:
500
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
TextArea
{
id
:
codeEditor
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
anchors.left
:
parent
.
left
anchors.right
:
settings
.
left
}
Column
{
id
:
settings
spacing
:
5
width
:
300
height
:
parent
.
height
anchors.right
:
parent
.
right
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
Label
{
text
:
"Arbitrary data"
}
TextArea
{
id
:
rawDataField
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
height
:
150
}
Label
{
text
:
"Amount"
}
TextField
{
id
:
txValue
width
:
200
placeholderText
:
"Amount"
validator
:
RegExpValidator
{
regExp
:
/
\d
*/
}
}
Label
{
text
:
"Amount of gas"
}
TextField
{
id
:
txGas
width
:
200
validator
:
RegExpValidator
{
regExp
:
/
\d
*/
}
text
:
"10000"
placeholderText
:
"Gas"
}
Label
{
text
:
"Gas price"
}
TextField
{
id
:
txGasPrice
width
:
200
placeholderText
:
"Gas price"
text
:
"1000000000000"
validator
:
RegExpValidator
{
regExp
:
/
\d
*/
}
}
}
}
SplitView
{
orientation
:
Qt
.
Vertical
id
:
inspectorPane
height
:
500
SplitView
{
orientation
:
Qt
.
Horizontal
height
:
150
TableView
{
id
:
stackTableView
property
var
stackModel
:
ListModel
{
id
:
stackModel
}
height
:
parent
.
height
width
:
300
TableViewColumn
{
role
:
"value"
;
title
:
"Stack"
;
width
:
200
}
model
:
stackModel
}
TableView
{
id
:
memoryTableView
property
var
memModel
:
ListModel
{
id
:
memModel
}
height
:
parent
.
height
width
:
parent
.
width
-
stackTableView
.
width
TableViewColumn
{
id
:
mnumColmn
;
role
:
"num"
;
title
:
"#"
;
width
:
50
}
TableViewColumn
{
role
:
"value"
;
title
:
"Memory"
;
width
:
750
}
model
:
memModel
}
}
Rectangle
{
height
:
100
width
:
parent
.
width
TableView
{
id
:
storageTableView
property
var
memModel
:
ListModel
{
id
:
storageModel
}
height
:
parent
.
height
width
:
parent
.
width
TableViewColumn
{
id
:
key
;
role
:
"key"
;
title
:
"#"
;
width
:
storageTableView
.
width
/
2
}
TableViewColumn
{
role
:
"value"
;
title
:
"Storage"
;
width
:
storageTableView
.
width
/
2
}
model
:
storageModel
}
}
Rectangle
{
height
:
200
width
:
parent
.
width
TableView
{
id
:
logTableView
property
var
logModel
:
ListModel
{
id
:
logModel
}
height
:
parent
.
height
width
:
parent
.
width
TableViewColumn
{
id
:
message
;
role
:
"message"
;
title
:
"log"
;
width
:
logTableView
.
width
}
model
:
logModel
}
}
}
}
}
}
toolBar
:
ToolBar
{
RowLayout
{
spacing
:
5
Button
{
property
var
enabled
:
true
id
:
debugStart
onClicked
:
{
debugCurrent
()
}
text
:
"Debug"
}
Button
{
property
var
enabled
:
true
id
:
debugNextButton
onClicked
:
{
dbg
.
next
()
}
text
:
"Next"
}
}
}
function
debugCurrent
()
{
dbg
.
debug
(
txValue
.
text
,
txGas
.
text
,
txGasPrice
.
text
,
codeEditor
.
text
,
rawDataField
.
text
)
}
function
setAsm
(
asm
)
{
asmModel
.
append
({
asm
:
asm
})
}
function
clearAsm
()
{
asmModel
.
clear
()
}
function
setInstruction
(
num
)
{
//asmTableView.selection.clear()
//asmTableView.selection.select(num)
}
function
setMem
(
mem
)
{
memModel
.
append
({
num
:
mem
.
num
,
value
:
mem
.
value
})
}
function
clearMem
(){
memModel
.
clear
()
}
function
setStack
(
stack
)
{
stackModel
.
append
({
value
:
stack
})
}
function
addDebugMessage
(
message
){
debuggerLog
.
append
({
value
:
message
})
}
function
clearStack
()
{
stackModel
.
clear
()
}
function
clearStorage
()
{
storageModel
.
clear
()
}
function
setStorage
(
storage
)
{
storageModel
.
append
({
key
:
storage
.
key
,
value
:
storage
.
value
})
}
function
setLog
(
msg
)
{
logModel
.
insert
(
0
,
{
message
:
msg
})
}
function
clearLog
()
{
logModel
.
clear
()
}
}
ethereal/assets/ext/ethereum.js
View file @
50fdfb12
...
...
@@ -32,6 +32,10 @@ window.eth = {
postData
({
call
:
"getStorage"
,
args
:
[
address
,
storageAddress
]},
cb
);
},
getStateKeyVals
:
function
(
address
,
cb
){
postData
({
call
:
"getStateKeyVals"
,
args
:
[
address
]},
cb
);
},
getKey
:
function
(
cb
)
{
postData
({
call
:
"getKey"
},
cb
);
},
...
...
ethereal/assets/heart.png
0 → 100644
View file @
50fdfb12
4.18 KB
ethereal/assets/qml/newTransaction/_new_contract.qml
deleted
100644 → 0
View file @
72df038d
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
}
}
}
}
ethereal/assets/qml/newTransaction/_simple_send.qml
deleted
100644 → 0
View file @
72df038d
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.
\n
Your 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"
}
}
}
}
ethereal/assets/qml/wallet.qml
View file @
50fdfb12
This diff is collapsed.
Click to expand it.
ethereal/assets/qml/webapp.qml
View file @
50fdfb12
...
...
@@ -34,7 +34,6 @@ ApplicationWindow {
top: parent.top
}
*/
onTitleChanged
:
{
window
.
title
=
title
}
experimental.preferences.javascriptEnabled
:
true
experimental.preferences.navigatorQtObjectEnabled
:
true
...
...
@@ -97,6 +96,12 @@ ApplicationWindow {
var
storage
=
stateObject
.
getStorage
(
data
.
args
[
1
])
postData
(
data
.
_seed
,
storage
)
break
case
"getStateKeyVals"
:
require
(
1
);
var
stateObject
=
eth
.
getStateObject
(
data
.
args
[
0
]).
stateKeyVal
(
true
)
postData
(
data
.
_seed
,
stateObject
)
break
case
"getBalance"
:
require
(
1
);
...
...
@@ -165,6 +170,30 @@ ApplicationWindow {
postEvent
(
ev
,
[
storageObject
.
address
,
storageObject
.
value
])
}
}
Rectangle
{
id
:
toggleInspector
color
:
"#bcbcbc"
visible
:
true
height
:
12
width
:
12
anchors
{
right
:
root
.
right
}
MouseArea
{
onClicked
:
{
if
(
inspector
.
visible
==
true
){
inspector
.
visible
=
false
}
else
{
inspector
.
visible
=
true
}
}
onDoubleClicked
:
{
console
.
log
(
'refreshing'
)
webView
.
reload
()
}
anchors.fill
:
parent
}
}
Rectangle
{
id
:
sizeGrip
...
...
ethereal/assets/samplecoin/samplecoin.html
View file @
50fdfb12
...
...
@@ -9,7 +9,7 @@
<script
type=
"text/javascript"
>
var
jefcoinAddr
=
"
fc0a9436890478bb9b1c6ed7455c2535366f4a99
"
var
jefcoinAddr
=
"
de0bd4ea1947deabf1749d7ed633f289358c9f6c
"
var
mAddr
=
""
function
createTransaction
()
{
...
...
ethereal/config.go
View file @
50fdfb12
...
...
@@ -5,8 +5,8 @@ import (
)
var
Identifier
string
var
StartConsole
bool
var
StartMining
bool
//
var StartMining bool
var
StartRpc
bool
var
RpcPort
int
var
UseUPnP
bool
...
...
@@ -18,25 +18,26 @@ var GenAddr bool
var
UseSeed
bool
var
ImportKey
string
var
ExportKey
bool
var
DataDir
string
var
AssetPath
string
var
Datadir
string
func
Init
()
{
flag
.
StringVar
(
&
Identifier
,
"i"
,
""
,
"Custom client identifier"
)
flag
.
BoolVar
(
&
StartConsole
,
"c"
,
false
,
"debug and testing console"
)
flag
.
BoolVar
(
&
StartMining
,
"m"
,
false
,
"start dagger mining"
)
flag
.
BoolVar
(
&
StartRpc
,
"r"
,
false
,
"start rpc server"
)
flag
.
BoolVar
(
&
ShowGenesis
,
"g"
,
false
,
"prints genesis header and exits"
)
flag
.
StringVar
(
&
Identifier
,
"id"
,
""
,
"Custom client identifier"
)
flag
.
StringVar
(
&
OutboundPort
,
"port"
,
"30303"
,
"listening port"
)
flag
.
BoolVar
(
&
UseUPnP
,
"upnp"
,
false
,
"enable UPnP support"
)
flag
.
IntVar
(
&
MaxPeer
,
"maxpeer"
,
10
,
"maximum desired peers"
)
flag
.
IntVar
(
&
RpcPort
,
"rpcport"
,
8080
,
"port to start json-rpc server on"
)
flag
.
BoolVar
(
&
StartRpc
,
"rpc"
,
false
,
"start rpc server"
)
flag
.
StringVar
(
&
AssetPath
,
"asset_path"
,
""
,
"absolute path to GUI assets directory"
)
flag
.
BoolVar
(
&
ShowGenesis
,
"genesis"
,
false
,
"prints genesis header and exits"
)
flag
.
BoolVar
(
&
UseSeed
,
"seed"
,
true
,
"seed peers"
)
flag
.
BoolVar
(
&
GenAddr
,
"genaddr"
,
false
,
"create a new priv/pub key"
)
flag
.
BoolVar
(
&
ExportKey
,
"export"
,
false
,
"export private key"
)
flag
.
IntVar
(
&
RpcPort
,
"rpcport"
,
8080
,
"port to start json-rpc server on"
)
flag
.
StringVar
(
&
OutboundPort
,
"p"
,
"30303"
,
"listening port"
)
flag
.
StringVar
(
&
DataDir
,
"dir"
,
".ethereal"
,
"ethereum data directory"
)
flag
.
StringVar
(
&
ImportKey
,
"import"
,
""
,
"imports the given private key (hex)"
)
flag
.
IntVar
(
&
MaxPeer
,
"x"
,
10
,
"maximum desired peers"
)
flag
.
StringVar
(
&
AssetPath
,
"asset_path"
,
""
,
"absolute path to GUI assets directory
"
)
flag
.
StringVar
(
&
Datadir
,
"datadir"
,
".ethereal"
,
"specifies the datadir to use. Takes precedence over config file.
"
)
flag
.
Parse
()
}
ethereal/ethereum.go
View file @
50fdfb12
...
...
@@ -8,9 +8,11 @@ import (
"github.com/ethereum/go-ethereum/ethereal/ui"
"github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
"github.com/rakyll/globalconf"
"log"
"os"
"os/signal"
"path"
"runtime"
)
...
...
@@ -39,7 +41,16 @@ func main() {
runtime
.
GOMAXPROCS
(
runtime
.
NumCPU
())
ethchain
.
InitFees
()
ethutil
.
ReadConfig
(
DataDir
,
ethutil
.
LogFile
|
ethutil
.
LogStd
,
Identifier
)
g
,
err
:=
globalconf
.
NewWithOptions
(
&
globalconf
.
Options
{
Filename
:
path
.
Join
(
ethutil
.
ApplicationFolder
(
Datadir
),
"conf.ini"
),
})
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
else
{
g
.
ParseAll
()
}
ethutil
.
ReadConfig
(
Datadir
,
ethutil
.
LogFile
|
ethutil
.
LogStd
,
g
,
Identifier
)
// Instantiated a eth stack
ethereum
,
err
:=
eth
.
New
(
eth
.
CapDefault
,
UseUPnP
)
...
...
@@ -108,9 +119,11 @@ save these words so you can restore your account later: %s
os
.
Exit
(
0
)
}
/*
if StartMining {
utils.DoMining(ethereum)
}
*/
if
StartRpc
{
utils
.
DoRpc
(
ethereum
,
RpcPort
)
...
...
ethereal/ui/debugger.go
0 → 100644
View file @
50fdfb12
package
ethui
import
(
"fmt"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml"
"math/big"
"strings"
)
type
DebuggerWindow
struct
{
win
*
qml
.
Window
engine
*
qml
.
Engine
lib
*
UiLib
Db
*
Debugger
}
func
NewDebuggerWindow
(
lib
*
UiLib
)
*
DebuggerWindow
{
engine
:=
qml
.
NewEngine
()
component
,
err
:=
engine
.
LoadFile
(
lib
.
AssetPath
(
"debugger/debugger.qml"
))
if
err
!=
nil
{
fmt
.
Println
(
err
)
return
nil
}
win
:=
component
.
CreateWindow
(
nil
)
db
:=
&
Debugger
{
win
,
make
(
chan
bool
),
make
(
chan
bool
),
true
,
false
}
return
&
DebuggerWindow
{
engine
:
engine
,
win
:
win
,
lib
:
lib
,
Db
:
db
}
}
func
(
self
*
DebuggerWindow
)
Show
()
{
context
:=
self
.
engine
.
Context
()
context
.
SetVar
(
"dbg"
,
self
)
go
func
()
{
self
.
win
.
Show
()
self
.
win
.
Wait
()
}()
}
func
(
self
*
DebuggerWindow
)
SetCode
(
code
string
)
{
self
.
win
.
Set
(
"codeText"
,
code
)
}
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
)
{
if
!
self
.
Db
.
done
{
self
.
Db
.
Q
<-
true
}
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
self
.
Logf
(
"compile FAULT: %v"
,
r
)
}
}()
data
:=
ethutil
.
StringToByteFunc
(
dataStr
,
func
(
s
string
)
(
ret
[]
byte
)
{
slice
:=
strings
.
Split
(
dataStr
,
"
\n
"
)
for
_
,
dataItem
:=
range
slice
{
d
:=
ethutil
.
FormatData
(
dataItem
)
ret
=
append
(
ret
,
d
...
)
}
return
})
var
err
error
script
:=
ethutil
.
StringToByteFunc
(
scriptStr
,
func
(
s
string
)
(
ret
[]
byte
)
{
ret
,
err
=
ethutil
.
Compile
(
s
)
fmt
.
Printf
(
"%x
\n
"
,
ret
)
return
})
if
err
!=
nil
{
self
.
Logln
(
err
)
return
}
dis
:=
ethchain
.
Disassemble
(
script
)
self
.
win
.
Root
()
.
Call
(
"clearAsm"
)
self
.
win
.
Root
()
.
Call
(
"clearLog"
)
for
_
,
str
:=
range
dis
{
self
.
win
.
Root
()
.
Call
(
"setAsm"
,
str
)
}
gas
:=
ethutil
.
Big
(
gasStr
)
gasPrice
:=
ethutil
.
Big
(
gasPriceStr
)
// Contract addr as test address
keyPair
:=
ethutil
.
GetKeyRing
()
.
Get
(
0
)
callerTx
:=
ethchain
.
NewContractCreationTx
(
ethutil
.
Big
(
valueStr
),
gas
,
gasPrice
,
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
,
gas
,
gasPrice
)
block
:=
self
.
lib
.
eth
.
BlockChain
()
.
CurrentBlock
vm
:=
ethchain
.
NewVm
(
state
,
self
.
lib
.
eth
.
StateManager
(),
ethchain
.
RuntimeVars
{
Origin
:
account
.
Address
(),
BlockNumber
:
block
.
BlockInfo
()
.
Number
,
PrevHash
:
block
.
PrevHash
,
Coinbase
:
block
.
Coinbase
,
Time
:
block
.
Time
,
Diff
:
block
.
Difficulty
,
Value
:
ethutil
.
Big
(
valueStr
),
})
self
.
Db
.
done
=
false
self
.
Logf
(
"callsize %d"
,
len
(
script
))
go
func
()
{
ret
,
g
,
err
:=
callerClosure
.
Call
(
vm
,
data
,
self
.
Db
.
halting
)
tot
:=
new
(
big
.
Int
)
.
Mul
(
g
,
gasPrice
)
self
.
Logf
(
"gas usage %v total price = %v (%v)"
,
g
,
tot
,
ethutil
.
CurrencyToString
(
tot
))
if
err
!=
nil
{
self
.
Logln
(
"exited with errors:"
,
err
)
}
else
{
if
len
(
ret
)
>
0
{
self
.
Logf
(
"exited: % x"
,
ret
)
}
else
{
self
.
Logf
(
"exited: nil"
)
}
}
state
.
Reset
()
if
!
self
.
Db
.
interrupt
{
self
.
Db
.
done
=
true
}
else
{
self
.
Db
.
interrupt
=
false
}
}()
}
func
(
self
*
DebuggerWindow
)
Logf
(
format
string
,
v
...
interface
{})
{
self
.
win
.
Root
()
.
Call
(
"setLog"
,
fmt
.
Sprintf
(
format
,
v
...
))
}
func
(
self
*
DebuggerWindow
)
Logln
(
v
...
interface
{})
{
str
:=
fmt
.
Sprintln
(
v
...
)
self
.
Logf
(
"%s"
,
str
[
:
len
(
str
)
-
1
])
}
func
(
self
*
DebuggerWindow
)
Next
()
{
self
.
Db
.
Next
()
}
type
Debugger
struct
{
win
*
qml
.
Window
N
chan
bool
Q
chan
bool
done
,
interrupt
bool
}
type
storeVal
struct
{
Key
,
Value
string
}
func
(
d
*
Debugger
)
halting
(
pc
int
,
op
ethchain
.
OpCode
,
mem
*
ethchain
.
Memory
,
stack
*
ethchain
.
Stack
,
stateObject
*
ethchain
.
StateObject
)
bool
{
d
.
win
.
Root
()
.
Call
(
"setInstruction"
,
pc
)
d
.
win
.
Root
()
.
Call
(
"clearMem"
)
d
.
win
.
Root
()
.
Call
(
"clearStack"
)
d
.
win
.
Root
()
.
Call
(
"clearStorage"
)
addr
:=
0
for
i
:=
0
;
i
+
32
<=
mem
.
Len
();
i
+=
32
{
d
.
win
.
Root
()
.
Call
(
"setMem"
,
memAddr
{
fmt
.
Sprintf
(
"%03d"
,
addr
),
fmt
.
Sprintf
(
"% x"
,
mem
.
Data
()[
i
:
i
+
32
])})
addr
++
}
for
_
,
val
:=
range
stack
.
Data
()
{
d
.
win
.
Root
()
.
Call
(
"setStack"
,
val
.
String
())
}
stateObject
.
State
()
.
EachStorage
(
func
(
key
string
,
node
*
ethutil
.
Value
)
{
d
.
win
.
Root
()
.
Call
(
"setStorage"
,
storeVal
{
fmt
.
Sprintf
(
"% x"
,
key
),
fmt
.
Sprintf
(
"% x"
,
node
.
Str
())})
})
out
:
for
{
select
{
case
<-
d
.
N
:
break
out
case
<-
d
.
Q
:
d
.
interrupt
=
true
d
.
clearBuffers
()
return
false
}
}
return
true
}
func
(
d
*
Debugger
)
clearBuffers
()
{
out
:
// drain
for
{
select
{
case
<-
d
.
N
:
case
<-
d
.
Q
:
default
:
break
out
}
}
}
func
(
d
*
Debugger
)
Next
()
{
if
!
d
.
done
{
d
.
N
<-
true
}
}
ethereal/ui/gui.go
View file @
50fdfb12
...
...
@@ -8,9 +8,11 @@ import (
"github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
"math/big"
"strings"
"time"
)
type
Gui
struct
{
...
...
@@ -54,7 +56,7 @@ func New(ethereum *eth.Ethereum) *Gui {
}
func
(
gui
*
Gui
)
Start
(
assetPath
string
)
{
const
version
=
"0.5.0 RC
8
"
const
version
=
"0.5.0 RC
12
"
defer
gui
.
txDb
.
Close
()
...
...
@@ -63,10 +65,12 @@ func (gui *Gui) Start(assetPath string) {
Init
:
func
(
p
*
ethpub
.
PBlock
,
obj
qml
.
Object
)
{
p
.
Number
=
0
;
p
.
Hash
=
""
},
},
{
Init
:
func
(
p
*
ethpub
.
PTx
,
obj
qml
.
Object
)
{
p
.
Value
=
""
;
p
.
Hash
=
""
;
p
.
Address
=
""
},
},
{
Init
:
func
(
p
*
ethpub
.
KeyVal
,
obj
qml
.
Object
)
{
p
.
Key
=
""
;
p
.
Value
=
""
},
}})
ethutil
.
Config
.
SetClientString
(
fmt
.
Sprintf
(
"/Ethereal v%s"
,
version
))
ethutil
.
Config
.
Log
.
Infoln
(
"[GUI] Starting GUI"
)
// Create a new QML engine
gui
.
engine
=
qml
.
NewEngine
()
context
:=
gui
.
engine
.
Context
()
...
...
@@ -86,19 +90,36 @@ func (gui *Gui) Start(assetPath string) {
win
,
err
=
gui
.
showKeyImport
(
context
)
}
else
{
win
,
err
=
gui
.
showWallet
(
context
)
ethutil
.
Config
.
Log
.
AddLogSystem
(
gui
)
}
if
err
!=
nil
{
ethutil
.
Config
.
Log
.
Infoln
(
"FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'"
)
ethutil
.
Config
.
Log
.
Infoln
(
"FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'"
,
err
)
panic
(
err
)
}
ethutil
.
Config
.
Log
.
Infoln
(
"[GUI] Starting GUI"
)
win
.
Show
()
win
.
Wait
()
gui
.
eth
.
Stop
()
}
func
(
gui
*
Gui
)
ToggleMining
()
{
var
txt
string
if
gui
.
eth
.
Mining
{
utils
.
StopMining
(
gui
.
eth
)
txt
=
"Start mining"
}
else
{
utils
.
StartMining
(
gui
.
eth
)
txt
=
"Stop mining"
}
gui
.
win
.
Root
()
.
Set
(
"miningButtonText"
,
txt
)
}
func
(
gui
*
Gui
)
showWallet
(
context
*
qml
.
Context
)
(
*
qml
.
Window
,
error
)
{
component
,
err
:=
gui
.
engine
.
LoadFile
(
gui
.
uiLib
.
AssetPath
(
"qml/wallet.qml"
))
if
err
!=
nil
{
...
...
@@ -107,8 +128,11 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
win
:=
gui
.
createWindow
(
component
)
go
gui
.
setInitialBlockChain
()
go
gui
.
readPreviousTransactions
()
gui
.
setInitialBlockChain
()
gui
.
loadAddressBook
()
gui
.
readPreviousTransactions
()
gui
.
setPeerInfo
()
go
gui
.
update
()
return
win
,
nil
...
...
@@ -130,20 +154,46 @@ func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
gui
.
win
=
win
gui
.
uiLib
.
win
=
win
db
:=
&
Debugger
{
gui
.
win
,
make
(
chan
bool
)}
db
:=
&
Debugger
{
gui
.
win
,
make
(
chan
bool
)
,
make
(
chan
bool
),
true
,
false
}
gui
.
lib
.
Db
=
db
gui
.
uiLib
.
Db
=
db
return
gui
.
win
}
func
(
gui
*
Gui
)
setInitialBlockChain
()
{
// Load previous 10 blocks
chain
:=
gui
.
eth
.
BlockChain
()
.
GetChain
(
gui
.
eth
.
BlockChain
()
.
CurrentBlock
.
Hash
(),
10
)
for
_
,
block
:=
range
chain
{
gui
.
processBlock
(
block
)
sBlk
:=
gui
.
eth
.
BlockChain
()
.
LastBlockHash
blk
:=
gui
.
eth
.
BlockChain
()
.
GetBlock
(
sBlk
)
for
;
blk
!=
nil
;
blk
=
gui
.
eth
.
BlockChain
()
.
GetBlock
(
sBlk
)
{
sBlk
=
blk
.
PrevHash
// Loop through all transactions to see if we missed any while being offline
for
_
,
tx
:=
range
blk
.
Transactions
()
{
if
bytes
.
Compare
(
tx
.
Sender
(),
gui
.
addr
)
==
0
||
bytes
.
Compare
(
tx
.
Recipient
,
gui
.
addr
)
==
0
{
if
ok
,
_
:=
gui
.
txDb
.
Get
(
tx
.
Hash
());
ok
==
nil
{
gui
.
txDb
.
Put
(
tx
.
Hash
(),
tx
.
RlpEncode
())
}
}
}
gui
.
processBlock
(
blk
,
true
)
}
}
type
address
struct
{
Name
,
Address
string
}
var
namereg
=
ethutil
.
FromHex
(
"bb5f186604d057c1c5240ca2ae0f6430138ac010"
)
func
(
gui
*
Gui
)
loadAddressBook
()
{
gui
.
win
.
Root
()
.
Call
(
"clearAddress"
)
stateObject
:=
gui
.
eth
.
StateManager
()
.
CurrentState
()
.
GetStateObject
(
namereg
)
if
stateObject
!=
nil
{
stateObject
.
State
()
.
EachStorage
(
func
(
name
string
,
value
*
ethutil
.
Value
)
{
gui
.
win
.
Root
()
.
Call
(
"addAddress"
,
struct
{
Name
,
Address
string
}{
name
,
ethutil
.
Hex
(
value
.
Bytes
())})
})
}
}
func
(
gui
*
Gui
)
readPreviousTransactions
()
{
...
...
@@ -151,13 +201,21 @@ func (gui *Gui) readPreviousTransactions() {
for
it
.
Next
()
{
tx
:=
ethchain
.
NewTransactionFromBytes
(
it
.
Value
())
gui
.
win
.
Root
()
.
Call
(
"addTx"
,
ethpub
.
NewPTx
(
tx
))
var
inout
string
if
bytes
.
Compare
(
tx
.
Sender
(),
gui
.
addr
)
==
0
{
inout
=
"send"
}
else
{
inout
=
"recv"
}
gui
.
win
.
Root
()
.
Call
(
"addTx"
,
ethpub
.
NewPTx
(
tx
),
inout
)
}
it
.
Release
()
}
func
(
gui
*
Gui
)
processBlock
(
block
*
ethchain
.
Block
)
{
gui
.
win
.
Root
()
.
Call
(
"addBlock"
,
ethpub
.
NewPBlock
(
block
))
func
(
gui
*
Gui
)
processBlock
(
block
*
ethchain
.
Block
,
initial
bool
)
{
gui
.
win
.
Root
()
.
Call
(
"addBlock"
,
ethpub
.
NewPBlock
(
block
)
,
initial
)
}
func
(
gui
*
Gui
)
setWalletValue
(
amount
,
unconfirmedFunds
*
big
.
Int
)
{
...
...
@@ -182,10 +240,16 @@ func (gui *Gui) update() {
blockChan
:=
make
(
chan
ethutil
.
React
,
1
)
txChan
:=
make
(
chan
ethutil
.
React
,
1
)
objectChan
:=
make
(
chan
ethutil
.
React
,
1
)
peerChan
:=
make
(
chan
ethutil
.
React
,
1
)
reactor
.
Subscribe
(
"newBlock"
,
blockChan
)
reactor
.
Subscribe
(
"newTx:pre"
,
txChan
)
reactor
.
Subscribe
(
"newTx:post"
,
txChan
)
reactor
.
Subscribe
(
"object:"
+
string
(
namereg
),
objectChan
)
reactor
.
Subscribe
(
"peerList"
,
peerChan
)
ticker
:=
time
.
NewTicker
(
5
*
time
.
Second
)
state
:=
gui
.
eth
.
StateManager
()
.
TransState
()
...
...
@@ -196,6 +260,7 @@ func (gui *Gui) update() {
select
{
case
b
:=
<-
blockChan
:
block
:=
b
.
Resource
.
(
*
ethchain
.
Block
)
gui
.
processBlock
(
block
,
false
)
if
bytes
.
Compare
(
block
.
Coinbase
,
gui
.
addr
)
==
0
{
gui
.
setWalletValue
(
gui
.
eth
.
StateManager
()
.
CurrentState
()
.
GetAccount
(
gui
.
addr
)
.
Amount
,
nil
)
}
...
...
@@ -207,12 +272,12 @@ func (gui *Gui) update() {
object
:=
state
.
GetAccount
(
gui
.
addr
)
if
bytes
.
Compare
(
tx
.
Sender
(),
gui
.
addr
)
==
0
{
gui
.
win
.
Root
()
.
Call
(
"addTx"
,
ethpub
.
NewPTx
(
tx
))
gui
.
win
.
Root
()
.
Call
(
"addTx"
,
ethpub
.
NewPTx
(
tx
)
,
"send"
)
gui
.
txDb
.
Put
(
tx
.
Hash
(),
tx
.
RlpEncode
())
unconfirmedFunds
.
Sub
(
unconfirmedFunds
,
tx
.
Value
)
}
else
if
bytes
.
Compare
(
tx
.
Recipient
,
gui
.
addr
)
==
0
{
gui
.
win
.
Root
()
.
Call
(
"addTx"
,
ethpub
.
NewPTx
(
tx
))
gui
.
win
.
Root
()
.
Call
(
"addTx"
,
ethpub
.
NewPTx
(
tx
)
,
"recv"
)
gui
.
txDb
.
Put
(
tx
.
Hash
(),
tx
.
RlpEncode
())
unconfirmedFunds
.
Add
(
unconfirmedFunds
,
tx
.
Value
)
...
...
@@ -231,10 +296,25 @@ func (gui *Gui) update() {
state
.
UpdateStateObject
(
object
)
}
case
<-
objectChan
:
gui
.
loadAddressBook
()
case
<-
peerChan
:
gui
.
setPeerInfo
()
case
<-
ticker
.
C
:
gui
.
setPeerInfo
()
}
}
}
func
(
gui
*
Gui
)
setPeerInfo
()
{
gui
.
win
.
Root
()
.
Call
(
"setPeers"
,
fmt
.
Sprintf
(
"%d / %d"
,
gui
.
eth
.
PeerCount
(),
gui
.
eth
.
MaxPeers
))
gui
.
win
.
Root
()
.
Call
(
"resetPeers"
)
for
_
,
peer
:=
range
gui
.
pub
.
GetPeers
()
{
gui
.
win
.
Root
()
.
Call
(
"addPeer"
,
peer
)
}
}
// Logging functions that log directly to the GUI interface
func
(
gui
*
Gui
)
Println
(
v
...
interface
{})
{
str
:=
strings
.
TrimRight
(
fmt
.
Sprintln
(
v
...
),
"
\n
"
)
...
...
@@ -251,6 +331,11 @@ func (gui *Gui) Printf(format string, v ...interface{}) {
gui
.
win
.
Root
()
.
Call
(
"addLog"
,
line
)
}
}
func
(
gui
*
Gui
)
RegisterName
(
name
string
)
{
keyPair
:=
ethutil
.
GetKeyRing
()
.
Get
(
0
)
name
=
fmt
.
Sprintf
(
"
\"
%s
\"\n
1"
,
name
)
gui
.
pub
.
Transact
(
ethutil
.
Hex
(
keyPair
.
PrivateKey
),
"namereg"
,
"1000"
,
"1000000"
,
"150"
,
name
)
}
func
(
gui
*
Gui
)
Transact
(
recipient
,
value
,
gas
,
gasPrice
,
data
string
)
(
*
ethpub
.
PReceipt
,
error
)
{
keyPair
:=
ethutil
.
GetKeyRing
()
.
Get
(
0
)
...
...
@@ -261,7 +346,13 @@ func (gui *Gui) Transact(recipient, value, gas, gasPrice, data string) (*ethpub.
func
(
gui
*
Gui
)
Create
(
recipient
,
value
,
gas
,
gasPrice
,
data
string
)
(
*
ethpub
.
PReceipt
,
error
)
{
keyPair
:=
ethutil
.
GetKeyRing
()
.
Get
(
0
)
//mainInput, initInput := mutan.PreParse(data)
return
gui
.
pub
.
Transact
(
ethutil
.
Hex
(
keyPair
.
PrivateKey
),
recipient
,
value
,
gas
,
gasPrice
,
data
)
}
func
(
gui
*
Gui
)
ChangeClientId
(
id
string
)
{
ethutil
.
Config
.
SetIdentifier
(
id
)
}
return
gui
.
pub
.
Create
(
ethutil
.
Hex
(
keyPair
.
PrivateKey
),
value
,
gas
,
gasPrice
,
data
)
func
(
gui
*
Gui
)
ClientId
()
string
{
return
ethutil
.
Config
.
Identifier
}
ethereal/ui/ui_lib.go
View file @
50fdfb12
...
...
@@ -2,13 +2,10 @@ package ethui
import
(
"bitbucket.org/kardianos/osext"
"fmt"
"github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils"
"github.com/go-qml/qml"
"github.com/obscuren/mutan"
"os"
"path"
"path/filepath"
...
...
@@ -29,6 +26,7 @@ type UiLib struct {
// The main application window
win
*
qml
.
Window
Db
*
Debugger
DbWindow
*
DebuggerWindow
}
func
NewUiLib
(
engine
*
qml
.
Engine
,
eth
*
eth
.
Ethereum
,
assetPath
string
)
*
UiLib
{
...
...
@@ -91,6 +89,29 @@ 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
(
"0x"
+
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
()
}
func
DefaultAssetPath
()
string
{
var
base
string
...
...
@@ -121,27 +142,28 @@ func DefaultAssetPath() string {
func
(
ui
*
UiLib
)
DebugTx
(
recipient
,
valueStr
,
gasStr
,
gasPriceStr
,
data
string
)
{
state
:=
ui
.
eth
.
BlockChain
()
.
CurrentBlock
.
State
()
mainInput
,
_
:=
mutan
.
PreParse
(
data
)
callerScript
,
err
:=
utils
.
Compile
(
mainInput
)
script
,
err
:=
ethutil
.
Compile
(
data
)
if
err
!=
nil
{
ethutil
.
Config
.
Log
.
Debugln
(
err
)
return
}
dis
:=
ethchain
.
Disassemble
(
callerS
cript
)
dis
:=
ethchain
.
Disassemble
(
s
cript
)
ui
.
win
.
Root
()
.
Call
(
"clearAsm"
)
for
_
,
str
:=
range
dis
{
ui
.
win
.
Root
()
.
Call
(
"setAsm"
,
str
)
}
callerTx
:=
ethchain
.
NewContractCreationTx
(
ethutil
.
Big
(
valueStr
),
ethutil
.
Big
(
gasStr
),
ethutil
.
Big
(
gasPriceStr
),
nil
)
// 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
)
account
:=
ui
.
eth
.
StateManager
()
.
TransState
()
.
GetStateObject
(
keyPair
.
Address
())
c
:=
ethchain
.
MakeContract
(
callerTx
,
state
)
callerClosure
:=
ethchain
.
NewClosure
(
account
,
c
,
c
.
Scrip
t
(),
state
,
ethutil
.
Big
(
gasStr
),
ethutil
.
Big
(
gasPriceStr
))
c
ontract
:=
ethchain
.
MakeContract
(
callerTx
,
state
)
callerClosure
:=
ethchain
.
NewClosure
(
account
,
c
ontract
,
contract
.
Ini
t
(),
state
,
ethutil
.
Big
(
gasStr
),
ethutil
.
Big
(
gasPriceStr
))
block
:=
ui
.
eth
.
BlockChain
()
.
CurrentBlock
vm
:=
ethchain
.
NewVm
(
state
,
ui
.
eth
.
StateManager
(),
ethchain
.
RuntimeVars
{
...
...
@@ -151,50 +173,18 @@ func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string)
Coinbase
:
block
.
Coinbase
,
Time
:
block
.
Time
,
Diff
:
block
.
Difficulty
,
TxData
:
nil
,
})
ui
.
Db
.
done
=
false
go
func
()
{
callerClosure
.
Call
(
vm
,
nil
,
ui
.
Db
.
halting
)
callerClosure
.
Call
(
vm
,
contract
.
Init
()
,
ui
.
Db
.
halting
)
state
.
Reset
()
ui
.
Db
.
done
=
true
}()
}
func
(
ui
*
UiLib
)
Next
()
{
ui
.
Db
.
Next
()
}
type
Debugger
struct
{
win
*
qml
.
Window
N
chan
bool
}
func
(
d
*
Debugger
)
halting
(
pc
int
,
op
ethchain
.
OpCode
,
mem
*
ethchain
.
Memory
,
stack
*
ethchain
.
Stack
)
{
d
.
win
.
Root
()
.
Call
(
"setInstruction"
,
pc
)
d
.
win
.
Root
()
.
Call
(
"clearMem"
)
d
.
win
.
Root
()
.
Call
(
"clearStack"
)
addr
:=
0
for
i
:=
0
;
i
+
32
<=
mem
.
Len
();
i
+=
32
{
d
.
win
.
Root
()
.
Call
(
"setMem"
,
memAddr
{
fmt
.
Sprintf
(
"%03d"
,
addr
),
fmt
.
Sprintf
(
"% x"
,
mem
.
Data
()[
i
:
i
+
32
])})
addr
++
}
for
_
,
val
:=
range
stack
.
Data
()
{
d
.
win
.
Root
()
.
Call
(
"setStack"
,
val
.
String
())
}
out
:
for
{
select
{
case
<-
d
.
N
:
break
out
default
:
}
}
}
func
(
d
*
Debugger
)
Next
()
{
d
.
N
<-
true
}
ethereum/config.go
View file @
50fdfb12
...
...
@@ -20,33 +20,35 @@ var UseSeed bool
var
ImportKey
string
var
ExportKey
bool
var
LogFile
string
var
DataDir
string
var
NonInteractive
bool
var
StartJsConsole
bool
var
InputFile
string
var
Datadir
string
func
Init
()
{
flag
.
Usage
=
func
()
{
fmt
.
Fprintf
(
os
.
Stderr
,
"%s [options] [filename]:
\n
"
,
os
.
Args
[
0
])
flag
.
PrintDefaults
()
}
flag
.
StringVar
(
&
Identifier
,
"i
"
,
""
,
"c
ustom client identifier"
)
flag
.
BoolVar
(
&
StartMining
,
"m"
,
false
,
"start dagger mining
"
)
flag
.
BoolVar
(
&
ShowGenesis
,
"g"
,
false
,
"prints genesis header and exits
"
)
flag
.
BoolVar
(
&
StartRpc
,
"r"
,
false
,
"start rpc server
"
)
flag
.
StringVar
(
&
Identifier
,
"i
d"
,
""
,
"C
ustom client identifier"
)
flag
.
StringVar
(
&
OutboundPort
,
"port"
,
"30303"
,
"listening port
"
)
flag
.
BoolVar
(
&
UseUPnP
,
"upnp"
,
false
,
"enable UPnP support
"
)
flag
.
IntVar
(
&
MaxPeer
,
"maxpeer"
,
10
,
"maximum desired peers
"
)
flag
.
IntVar
(
&
RpcPort
,
"rpcport"
,
8080
,
"port to start json-rpc server on"
)
flag
.
BoolVar
(
&
StartRpc
,
"rpc"
,
false
,
"start rpc server"
)
flag
.
BoolVar
(
&
StartJsConsole
,
"js"
,
false
,
"exp"
)
flag
.
BoolVar
(
&
StartMining
,
"mine"
,
false
,
"start dagger mining"
)
flag
.
BoolVar
(
&
NonInteractive
,
"y"
,
false
,
"non-interactive mode (say yes to confirmations)"
)
flag
.
BoolVar
(
&
UseUPnP
,
"upnp"
,
false
,
"enable UPnP support"
)
flag
.
BoolVar
(
&
UseSeed
,
"seed"
,
true
,
"seed peers"
)
flag
.
BoolVar
(
&
GenAddr
,
"genaddr"
,
false
,
"create a new priv/pub key"
)
flag
.
BoolVar
(
&
ExportKey
,
"export"
,
false
,
"export private key"
)
flag
.
StringVar
(
&
OutboundPort
,
"p"
,
"30303"
,
"listening port"
)
flag
.
StringVar
(
&
LogFile
,
"logfile"
,
""
,
"log file (defaults to standard output)"
)
flag
.
StringVar
(
&
DataDir
,
"dir"
,
".ethereum"
,
"ethereum data directory"
)
flag
.
StringVar
(
&
ImportKey
,
"import"
,
""
,
"imports the given private key (hex)"
)
flag
.
IntVar
(
&
MaxPeer
,
"x"
,
10
,
"maximum desired peers"
)
flag
.
BoolVar
(
&
StartJsConsole
,
"js"
,
false
,
"exp
"
)
flag
.
StringVar
(
&
Datadir
,
"datadir"
,
".ethereum"
,
"specifies the datadir to use. Takes precedence over config file.
"
)
flag
.
Parse
()
...
...
ethereum/ethereum.go
View file @
50fdfb12
...
...
@@ -6,10 +6,12 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils"
"github.com/rakyll/globalconf"
"io/ioutil"
"log"
"os"
"os/signal"
"path"
"runtime"
"strings"
)
...
...
@@ -59,7 +61,15 @@ func main() {
lt
=
ethutil
.
LogFile
|
ethutil
.
LogStd
}
ethutil
.
ReadConfig
(
DataDir
,
lt
,
Identifier
)
g
,
err
:=
globalconf
.
NewWithOptions
(
&
globalconf
.
Options
{
Filename
:
path
.
Join
(
ethutil
.
ApplicationFolder
(
Datadir
),
"conf.ini"
),
})
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
else
{
g
.
ParseAll
()
}
ethutil
.
ReadConfig
(
Datadir
,
lt
,
g
,
Identifier
)
logger
:=
ethutil
.
Config
.
Log
...
...
ethereum/javascript_runtime.go
View file @
50fdfb12
...
...
@@ -10,6 +10,7 @@ import (
"github.com/obscuren/otto"
"io/ioutil"
"os"
"path"
"path/filepath"
)
...
...
@@ -25,6 +26,20 @@ type JSRE struct {
objectCb
map
[
string
][]
otto
.
Value
}
func
(
jsre
*
JSRE
)
LoadExtFile
(
path
string
)
{
result
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
==
nil
{
jsre
.
vm
.
Run
(
result
)
}
else
{
ethutil
.
Config
.
Log
.
Debugln
(
"Could not load file:"
,
path
)
}
}
func
(
jsre
*
JSRE
)
LoadIntFile
(
file
string
)
{
assetPath
:=
path
.
Join
(
os
.
Getenv
(
"GOPATH"
),
"src"
,
"github.com"
,
"ethereum"
,
"go-ethereum"
,
"ethereal"
,
"assets"
,
"ext"
)
jsre
.
LoadExtFile
(
path
.
Join
(
assetPath
,
file
))
}
func
NewJSRE
(
ethereum
*
eth
.
Ethereum
)
*
JSRE
{
re
:=
&
JSRE
{
ethereum
,
...
...
@@ -39,6 +54,10 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
// Init the JS lib
re
.
vm
.
Run
(
jsLib
)
// Load extra javascript files
re
.
LoadIntFile
(
"string.js"
)
re
.
LoadIntFile
(
"big.js"
)
// We have to make sure that, whoever calls this, calls "Stop"
go
re
.
mainLoop
()
...
...
ethereum/repl.go
View file @
50fdfb12
...
...
@@ -66,6 +66,10 @@ func (self *JSEthereum) GetBlock(hash string) otto.Value {
return
self
.
toVal
(
&
JSBlock
{
self
.
PEthereum
.
GetBlock
(
hash
),
self
})
}
func
(
self
*
JSEthereum
)
GetPeers
()
otto
.
Value
{
return
self
.
toVal
(
self
.
PEthereum
.
GetPeers
())
}
func
(
self
*
JSEthereum
)
GetKey
()
otto
.
Value
{
return
self
.
toVal
(
self
.
PEthereum
.
GetKey
())
}
...
...
@@ -74,6 +78,10 @@ func (self *JSEthereum) GetStateObject(addr string) otto.Value {
return
self
.
toVal
(
self
.
PEthereum
.
GetStateObject
(
addr
))
}
func
(
self
*
JSEthereum
)
GetStateKeyVals
(
addr
string
)
otto
.
Value
{
return
self
.
toVal
(
self
.
PEthereum
.
GetStateObject
(
addr
)
.
StateKeyVal
(
false
))
}
func
(
self
*
JSEthereum
)
Transact
(
key
,
recipient
,
valueStr
,
gasStr
,
gasPriceStr
,
dataStr
string
)
otto
.
Value
{
r
,
err
:=
self
.
PEthereum
.
Transact
(
key
,
recipient
,
valueStr
,
gasStr
,
gasPriceStr
,
dataStr
)
if
err
!=
nil
{
...
...
@@ -101,7 +109,7 @@ func (self *JSEthereum) toVal(v interface{}) otto.Value {
result
,
err
:=
self
.
vm
.
ToValue
(
v
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
fmt
.
Println
(
"Value unknown:"
,
err
)
return
otto
.
UndefinedValue
()
}
...
...
utils/cmd.go
View file @
50fdfb12
...
...
@@ -33,13 +33,18 @@ func DoMining(ethereum *eth.Ethereum) {
addr
:=
keyPair
.
Address
()
go
func
()
{
ethutil
.
Config
.
Log
.
Infoln
(
"Miner started"
)
miner
=
ethminer
.
NewDefaultMiner
(
addr
,
ethereum
)
// Give it some time to connect with peers
time
.
Sleep
(
3
*
time
.
Second
)
for
ethereum
.
IsUpToDate
()
==
false
{
time
.
Sleep
(
5
*
time
.
Second
)
}
ethutil
.
Config
.
Log
.
Infoln
(
"Miner started"
)
miner
:=
ethminer
.
NewDefaultMiner
(
addr
,
ethereum
)
miner
.
Start
()
}()
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment