aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md8
-rw-r--r--ethereum/flags.go8
-rw-r--r--ethereum/main.go12
-rw-r--r--ethereum/repl/console_colors_windows.go80
-rw-r--r--ethereum/repl/repl_darwin.go6
-rw-r--r--ethereum/repl/repl_windows.go57
-rwxr-xr-xinstall.sh6
-rw-r--r--javascript/javascript_runtime.go39
-rw-r--r--javascript/js_lib.go4
-rw-r--r--javascript/types.go4
-rw-r--r--mist/assets/qml/main.qml19
-rw-r--r--mist/assets/qml/views/chain.qml41
-rw-r--r--mist/assets/qml/views/history.qml1
-rw-r--r--mist/assets/qml/views/info.qml3
-rw-r--r--mist/assets/qml/views/javascript.qml45
-rw-r--r--mist/assets/qml/views/pending_tx.qml1
-rw-r--r--mist/assets/qml/views/transaction.qml3
-rw-r--r--mist/assets/qml/webapp.qml727
-rw-r--r--mist/bindings.go17
-rw-r--r--mist/debugger.go27
-rw-r--r--mist/ext_app.go74
-rw-r--r--mist/flags.go52
-rw-r--r--mist/gui.go135
-rw-r--r--mist/main.go8
-rw-r--r--mist/ui_lib.go15
-rw-r--r--utils/cmd.go17
-rw-r--r--utils/vm_env.go5
27 files changed, 737 insertions, 677 deletions
diff --git a/README.md b/README.md
index 8657e3fb6..3d4a75797 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,9 @@ For the development package please see the [eth-go package](https://github.com/e
Build
=======
-To build Ethereal (GUI):
+To build Mist (GUI):
-`go get github.com/ethereum/go-ethereum/ethereal`
+`go get github.com/ethereum/go-ethereum/mist`
To build the node (CLI):
@@ -29,7 +29,7 @@ General command line options
====================
```
-Shared between ethereum and ethereal
+Shared between ethereum and Mist
-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
@@ -47,7 +47,7 @@ ethereum [options] [filename]
filename Load the given file and interpret as JavaScript
-m Start mining blocks
-Etheral only
+Mist only
-asset_path absolute path to GUI assets directory
```
diff --git a/ethereum/flags.go b/ethereum/flags.go
index 58220f4e6..af7b3365a 100644
--- a/ethereum/flags.go
+++ b/ethereum/flags.go
@@ -3,11 +3,13 @@ package main
import (
"flag"
"fmt"
+ "log"
"os"
"os/user"
"path"
"github.com/ethereum/eth-go/ethlog"
+ "github.com/ethereum/eth-go/vm"
)
var (
@@ -37,6 +39,7 @@ var (
Dump bool
DumpHash string
DumpNumber int
+ VmType int
)
// flags specific to cli client
@@ -59,6 +62,7 @@ func Init() {
flag.PrintDefaults()
}
+ flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug")
flag.StringVar(&Identifier, "id", "", "Custom client identifier")
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
@@ -91,5 +95,9 @@ func Init() {
flag.Parse()
+ if VmType >= int(vm.MaxVmTy) {
+ log.Fatal("Invalid VM type ", VmType)
+ }
+
InputFile = flag.Arg(0)
}
diff --git a/ethereum/main.go b/ethereum/main.go
index 0f0df20bb..21668ad25 100644
--- a/ethereum/main.go
+++ b/ethereum/main.go
@@ -13,7 +13,7 @@ import (
const (
ClientIdentifier = "Ethereum(G)"
- Version = "0.6.7"
+ Version = "0.7.0"
)
var logger = ethlog.NewLogger("CLI")
@@ -31,7 +31,7 @@ func main() {
LogLevel = 0
}
- utils.InitConfig(ConfigFile, Datadir, "ETH")
+ utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethutil.Config.Diff = DiffTool
ethutil.Config.DiffType = DiffType
@@ -42,7 +42,7 @@ func main() {
db := utils.NewDatabase()
err := utils.DBSanityCheck(db)
if err != nil {
- logger.Errorln(err)
+ fmt.Println(err)
os.Exit(1)
}
@@ -60,11 +60,11 @@ func main() {
var block *ethchain.Block
if len(DumpHash) == 0 && DumpNumber == -1 {
- block = ethereum.BlockChain().CurrentBlock
+ block = ethereum.ChainManager().CurrentBlock
} else if len(DumpHash) > 0 {
- block = ethereum.BlockChain().GetBlock(ethutil.Hex2Bytes(DumpHash))
+ block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash))
} else {
- block = ethereum.BlockChain().GetBlockByNumber(uint64(DumpNumber))
+ block = ethereum.ChainManager().GetBlockByNumber(uint64(DumpNumber))
}
if block == nil {
diff --git a/ethereum/repl/console_colors_windows.go b/ethereum/repl/console_colors_windows.go
new file mode 100644
index 000000000..1f517bd8c
--- /dev/null
+++ b/ethereum/repl/console_colors_windows.go
@@ -0,0 +1,80 @@
+/* Inspired by https://github.com/xuyu/logging/blob/master/colorful_win.go */
+
+package ethrepl
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+type color uint16
+
+const (
+ green = color(0x0002)
+ red = color(0x0004)
+ yellow = color(0x000E)
+)
+
+const (
+ mask = uint16(yellow | green | red)
+)
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32.dll")
+ procGetStdHandle = kernel32.NewProc("GetStdHandle")
+ procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
+ procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
+ hStdout uintptr
+ initScreenInfo *consoleScreenBufferInfo
+)
+
+func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
+ ret, _, _ := procSetConsoleTextAttribute.Call(hConsoleOutput, uintptr(wAttributes))
+ return ret != 0
+}
+
+type coord struct {
+ X, Y int16
+}
+
+type smallRect struct {
+ Left, Top, Right, Bottom int16
+}
+
+type consoleScreenBufferInfo struct {
+ DwSize coord
+ DwCursorPosition coord
+ WAttributes uint16
+ SrWindow smallRect
+ DwMaximumWindowSize coord
+}
+
+func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
+ var csbi consoleScreenBufferInfo
+ ret, _, _ := procGetConsoleScreenBufferInfo.Call(hConsoleOutput, uintptr(unsafe.Pointer(&csbi)))
+ if ret == 0 {
+ return nil
+ }
+ return &csbi
+}
+
+const (
+ stdOutputHandle = uint32(-11 & 0xFFFFFFFF)
+)
+
+func init() {
+ hStdout, _, _ = procGetStdHandle.Call(uintptr(stdOutputHandle))
+ initScreenInfo = getConsoleScreenBufferInfo(hStdout)
+}
+
+func resetColorful() {
+ if initScreenInfo == nil {
+ return
+ }
+ setConsoleTextAttribute(hStdout, initScreenInfo.WAttributes)
+}
+
+func changeColor(c color) {
+ attr := uint16(0) & ^mask | uint16(c)
+ setConsoleTextAttribute(hStdout, attr)
+}
diff --git a/ethereum/repl/repl_darwin.go b/ethereum/repl/repl_darwin.go
index 4c07280f7..ba7dae996 100644
--- a/ethereum/repl/repl_darwin.go
+++ b/ethereum/repl/repl_darwin.go
@@ -9,6 +9,7 @@ package ethrepl
// #include <readline/history.h>
import "C"
import (
+ "fmt"
"os"
"os/signal"
"strings"
@@ -118,6 +119,9 @@ func (self *JSRepl) PrintValue(v interface{}) {
method, _ := self.re.Vm.Get("prettyPrint")
v, err := self.re.Vm.ToValue(v)
if err == nil {
- method.Call(method, v)
+ val, err := method.Call(method, v)
+ if err == nil {
+ fmt.Printf("%v", val)
+ }
}
}
diff --git a/ethereum/repl/repl_windows.go b/ethereum/repl/repl_windows.go
index 4106c89bc..bfae57088 100644
--- a/ethereum/repl/repl_windows.go
+++ b/ethereum/repl/repl_windows.go
@@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"os"
+ "strings"
)
func (self *JSRepl) read() {
@@ -14,11 +15,61 @@ func (self *JSRepl) read() {
if err != nil {
fmt.Println("Error reading input", err)
} else {
- self.parseInput(string(str))
+ if (string(str) == "exit") {
+ self.Stop()
+ break
+ } else {
+ self.parseInput(string(str))
+ }
}
}
}
-func (self *JSRepl) PrintValue(value otto.Value) {
- fmt.Println(value)
+func addHistory(s string) {
+}
+
+func printColored(outputVal string) {
+ for ; outputVal != "" ; {
+ codePart := ""
+ if (strings.HasPrefix(outputVal, "\033[32m")) {
+ codePart = "\033[32m"
+ changeColor(2)
+ }
+ if (strings.HasPrefix(outputVal, "\033[1m\033[30m")) {
+ codePart = "\033[1m\033[30m"
+ changeColor(8)
+ }
+ if (strings.HasPrefix(outputVal, "\033[31m")) {
+ codePart = "\033[31m"
+ changeColor(red)
+ }
+ if (strings.HasPrefix(outputVal, "\033[35m")) {
+ codePart = "\033[35m"
+ changeColor(5)
+ }
+ if (strings.HasPrefix(outputVal, "\033[0m")) {
+ codePart = "\033[0m"
+ resetColorful()
+ }
+ textPart := outputVal[len(codePart):len(outputVal)]
+ index := strings.Index(textPart, "\033")
+ if index == -1 {
+ outputVal = ""
+ } else {
+ outputVal = textPart[index:len(textPart)]
+ textPart = textPart[0:index]
+ }
+ fmt.Printf("%v", textPart)
+ }
+}
+
+func (self *JSRepl) PrintValue(v interface{}) {
+ method, _ := self.re.Vm.Get("prettyPrint")
+ v, err := self.re.Vm.ToValue(v)
+ if err == nil {
+ val, err := method.Call(method, v)
+ if err == nil {
+ printColored(fmt.Sprintf("%v", val))
+ }
+ }
}
diff --git a/install.sh b/install.sh
index 9719a1afc..f880aa39b 100755
--- a/install.sh
+++ b/install.sh
@@ -2,7 +2,7 @@
if [ "$1" == "" ]; then
echo "Usage $0 executable branch ethereum develop"
- echo "executable ethereum or ethereal"
+ echo "executable ethereum or mist"
echo "branch develop or master"
exit
fi
@@ -41,8 +41,8 @@ echo "go-ethereum"
cd $GOPATH/src/github.com/ethereum/go-ethereum/$exe
git checkout $branch
-if [ "$exe" == "ethereal" ]; then
- echo "Building ethereal GUI. Assuming Qt is installed. If this step"
+if [ "$exe" == "mist" ]; then
+ echo "Building Mist GUI. Assuming Qt is installed. If this step"
echo "fails; please refer to: https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)"
else
echo "Building ethereum CLI."
diff --git a/javascript/javascript_runtime.go b/javascript/javascript_runtime.go
index ffc672a63..189106ae9 100644
--- a/javascript/javascript_runtime.go
+++ b/javascript/javascript_runtime.go
@@ -11,9 +11,9 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethpipe"
- "github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
+ "github.com/ethereum/eth-go/event"
"github.com/ethereum/go-ethereum/utils"
"github.com/obscuren/otto"
)
@@ -25,9 +25,8 @@ type JSRE struct {
Vm *otto.Otto
pipe *ethpipe.JSPipe
- blockChan chan ethreact.Event
- changeChan chan ethreact.Event
- quitChan chan bool
+ events event.Subscription
+ quitChan chan bool
objectCb map[string][]otto.Value
}
@@ -51,8 +50,7 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
ethereum,
otto.New(),
ethpipe.NewJSPipe(ethereum),
- make(chan ethreact.Event, 10),
- make(chan ethreact.Event, 10),
+ nil,
make(chan bool),
make(map[string][]otto.Value),
}
@@ -68,8 +66,8 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
go re.mainLoop()
// Subscribe to events
- reactor := ethereum.Reactor()
- reactor.Subscribe("newBlock", re.blockChan)
+ mux := ethereum.EventMux()
+ re.events = mux.Subscribe(ethchain.NewBlockEvent{})
re.Bind("eth", &JSEthereum{re.pipe, re.Vm, ethereum})
@@ -105,25 +103,16 @@ func (self *JSRE) Require(file string) error {
}
func (self *JSRE) Stop() {
+ self.events.Unsubscribe()
// Kill the main loop
self.quitChan <- true
- close(self.blockChan)
close(self.quitChan)
- close(self.changeChan)
jsrelogger.Infoln("stopped")
}
func (self *JSRE) mainLoop() {
-out:
- for {
- select {
- case <-self.quitChan:
- break out
- case block := <-self.blockChan:
- if _, ok := block.Resource.(*ethchain.Block); ok {
- }
- }
+ for _ = range self.events.Chan() {
}
}
@@ -150,10 +139,10 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
var block *ethchain.Block
if call.Argument(0).IsNumber() {
num, _ := call.Argument(0).ToInteger()
- block = self.ethereum.BlockChain().GetBlockByNumber(uint64(num))
+ block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
} else if call.Argument(0).IsString() {
hash, _ := call.Argument(0).ToString()
- block = self.ethereum.BlockChain().GetBlock(ethutil.Hex2Bytes(hash))
+ block = self.ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(hash))
} else {
fmt.Println("invalid argument for dump. Either hex string or number")
}
@@ -201,13 +190,13 @@ func (self *JSRE) watch(call otto.FunctionCall) otto.Value {
if storageCallback {
self.objectCb[addr+storageAddr] = append(self.objectCb[addr+storageAddr], cb)
- event := "storage:" + string(ethutil.Hex2Bytes(addr)) + ":" + string(ethutil.Hex2Bytes(storageAddr))
- self.ethereum.Reactor().Subscribe(event, self.changeChan)
+ // event := "storage:" + string(ethutil.Hex2Bytes(addr)) + ":" + string(ethutil.Hex2Bytes(storageAddr))
+ // self.ethereum.EventMux().Subscribe(event, self.changeChan)
} else {
self.objectCb[addr] = append(self.objectCb[addr], cb)
- event := "object:" + string(ethutil.Hex2Bytes(addr))
- self.ethereum.Reactor().Subscribe(event, self.changeChan)
+ // event := "object:" + string(ethutil.Hex2Bytes(addr))
+ // self.ethereum.EventMux().Subscribe(event, self.changeChan)
}
return otto.UndefinedValue()
diff --git a/javascript/js_lib.go b/javascript/js_lib.go
index a3e9b8a5b..dd1fe5f4d 100644
--- a/javascript/js_lib.go
+++ b/javascript/js_lib.go
@@ -44,9 +44,11 @@ function pp(object) {
function prettyPrint(/* */) {
var args = arguments;
+ var ret = "";
for(var i = 0, l = args.length; i < l; i++) {
- console.log(pp(args[i]))
+ ret += pp(args[i]) + "\n";
}
+ return ret;
}
var print = prettyPrint;
diff --git a/javascript/types.go b/javascript/types.go
index 53a2977a8..560960f54 100644
--- a/javascript/types.go
+++ b/javascript/types.go
@@ -4,10 +4,10 @@ import (
"fmt"
"github.com/ethereum/eth-go"
- "github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpipe"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
+ "github.com/ethereum/eth-go/ui"
"github.com/obscuren/otto"
)
@@ -128,7 +128,7 @@ func (self *JSEthereum) toVal(v interface{}) otto.Value {
}
func (self *JSEthereum) Messages(object map[string]interface{}) otto.Value {
- filter := ethchain.NewFilterFromMap(object, self.ethereum)
+ filter := ui.NewFilterFromMap(object, self.ethereum)
messages := filter.Find()
var msgs []JSMessage
diff --git a/mist/assets/qml/main.qml b/mist/assets/qml/main.qml
index 3d9204ce8..cfd227b49 100644
--- a/mist/assets/qml/main.qml
+++ b/mist/assets/qml/main.qml
@@ -51,9 +51,8 @@ ApplicationWindow {
addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"});
- addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"});
- addPlugin("./views/javascript.qml", {noAdd: true, close: false, section: "legacy"});
+ addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/jeffcoin/jeffcoin.qml", {noAdd: true, close: false, section: "apps"})
@@ -363,12 +362,7 @@ ApplicationWindow {
view.visible = false
view.anchors.fill = mainView
- if( !view.hasOwnProperty("iconSource") ) {
- console.log("Could not load plugin. Property 'iconSourc' not found on view.");
- return;
- }
-
- var menuItem = menu.createMenuItem(view.iconSource, view, options);
+ var menuItem = menu.createMenuItem(view, options);
if( view.hasOwnProperty("menuItem") ) {
view.menuItem = menuItem;
}
@@ -525,7 +519,7 @@ ApplicationWindow {
}
}
- function createMenuItem(icon, view, options) {
+ function createMenuItem(view, options) {
if(options === undefined) {
options = {};
}
@@ -547,7 +541,10 @@ ApplicationWindow {
comp.view = view
comp.title = view.title
- comp.icon = view.iconSource
+
+ if(view.hasOwnProperty("iconSource")) {
+ comp.icon = view.iconSource;
+ }
comp.closable = options.close;
return comp
@@ -889,7 +886,7 @@ ApplicationWindow {
pastPeers.append({text: ips.get(i)})
}
- pastPeers.insert(0, {text: "poc-6.ethdev.com:30303"})
+ pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"})
}
}
diff --git a/mist/assets/qml/views/chain.qml b/mist/assets/qml/views/chain.qml
index 130ff8bb9..c4ceecfc0 100644
--- a/mist/assets/qml/views/chain.qml
+++ b/mist/assets/qml/views/chain.qml
@@ -8,8 +8,7 @@ import Ethereum 1.0
Rectangle {
id: root
- property var title: "Network"
- property var iconSource: "../net.png"
+ property var title: "Block Chain"
property var menuItem
objectName: "chainView"
@@ -64,12 +63,12 @@ Rectangle {
Menu {
id: contextMenu
- property var row;
+ property var row
MenuItem {
text: "Details"
onTriggered: {
popup.visible = true
- popup.setDetails(blockModel.get(this.row))
+ popup.setDetails(blockModel.get(contextMenu.row))
}
}
@@ -78,7 +77,7 @@ Rectangle {
MenuItem {
text: "Copy"
onTriggered: {
- copyToClipboard(blockModel.get(this.row).hash)
+ copyToClipboard(blockModel.get(contextMenu.row).hash)
}
}
@@ -86,7 +85,7 @@ Rectangle {
text: "Dump State"
onTriggered: {
generalFileDialog.show(false, function(path) {
- var hash = blockModel.get(this.row).hash;
+ var hash = blockModel.get(contextMenu.row).hash;
gui.dumpState(hash, path);
});
@@ -102,22 +101,18 @@ Rectangle {
initial = false
}
- /*
- var txs = JSON.parse(block.transactions);
- if(txs != null){
- amount = txs.length
- }
- */
- var txs = block.transactions;
var amount = block.transactions.length;
+ var txs = [];
+ for(var i = 0; i < block.transactions.length; i++) {
+ var tx = JSON.parse(block.transactions.getAsJson(i));
+ txs.push(tx);
+ }
if(initial){
blockModel.append({size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
} else {
blockModel.insert(0, {size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
}
-
- //root.secondary.text = "#" + block.number;
}
Window {
@@ -215,7 +210,7 @@ Rectangle {
anchors.topMargin: 10
text: "Debug contract"
onClicked: {
- if(tx.createsContract){
+ if(tx && tx.createsContract){
eth.startDbWithCode(tx.rawData)
}else {
eth.startDbWithContractAndData(tx.address, tx.rawData)
@@ -240,16 +235,16 @@ Rectangle {
property var singleBlock: ListModel {
id: singleBlock
}
- function setDetails(block){
- singleBlock.set(0,block)
+ function setDetails(bl){
+ singleBlock.set(0, bl)
popup.height = 300
transactionModel.clear()
- if(block.txs !== undefined){
- for(var i = 0; i < block.txs.length; i++) {
- transactionModel.insert(0, block.txs.get(i))
+ if(bl.txs !== undefined){
+ for(var i = 0; i < bl.txs.count; i++) {
+ transactionModel.insert(0, bl.txs.get(i))
}
- if(block.txs.length > 0 && block.txs.get(0).data){
- popup.showContractData(block.txs.get(0))
+ if(bl.txs.count > 0 && bl.txs.get(0).data){
+ popup.showContractData(bl.txs.get(0))
}
}
txView.forceActiveFocus()
diff --git a/mist/assets/qml/views/history.qml b/mist/assets/qml/views/history.qml
index 9eee883e3..c72f8f3ae 100644
--- a/mist/assets/qml/views/history.qml
+++ b/mist/assets/qml/views/history.qml
@@ -7,7 +7,6 @@ import QtQuick.Controls.Styles 1.1
import Ethereum 1.0
Rectangle {
- property var iconSource: "../tx.png"
property var title: "Transactions"
property var menuItem
diff --git a/mist/assets/qml/views/info.qml b/mist/assets/qml/views/info.qml
index 158e2c960..3ff551b05 100644
--- a/mist/assets/qml/views/info.qml
+++ b/mist/assets/qml/views/info.qml
@@ -7,8 +7,7 @@ import QtQuick.Controls.Styles 1.1
import Ethereum 1.0
Rectangle {
- property var title: "Information"
- property var iconSource: "../heart.png"
+ property var title: "Debug Info"
property var menuItem
objectName: "infoView"
diff --git a/mist/assets/qml/views/javascript.qml b/mist/assets/qml/views/javascript.qml
deleted file mode 100644
index ea05c4148..000000000
--- a/mist/assets/qml/views/javascript.qml
+++ /dev/null
@@ -1,45 +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
-
-Rectangle {
- property var title: "JavaScript"
- property var iconSource: "../tx.png"
- property var menuItem
-
- objectName: "javascriptView"
- visible: false
- anchors.fill: parent
-
- TextField {
- id: input
- anchors {
- left: parent.left
- right: parent.right
- bottom: parent.bottom
- }
- height: 20
-
- Keys.onReturnPressed: {
- var res = eth.evalJavascriptString(this.text);
- this.text = "";
-
- output.append(res)
- }
- }
-
- TextArea {
- id: output
- text: "> JSRE Ready..."
- anchors {
- top: parent.top
- left: parent.left
- right: parent.right
- bottom: input.top
- }
- }
-}
diff --git a/mist/assets/qml/views/pending_tx.qml b/mist/assets/qml/views/pending_tx.qml
index abfa25790..4442a69db 100644
--- a/mist/assets/qml/views/pending_tx.qml
+++ b/mist/assets/qml/views/pending_tx.qml
@@ -8,7 +8,6 @@ import Ethereum 1.0
Rectangle {
property var title: "Pending Transactions"
- property var iconSource: "../tx.png"
property var menuItem
objectName: "pendingTxView"
diff --git a/mist/assets/qml/views/transaction.qml b/mist/assets/qml/views/transaction.qml
index 7d689733f..8792e31eb 100644
--- a/mist/assets/qml/views/transaction.qml
+++ b/mist/assets/qml/views/transaction.qml
@@ -7,8 +7,7 @@ import QtQuick.Controls.Styles 1.1
import Ethereum 1.0
Rectangle {
- property var iconSource: "../new.png"
- property var title: "New transaction"
+ property var title: "New Transaction"
property var menuItem
objectName: "newTxView"
diff --git a/mist/assets/qml/webapp.qml b/mist/assets/qml/webapp.qml
index 09e6a83ad..c35f325d5 100644
--- a/mist/assets/qml/webapp.qml
+++ b/mist/assets/qml/webapp.qml
@@ -7,411 +7,402 @@ import QtQuick.Layouts 1.0;
import QtQuick.Window 2.1;
import Ethereum 1.0
-import "../ext/qml_messaging.js" as Messaging
-
-//ApplicationWindow {
- Rectangle {
- id: window
- property var title: "Browser"
- property var iconSource: "../browser.png"
- property var menuItem
-
- property alias url: webview.url
- property alias webView: webview
-
- property var cleanPath: false
- property var open: function(url) {
- if(!window.cleanPath) {
- var uri = url;
- if(!/.*\:\/\/.*/.test(uri)) {
- uri = "http://" + uri;
- }
-
- var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
-
- if(reg.test(uri)) {
- uri.replace(reg, function(match, pre, domain, path) {
- uri = pre;
-
- var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
- var ip = [];
- for(var i = 0, l = lookup.length; i < l; i++) {
- ip.push(lookup.charCodeAt(i))
- }
-
- if(ip.length != 0) {
- uri += lookup;
- } else {
- uri += domain;
- }
-
- uri += path;
- });
- }
-
- window.cleanPath = true;
-
- webview.url = uri;
-
- //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>");
- uriNav.text = uri;
- } else {
- // Prevent inf loop.
- window.cleanPath = false;
- }
- }
-
- Component.onCompleted: {
- webview.url = "http://etherian.io"
- }
-
- signal messages(var messages, int id);
- onMessages: {
- // Bit of a cheat to get proper JSON
- var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
- webview.postEvent("messages", [m, id]);
- }
-
- Item {
- objectName: "root"
- id: root
- anchors.fill: parent
- state: "inspectorShown"
-
- RowLayout {
- id: navBar
- height: 40
- anchors {
- left: parent.left
- right: parent.right
- leftMargin: 7
- }
-
- Button {
- id: back
- onClicked: {
- webview.goBack()
- }
- style: ButtonStyle {
- background: Image {
- source: "../back.png"
- width: 30
- height: 30
- }
- }
- }
-
- TextField {
- anchors {
- left: back.right
- right: toggleInspector.left
- leftMargin: 5
- rightMargin: 5
- }
- text: "http://etherian.io"
- id: uriNav
- y: parent.height / 2 - this.height / 2
-
- Keys.onReturnPressed: {
- webview.url = this.text;
- }
- }
-
- Button {
- id: toggleInspector
- anchors {
- right: parent.right
- }
- iconSource: "../bug.png"
- onClicked: {
- if(inspector.visible == true){
- inspector.visible = false
- }else{
- inspector.visible = true
- inspector.url = webview.experimental.remoteInspectorUrl
- }
- }
- }
- }
-
-
- WebView {
- objectName: "webView"
- id: webview
- anchors {
- left: parent.left
- right: parent.right
- bottom: parent.bottom
- top: navBar.bottom
- }
-
- //property var cleanPath: false
- onNavigationRequested: {
- window.open(request.url.toString());
- }
-
- function sendMessage(data) {
- webview.experimental.postMessage(JSON.stringify(data))
- }
-
- onTitleChanged: {
- var data = Messaging.HandleMessage(title);
- if(data) {
- sendMessage(data)
- }
- }
-
- experimental.preferences.javascriptEnabled: true
- experimental.preferences.navigatorQtObjectEnabled: true
- experimental.preferences.developerExtrasEnabled: true
- experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
- experimental.onMessageReceived: {
- console.log("[onMessageReceived]: ", message.data)
- // TODO move to messaging.js
- var data = JSON.parse(message.data)
-
- try {
- switch(data.call) {
- case "compile":
- postData(data._seed, eth.compile(data.args[0]))
- break
-
- case "getCoinBase":
- postData(data._seed, eth.coinBase())
-
- break
-
- case "getIsListening":
- postData(data._seed, eth.isListening())
-
- break
-
- case "getIsMining":
- postData(data._seed, eth.isMining())
-
- break
+Rectangle {
+ id: window
+ property var title: "Browser"
+ property var iconSource: "../browser.png"
+ property var menuItem
+
+ property alias url: webview.url
+ property alias webView: webview
+
+ property var cleanPath: false
+ property var open: function(url) {
+ if(!window.cleanPath) {
+ var uri = url;
+ if(!/.*\:\/\/.*/.test(uri)) {
+ uri = "http://" + uri;
+ }
+
+ var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
+
+ if(reg.test(uri)) {
+ uri.replace(reg, function(match, pre, domain, path) {
+ uri = pre;
+
+ var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
+ var ip = [];
+ for(var i = 0, l = lookup.length; i < l; i++) {
+ ip.push(lookup.charCodeAt(i))
+ }
+
+ if(ip.length != 0) {
+ uri += lookup;
+ } else {
+ uri += domain;
+ }
+
+ uri += path;
+ });
+ }
+
+ window.cleanPath = true;
+
+ webview.url = uri;
+
+ //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>");
+ uriNav.text = uri;
+ } else {
+ // Prevent inf loop.
+ window.cleanPath = false;
+ }
+ }
+
+ Component.onCompleted: {
+ webview.url = "http://etherian.io"
+ }
+
+ signal messages(var messages, int id);
+ onMessages: {
+ // Bit of a cheat to get proper JSON
+ var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
+ webview.postEvent("messages", [m, id]);
+ }
+
+ Item {
+ objectName: "root"
+ id: root
+ anchors.fill: parent
+ state: "inspectorShown"
+
+ RowLayout {
+ id: navBar
+ height: 40
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: 7
+ }
+
+ Button {
+ id: back
+ onClicked: {
+ webview.goBack()
+ }
+ style: ButtonStyle {
+ background: Image {
+ source: "../back.png"
+ width: 30
+ height: 30
+ }
+ }
+ }
+
+ TextField {
+ anchors {
+ left: back.right
+ right: toggleInspector.left
+ leftMargin: 5
+ rightMargin: 5
+ }
+ text: "http://etherian.io"
+ id: uriNav
+ y: parent.height / 2 - this.height / 2
+
+ Keys.onReturnPressed: {
+ webview.url = this.text;
+ }
+ }
+
+ Button {
+ id: toggleInspector
+ anchors {
+ right: parent.right
+ }
+ iconSource: "../bug.png"
+ onClicked: {
+ if(inspector.visible == true){
+ inspector.visible = false
+ }else{
+ inspector.visible = true
+ inspector.url = webview.experimental.remoteInspectorUrl
+ }
+ }
+ }
+ }
+
+
+ WebView {
+ objectName: "webView"
+ id: webview
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ top: navBar.bottom
+ }
+
+ //property var cleanPath: false
+ onNavigationRequested: {
+ window.open(request.url.toString());
+ }
+
+ function sendMessage(data) {
+ webview.experimental.postMessage(JSON.stringify(data))
+ }
+
+
+ experimental.preferences.javascriptEnabled: true
+ experimental.preferences.navigatorQtObjectEnabled: true
+ experimental.preferences.developerExtrasEnabled: true
+ experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
+ experimental.onMessageReceived: {
+ console.log("[onMessageReceived]: ", message.data)
+ // TODO move to messaging.js
+ var data = JSON.parse(message.data)
+
+ try {
+ switch(data.call) {
+ case "compile":
+ postData(data._seed, eth.compile(data.args[0]))
+ break
+
+ case "getCoinBase":
+ postData(data._seed, eth.coinBase())
+
+ break
+
+ case "getIsListening":
+ postData(data._seed, eth.isListening())
- case "getPeerCount":
- postData(data._seed, eth.peerCount())
+ break
+
+ case "getIsMining":
+ postData(data._seed, eth.isMining())
- break
+ break
- case "getCountAt":
- require(1)
- postData(data._seed, eth.txCountAt(data.args[0]))
+ case "getPeerCount":
+ postData(data._seed, eth.peerCount())
- break
+ break
- case "getCodeAt":
- require(1)
- var code = eth.codeAt(data.args[0])
- postData(data._seed, code);
+ case "getCountAt":
+ require(1)
+ postData(data._seed, eth.txCountAt(data.args[0]))
- break
+ break
- case "getBlockByNumber":
- var block = eth.blockByNumber(data.args[0])
- postData(data._seed, block)
+ case "getCodeAt":
+ require(1)
+ var code = eth.codeAt(data.args[0])
+ postData(data._seed, code);
- break
+ break
- case "getBlockByHash":
- var block = eth.blockByHash(data.args[0])
- postData(data._seed, block)
+ case "getBlockByNumber":
+ var block = eth.blockByNumber(data.args[0])
+ postData(data._seed, block)
- break
+ break
- case "transact":
- require(5)
+ case "getBlockByHash":
+ var block = eth.blockByHash(data.args[0])
+ postData(data._seed, block)
- var tx = eth.transact(data.args)
- postData(data._seed, tx)
+ break
- break
+ case "transact":
+ require(5)
- case "getStorageAt":
- require(2);
+ var tx = eth.transact(data.args)
+ postData(data._seed, tx)
- var storage = eth.storageAt(data.args[0], data.args[1]);
- postData(data._seed, storage)
+ break
- break
+ case "getStorageAt":
+ require(2);
- case "call":
- require(1);
- var ret = eth.call(data.args)
- postData(data._seed, ret)
+ var storage = eth.storageAt(data.args[0], data.args[1]);
+ postData(data._seed, storage)
- break
+ break
- case "getEachStorage":
- require(1);
- var storage = JSON.parse(eth.eachStorage(data.args[0]))
- postData(data._seed, storage)
+ case "call":
+ require(1);
+ var ret = eth.call(data.args)
+ postData(data._seed, ret)
- break
+ break
- case "getTransactionsFor":
- require(1);
- var txs = eth.transactionsFor(data.args[0], true)
- postData(data._seed, txs)
+ case "getEachStorage":
+ require(1);
+ var storage = JSON.parse(eth.eachStorage(data.args[0]))
+ postData(data._seed, storage)
- break
+ break
- case "getBalanceAt":
- require(1);
+ case "getTransactionsFor":
+ require(1);
+ var txs = eth.transactionsFor(data.args[0], true)
+ postData(data._seed, txs)
- postData(data._seed, eth.balanceAt(data.args[0]));
+ break
- break
+ case "getBalanceAt":
+ require(1);
- case "getKey":
- var key = eth.key().privateKey;
+ postData(data._seed, eth.balanceAt(data.args[0]));
- postData(data._seed, key)
- break
+ break
- case "watch":
- require(2)
- eth.watch(data.args[0], data.args[1])
+ case "getKey":
+ var key = eth.key().privateKey;
- case "disconnect":
- require(1)
- postData(data._seed, null)
+ postData(data._seed, key)
+ break
- break;
+ case "watch":
+ require(2)
+ eth.watch(data.args[0], data.args[1])
- case "getSecretToAddress":
- require(1)
+ case "disconnect":
+ require(1)
+ postData(data._seed, null)
- var addr = eth.secretToAddress(data.args[0])
- console.log("getsecret", addr)
- postData(data._seed, addr)
+ break;
- break;
+ case "getSecretToAddress":
+ require(1)
- case "messages":
- require(1);
+ var addr = eth.secretToAddress(data.args[0])
+ console.log("getsecret", addr)
+ postData(data._seed, addr)
- var messages = JSON.parse(eth.getMessages(data.args[0]))
- postData(data._seed, messages)
+ break;
- break
+ case "messages":
+ require(1);
- case "mutan":
- require(1)
+ var messages = JSON.parse(eth.getMessages(data.args[0]))
+ postData(data._seed, messages)
- var code = eth.compileMutan(data.args[0])
- postData(data._seed, "0x"+code)
+ break
- break;
+ case "mutan":
+ require(1)
- case "newFilterString":
- require(1)
- var id = eth.newFilterString(data.args[0])
- postData(data._seed, id);
- break;
- case "newFilter":
- require(1)
- var id = eth.newFilter(data.args[0])
-
- postData(data._seed, id);
- break;
-
- case "getMessages":
- require(1);
-
- var messages = eth.messages(data.args[0]);
- var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
- postData(data._seed, m);
-
- break;
-
- case "deleteFilter":
- require(1);
- eth.uninstallFilter(data.args[0])
- break;
- }
- } catch(e) {
- console.log(data.call + ": " + e)
-
- postData(data._seed, null);
- }
- }
-
-
- function post(seed, data) {
- postData(data._seed, data)
- }
-
- function require(args, num) {
- if(args.length < num) {
- throw("required argument count of "+num+" got "+args.length);
- }
- }
- function postData(seed, data) {
- webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
- }
- function postEvent(event, data) {
- webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
- }
-
- function onWatchedCb(data, id) {
- var messages = JSON.parse(data)
- postEvent("watched:"+id, messages)
- }
-
- function onNewBlockCb(block) {
- postEvent("block:new", block)
- }
- function onObjectChangeCb(stateObject) {
- postEvent("object:"+stateObject.address(), stateObject)
- }
- function onStorageChangeCb(storageObject) {
- var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":");
- postEvent(ev, [storageObject.address, storageObject.value])
- }
- }
-
-
- Rectangle {
- id: sizeGrip
- color: "gray"
- visible: false
- height: 10
- anchors {
- left: root.left
- right: root.right
- }
- y: Math.round(root.height * 2 / 3)
-
- MouseArea {
- anchors.fill: parent
- drag.target: sizeGrip
- drag.minimumY: 0
- drag.maximumY: root.height
- drag.axis: Drag.YAxis
- }
- }
-
- WebView {
- id: inspector
- visible: false
- anchors {
- left: root.left
- right: root.right
- top: sizeGrip.bottom
- bottom: root.bottom
- }
- }
-
- states: [
- State {
- name: "inspectorShown"
- PropertyChanges {
- target: inspector
- }
- }
- ]
- }
- }
+ var code = eth.compileMutan(data.args[0])
+ postData(data._seed, "0x"+code)
+
+ break;
+
+ case "newFilterString":
+ require(1)
+ var id = eth.newFilterString(data.args[0])
+ postData(data._seed, id);
+ break;
+ case "newFilter":
+ require(1)
+ var id = eth.newFilter(data.args[0])
+
+ postData(data._seed, id);
+ break;
+
+ case "getMessages":
+ require(1);
+
+ var messages = eth.messages(data.args[0]);
+ var m = JSON.parse(JSON.parse(JSON.stringify(messages)))
+ postData(data._seed, m);
+
+ break;
+
+ case "deleteFilter":
+ require(1);
+ eth.uninstallFilter(data.args[0])
+ break;
+ }
+ } catch(e) {
+ console.log(data.call + ": " + e)
+
+ postData(data._seed, null);
+ }
+ }
+
+
+ function post(seed, data) {
+ postData(data._seed, data)
+ }
+
+ function require(args, num) {
+ if(args.length < num) {
+ throw("required argument count of "+num+" got "+args.length);
+ }
+ }
+ function postData(seed, data) {
+ webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
+ }
+ function postEvent(event, data) {
+ webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
+ }
+
+ function onWatchedCb(data, id) {
+ var messages = JSON.parse(data)
+ postEvent("watched:"+id, messages)
+ }
+
+ function onNewBlockCb(block) {
+ postEvent("block:new", block)
+ }
+ function onObjectChangeCb(stateObject) {
+ postEvent("object:"+stateObject.address(), stateObject)
+ }
+ function onStorageChangeCb(storageObject) {
+ var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":");
+ postEvent(ev, [storageObject.address, storageObject.value])
+ }
+ }
+
+
+ Rectangle {
+ id: sizeGrip
+ color: "gray"
+ visible: false
+ height: 10
+ anchors {
+ left: root.left
+ right: root.right
+ }
+ y: Math.round(root.height * 2 / 3)
+
+ MouseArea {
+ anchors.fill: parent
+ drag.target: sizeGrip
+ drag.minimumY: 0
+ drag.maximumY: root.height
+ drag.axis: Drag.YAxis
+ }
+ }
+
+ WebView {
+ id: inspector
+ visible: false
+ anchors {
+ left: root.left
+ right: root.right
+ top: sizeGrip.bottom
+ bottom: root.bottom
+ }
+ }
+
+ states: [
+ State {
+ name: "inspectorShown"
+ PropertyChanges {
+ target: inspector
+ }
+ }
+ ]
+ }
+}
diff --git a/mist/bindings.go b/mist/bindings.go
index 141c4a469..972e4e8ed 100644
--- a/mist/bindings.go
+++ b/mist/bindings.go
@@ -2,7 +2,6 @@ package main
import (
"encoding/json"
- "fmt"
"os"
"strconv"
@@ -18,16 +17,8 @@ type plugin struct {
Path string `json:"path"`
}
-func (gui *Gui) Println(v ...interface{}) {
- gui.printLog(fmt.Sprintln(v...))
-}
-
-func (gui *Gui) Printf(format string, v ...interface{}) {
- gui.printLog(fmt.Sprintf(format, v...))
-}
-
-// Print function that logs directly to the GUI
-func (gui *Gui) printLog(s string) {
+// LogPrint writes to the GUI log.
+func (gui *Gui) LogPrint(level ethlog.LogLevel, msg string) {
/*
str := strings.TrimRight(s, "\n")
lines := strings.Split(str, "\n")
@@ -105,9 +96,9 @@ func (self *Gui) DumpState(hash, path string) {
var block *ethchain.Block
if hash[0] == '#' {
i, _ := strconv.Atoi(hash[1:])
- block = self.eth.BlockChain().GetBlockByNumber(uint64(i))
+ block = self.eth.ChainManager().GetBlockByNumber(uint64(i))
} else {
- block = self.eth.BlockChain().GetBlock(ethutil.Hex2Bytes(hash))
+ block = self.eth.ChainManager().GetBlock(ethutil.Hex2Bytes(hash))
}
if block == nil {
diff --git a/mist/debugger.go b/mist/debugger.go
index 9d1de8c42..ebe18c78f 100644
--- a/mist/debugger.go
+++ b/mist/debugger.go
@@ -10,7 +10,7 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
- "github.com/ethereum/eth-go/ethvm"
+ "github.com/ethereum/eth-go/vm"
"github.com/ethereum/go-ethereum/utils"
"gopkg.in/qml.v1"
)
@@ -20,7 +20,7 @@ type DebuggerWindow struct {
engine *qml.Engine
lib *UiLib
- vm *ethvm.Vm
+ vm *vm.DebugVm
Db *Debugger
state *ethstate.State
@@ -37,7 +37,7 @@ func NewDebuggerWindow(lib *UiLib) *DebuggerWindow {
win := component.CreateWindow(nil)
- w := &DebuggerWindow{engine: engine, win: win, lib: lib, vm: &ethvm.Vm{}}
+ w := &DebuggerWindow{engine: engine, win: win, lib: lib, vm: &vm.DebugVm{}}
w.Db = NewDebugger(w)
return w
@@ -127,23 +127,22 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
state := self.lib.eth.StateManager().TransState()
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
contract := ethstate.NewStateObject([]byte{0})
- contract.Balance = value
+ contract.SetBalance(value)
self.SetAsm(script)
- block := self.lib.eth.BlockChain().CurrentBlock
+ block := self.lib.eth.ChainManager().CurrentBlock
- callerClosure := ethvm.NewClosure(&ethstate.Message{}, account, contract, script, gas, gasPrice)
+ callerClosure := vm.NewClosure(&ethstate.Message{}, account, contract, script, gas, gasPrice)
env := utils.NewEnv(state, block, account.Address(), value)
- vm := ethvm.New(env)
- vm.Verbose = true
- vm.Dbg = self.Db
+ evm := vm.NewDebugVm(env)
+ evm.Dbg = self.Db
- self.vm = vm
+ self.vm = evm
self.Db.done = false
self.Logf("callsize %d", len(script))
go func() {
- ret, g, err := callerClosure.Call(vm, data)
+ ret, g, err := callerClosure.Call(evm, data)
tot := new(big.Int).Mul(g, gasPrice)
self.Logf("gas usage %v total price = %v (%v)", g, tot, ethutil.CurrencyToString(tot))
if err != nil {
@@ -251,13 +250,13 @@ type storeVal struct {
Key, Value string
}
-func (self *Debugger) BreakHook(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *ethvm.Stack, stateObject *ethstate.StateObject) bool {
+func (self *Debugger) BreakHook(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, stateObject *ethstate.StateObject) bool {
self.main.Logln("break on instr:", pc)
return self.halting(pc, op, mem, stack, stateObject)
}
-func (self *Debugger) StepHook(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *ethvm.Stack, stateObject *ethstate.StateObject) bool {
+func (self *Debugger) StepHook(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, stateObject *ethstate.StateObject) bool {
return self.halting(pc, op, mem, stack, stateObject)
}
@@ -269,7 +268,7 @@ func (self *Debugger) BreakPoints() []int64 {
return self.breakPoints
}
-func (d *Debugger) halting(pc int, op ethvm.OpCode, mem *ethvm.Memory, stack *ethvm.Stack, stateObject *ethstate.StateObject) bool {
+func (d *Debugger) halting(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, stateObject *ethstate.StateObject) bool {
d.win.Root().Call("setInstruction", pc)
d.win.Root().Call("clearMem")
d.win.Root().Call("clearStack")
diff --git a/mist/ext_app.go b/mist/ext_app.go
index 514084c97..c4e6fd394 100644
--- a/mist/ext_app.go
+++ b/mist/ext_app.go
@@ -5,8 +5,9 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpipe"
- "github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethstate"
+ "github.com/ethereum/eth-go/event"
+ "github.com/ethereum/eth-go/ui/qt"
"github.com/ethereum/go-ethereum/javascript"
"gopkg.in/qml.v1"
)
@@ -28,9 +29,7 @@ type ExtApplication struct {
*ethpipe.JSPipe
eth ethchain.EthManager
- blockChan chan ethreact.Event
- messageChan chan ethreact.Event
- quitChan chan bool
+ events event.Subscription
watcherQuitChan chan bool
filters map[string]*ethchain.Filter
@@ -40,19 +39,14 @@ type ExtApplication struct {
}
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
- app := &ExtApplication{
- ethpipe.NewJSPipe(lib.eth),
- lib.eth,
- make(chan ethreact.Event, 100),
- make(chan ethreact.Event, 100),
- make(chan bool),
- make(chan bool),
- make(map[string]*ethchain.Filter),
- container,
- lib,
+ return &ExtApplication{
+ JSPipe: ethpipe.NewJSPipe(lib.eth),
+ eth: lib.eth,
+ watcherQuitChan: make(chan bool),
+ filters: make(map[string]*ethchain.Filter),
+ container: container,
+ lib: lib,
}
-
- return app
}
func (app *ExtApplication) run() {
@@ -67,14 +61,13 @@ func (app *ExtApplication) run() {
return
}
+ // Subscribe to events
+ mux := app.lib.eth.EventMux()
+ app.events = mux.Subscribe(ethchain.NewBlockEvent{}, ethstate.Messages(nil))
+
// Call the main loop
go app.mainLoop()
- // Subscribe to events
- reactor := app.lib.eth.Reactor()
- reactor.Subscribe("newBlock", app.blockChan)
- reactor.Subscribe("messages", app.messageChan)
-
app.container.NewWatcher(app.watcherQuitChan)
win := app.container.Window()
@@ -85,50 +78,37 @@ func (app *ExtApplication) run() {
}
func (app *ExtApplication) stop() {
- // Clean up
- reactor := app.lib.eth.Reactor()
- reactor.Unsubscribe("newBlock", app.blockChan)
+ app.events.Unsubscribe()
// Kill the main loop
- app.quitChan <- true
app.watcherQuitChan <- true
- close(app.blockChan)
- close(app.quitChan)
-
app.container.Destroy()
}
func (app *ExtApplication) mainLoop() {
-out:
- for {
- select {
- case <-app.quitChan:
- break out
- case block := <-app.blockChan:
- if block, ok := block.Resource.(*ethchain.Block); ok {
- app.container.NewBlock(block)
- }
- case msg := <-app.messageChan:
- if messages, ok := msg.Resource.(ethstate.Messages); ok {
- for id, filter := range app.filters {
- msgs := filter.FilterMessages(messages)
- if len(msgs) > 0 {
- app.container.Messages(msgs, id)
- }
+ for ev := range app.events.Chan() {
+ switch ev := ev.(type) {
+ case ethchain.NewBlockEvent:
+ app.container.NewBlock(ev.Block)
+
+ case ethstate.Messages:
+ for id, filter := range app.filters {
+ msgs := filter.FilterMessages(ev)
+ if len(msgs) > 0 {
+ app.container.Messages(msgs, id)
}
}
}
}
-
}
func (self *ExtApplication) Watch(filterOptions map[string]interface{}, identifier string) {
- self.filters[identifier] = ethchain.NewFilterFromMap(filterOptions, self.eth)
+ self.filters[identifier] = qt.NewFilterFromMap(filterOptions, self.eth)
}
func (self *ExtApplication) GetMessages(object map[string]interface{}) string {
- filter := ethchain.NewFilterFromMap(object, self.eth)
+ filter := qt.NewFilterFromMap(object, self.eth)
messages := filter.Find()
var msgs []javascript.JSMessage
diff --git a/mist/flags.go b/mist/flags.go
index d2e7d3fb0..68accf1bc 100644
--- a/mist/flags.go
+++ b/mist/flags.go
@@ -3,6 +3,7 @@ package main
import (
"flag"
"fmt"
+ "log"
"os"
"os/user"
"path"
@@ -11,28 +12,33 @@ import (
"bitbucket.org/kardianos/osext"
"github.com/ethereum/eth-go/ethlog"
+ "github.com/ethereum/eth-go/vm"
)
-var Identifier string
-var KeyRing string
-var KeyStore string
-var StartRpc bool
-var RpcPort int
-var UseUPnP bool
-var OutboundPort string
-var ShowGenesis bool
-var AddPeer string
-var MaxPeer int
-var GenAddr bool
-var UseSeed bool
-var SecretFile string
-var ExportDir string
-var NonInteractive bool
-var Datadir string
-var LogFile string
-var ConfigFile string
-var DebugFile string
-var LogLevel int
+var (
+ Identifier string
+ KeyRing string
+ KeyStore string
+ StartRpc bool
+ StartWebSockets bool
+ RpcPort int
+ UseUPnP bool
+ OutboundPort string
+ ShowGenesis bool
+ AddPeer string
+ MaxPeer int
+ GenAddr bool
+ UseSeed bool
+ SecretFile string
+ ExportDir string
+ NonInteractive bool
+ Datadir string
+ LogFile string
+ ConfigFile string
+ DebugFile string
+ LogLevel int
+ VmType int
+)
// flags specific to gui client
var AssetPath string
@@ -75,6 +81,7 @@ func Init() {
flag.PrintDefaults()
}
+ flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug")
flag.StringVar(&Identifier, "id", "", "Custom client identifier")
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
@@ -83,6 +90,7 @@ func Init() {
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(&StartWebSockets, "ws", false, "start websocket server")
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
@@ -97,4 +105,8 @@ func Init() {
flag.StringVar(&AssetPath, "asset_path", defaultAssetPath(), "absolute path to GUI assets directory")
flag.Parse()
+
+ if VmType >= int(vm.MaxVmTy) {
+ log.Fatal("Invalid VM type ", VmType)
+ }
}
diff --git a/mist/gui.go b/mist/gui.go
index 80d4a1fc3..2c19680c0 100644
--- a/mist/gui.go
+++ b/mist/gui.go
@@ -19,7 +19,6 @@ import (
"github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethminer"
"github.com/ethereum/eth-go/ethpipe"
- "github.com/ethereum/eth-go/ethreact"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire"
"gopkg.in/qml.v1"
@@ -229,10 +228,10 @@ func (gui *Gui) CreateAndSetPrivKey() (string, string, string, string) {
return gui.eth.KeyManager().KeyPair().AsStrings()
}
-func (gui *Gui) setInitialBlockChain() {
- sBlk := gui.eth.BlockChain().LastBlockHash
- blk := gui.eth.BlockChain().GetBlock(sBlk)
- for ; blk != nil; blk = gui.eth.BlockChain().GetBlock(sBlk) {
+func (gui *Gui) setInitialChainManager() {
+ sBlk := gui.eth.ChainManager().LastBlockHash
+ blk := gui.eth.ChainManager().GetBlock(sBlk)
+ for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) {
sBlk = blk.PrevHash
addr := gui.address()
@@ -364,7 +363,7 @@ func (gui *Gui) update() {
}
go func() {
- go gui.setInitialBlockChain()
+ go gui.setInitialChainManager()
gui.loadAddressBook()
gui.setPeerInfo()
gui.readPreviousTransactions()
@@ -376,15 +375,6 @@ func (gui *Gui) update() {
gui.win.Root().Call("addPlugin", plugin.Path, "")
}
- var (
- blockChan = make(chan ethreact.Event, 100)
- txChan = make(chan ethreact.Event, 100)
- objectChan = make(chan ethreact.Event, 100)
- peerChan = make(chan ethreact.Event, 100)
- chainSyncChan = make(chan ethreact.Event, 100)
- miningChan = make(chan ethreact.Event, 100)
- )
-
peerUpdateTicker := time.NewTicker(5 * time.Second)
generalUpdateTicker := time.NewTicker(500 * time.Millisecond)
statsUpdateTicker := time.NewTicker(5 * time.Second)
@@ -392,68 +382,89 @@ func (gui *Gui) update() {
state := gui.eth.StateManager().TransState()
unconfirmedFunds := new(big.Int)
- gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance)))
+ gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance())))
lastBlockLabel := gui.getObjectByName("lastBlockLabel")
miningLabel := gui.getObjectByName("miningLabel")
+ events := gui.eth.EventMux().Subscribe(
+ eth.ChainSyncEvent{},
+ eth.PeerListEvent{},
+ ethchain.NewBlockEvent{},
+ ethchain.TxEvent{},
+ ethminer.Event{},
+ )
+
+ // nameReg := gui.pipe.World().Config().Get("NameReg")
+ // mux.Subscribe("object:"+string(nameReg.Address()), objectChan)
+
go func() {
+ defer events.Unsubscribe()
for {
select {
- case b := <-blockChan:
- block := b.Resource.(*ethchain.Block)
- gui.processBlock(block, false)
- if bytes.Compare(block.Coinbase, gui.address()) == 0 {
- gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Balance, nil)
+ case ev, isopen := <-events.Chan():
+ if !isopen {
+ return
}
- case txMsg := <-txChan:
- tx := txMsg.Resource.(*ethchain.Transaction)
+ switch ev := ev.(type) {
+ case ethchain.NewBlockEvent:
+ gui.processBlock(ev.Block, false)
+ if bytes.Compare(ev.Block.Coinbase, gui.address()) == 0 {
+ gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Balance(), nil)
+ }
- if txMsg.Name == "newTx:pre" {
- object := state.GetAccount(gui.address())
+ case ethchain.TxEvent:
+ tx := ev.Tx
+ if ev.Type == ethchain.TxPre {
+ object := state.GetAccount(gui.address())
- if bytes.Compare(tx.Sender(), gui.address()) == 0 {
- unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
- } else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
- unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
- }
+ if bytes.Compare(tx.Sender(), gui.address()) == 0 {
+ unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
+ } else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
+ unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
+ }
+
+ gui.setWalletValue(object.Balance(), unconfirmedFunds)
+
+ gui.insertTransaction("pre", tx)
- gui.setWalletValue(object.Balance, unconfirmedFunds)
+ } else if ev.Type == ethchain.TxPost {
+ object := state.GetAccount(gui.address())
+ if bytes.Compare(tx.Sender(), gui.address()) == 0 {
+ object.SubAmount(tx.Value)
- gui.insertTransaction("pre", tx)
- } else {
- object := state.GetAccount(gui.address())
- if bytes.Compare(tx.Sender(), gui.address()) == 0 {
- object.SubAmount(tx.Value)
+ //gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "send")
+ gui.txDb.Put(tx.Hash(), tx.RlpEncode())
+ } else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
+ object.AddAmount(tx.Value)
- //gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "send")
- gui.txDb.Put(tx.Hash(), tx.RlpEncode())
- } else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
- object.AddAmount(tx.Value)
+ //gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "recv")
+ gui.txDb.Put(tx.Hash(), tx.RlpEncode())
+ }
- //gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "recv")
- gui.txDb.Put(tx.Hash(), tx.RlpEncode())
+ gui.setWalletValue(object.Balance(), nil)
+
+ state.UpdateStateObject(object)
}
- gui.setWalletValue(object.Balance, nil)
+ // case object:
+ // gui.loadAddressBook()
+
+ case eth.PeerListEvent:
+ gui.setPeerInfo()
- state.UpdateStateObject(object)
+ case ethminer.Event:
+ if ev.Type == ethminer.Started {
+ gui.miner = ev.Miner
+ } else {
+ gui.miner = nil
+ }
}
- case <-objectChan:
- gui.loadAddressBook()
- case <-peerChan:
- gui.setPeerInfo()
case <-peerUpdateTicker.C:
gui.setPeerInfo()
- case msg := <-miningChan:
- if msg.Name == "miner:start" {
- gui.miner = msg.Resource.(*ethminer.Miner)
- } else {
- gui.miner = nil
- }
case <-generalUpdateTicker.C:
- statusText := "#" + gui.eth.BlockChain().CurrentBlock.Number.String()
+ statusText := "#" + gui.eth.ChainManager().CurrentBlock.Number.String()
lastBlockLabel.Set("text", statusText)
if gui.miner != nil {
@@ -478,20 +489,6 @@ func (gui *Gui) update() {
}
}
}()
-
- reactor := gui.eth.Reactor()
-
- reactor.Subscribe("newBlock", blockChan)
- reactor.Subscribe("newTx:pre", txChan)
- reactor.Subscribe("newTx:post", txChan)
- reactor.Subscribe("chainSync", chainSyncChan)
- reactor.Subscribe("miner:start", miningChan)
- reactor.Subscribe("miner:stop", miningChan)
-
- nameReg := gui.pipe.World().Config().Get("NameReg")
- reactor.Subscribe("object:"+string(nameReg.Address()), objectChan)
-
- reactor.Subscribe("peerList", peerChan)
}
func (gui *Gui) setStatsPane() {
diff --git a/mist/main.go b/mist/main.go
index 6e4554352..116bd78fd 100644
--- a/mist/main.go
+++ b/mist/main.go
@@ -12,7 +12,7 @@ import (
const (
ClientIdentifier = "Mist"
- Version = "0.6.7"
+ Version = "0.7.1"
)
var ethereum *eth.Ethereum
@@ -21,7 +21,7 @@ func run() error {
// precedence: code-internal flag default < config file < environment variables < command line
Init() // parsing command line
- config := utils.InitConfig(ConfigFile, Datadir, "ETH")
+ config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
utils.InitDataDir(Datadir)
@@ -80,6 +80,10 @@ func main() {
utils.HandleInterrupt()
+ if StartWebSockets {
+ utils.StartWebSockets(ethereum)
+ }
+
// we need to run the interrupt callbacks in case gui is closed
// this skips if we got here by actual interrupt stopping the GUI
if !interrupted {
diff --git a/mist/ui_lib.go b/mist/ui_lib.go
index e77336c90..90ba0bbaf 100644
--- a/mist/ui_lib.go
+++ b/mist/ui_lib.go
@@ -13,6 +13,7 @@ import (
"github.com/ethereum/eth-go/ethpipe"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
+ "github.com/ethereum/eth-go/ui/qt"
"github.com/ethereum/go-ethereum/javascript"
"gopkg.in/qml.v1"
)
@@ -51,7 +52,7 @@ func (self *UiLib) LookupDomain(domain string) string {
world := self.World()
if len(domain) > 32 {
- domain = string(ethcrypto.Sha3Bin([]byte(domain)))
+ domain = string(ethcrypto.Sha3([]byte(domain)))
}
data := world.Config().Get("DnsReg").StorageString(domain).Bytes()
@@ -193,21 +194,21 @@ func (self *UiLib) StartDebugger() {
dbWindow.Show()
}
-func (self *UiLib) NewFilter(object map[string]interface{}) int {
- filter, id := self.eth.InstallFilter(object)
+func (self *UiLib) NewFilter(object map[string]interface{}) (id int) {
+ filter := qt.NewFilterFromMap(object, self.eth)
filter.MessageCallback = func(messages ethstate.Messages) {
self.win.Root().Call("invokeFilterCallback", ethpipe.ToJSMessages(messages), id)
}
-
+ id = self.eth.InstallFilter(filter)
return id
}
-func (self *UiLib) NewFilterString(typ string) int {
- filter, id := self.eth.InstallFilter(nil)
+func (self *UiLib) NewFilterString(typ string) (id int) {
+ filter := ethchain.NewFilter(self.eth)
filter.BlockCallback = func(block *ethchain.Block) {
self.win.Root().Call("invokeFilterCallback", "{}", id)
}
-
+ id = self.eth.InstallFilter(filter)
return id
}
diff --git a/utils/cmd.go b/utils/cmd.go
index 700542cae..32aebc91e 100644
--- a/utils/cmd.go
+++ b/utils/cmd.go
@@ -19,9 +19,9 @@ import (
"github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethminer"
"github.com/ethereum/eth-go/ethpipe"
- "github.com/ethereum/eth-go/ethrpc"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire"
+ "github.com/ethereum/eth-go/rpc"
)
var logger = ethlog.NewLogger("CLI")
@@ -118,9 +118,12 @@ func InitLogging(Datadir string, LogFile string, LogLevel int, DebugFile string)
return sys
}
-func InitConfig(ConfigFile string, Datadir string, EnvPrefix string) *ethutil.ConfigManager {
+func InitConfig(vmType int, ConfigFile string, Datadir string, EnvPrefix string) *ethutil.ConfigManager {
InitDataDir(Datadir)
- return ethutil.ReadConfig(ConfigFile, Datadir, EnvPrefix)
+ cfg := ethutil.ReadConfig(ConfigFile, Datadir, EnvPrefix)
+ cfg.VmType = vmType
+
+ return cfg
}
func exit(err error) {
@@ -166,7 +169,7 @@ func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) {
}
func ShowGenesis(ethereum *eth.Ethereum) {
- logger.Infoln(ethereum.BlockChain().Genesis())
+ logger.Infoln(ethereum.ChainManager().Genesis())
exit(nil)
}
@@ -241,7 +244,7 @@ func KeyTasks(keyManager *ethcrypto.KeyManager, KeyRing string, GenAddr bool, Se
func StartRpc(ethereum *eth.Ethereum, RpcPort int) {
var err error
- ethereum.RpcServer, err = ethrpc.NewJsonRpcServer(ethpipe.NewJSPipe(ethereum), RpcPort)
+ ethereum.RpcServer, err = rpc.NewJsonRpcServer(ethpipe.NewJSPipe(ethereum), RpcPort)
if err != nil {
logger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err)
} else {
@@ -307,12 +310,12 @@ func StopMining(ethereum *eth.Ethereum) bool {
// Replay block
func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
- block := ethereum.BlockChain().GetBlock(hash)
+ block := ethereum.ChainManager().GetBlock(hash)
if block == nil {
return fmt.Errorf("unknown block %x", hash)
}
- parent := ethereum.BlockChain().GetBlock(block.PrevHash)
+ parent := ethereum.ChainManager().GetBlock(block.PrevHash)
_, err := ethereum.StateManager().ApplyDiff(parent.State(), parent, block)
if err != nil {
diff --git a/utils/vm_env.go b/utils/vm_env.go
index 30568c421..21341ab04 100644
--- a/utils/vm_env.go
+++ b/utils/vm_env.go
@@ -5,6 +5,7 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethstate"
+ "github.com/ethereum/eth-go/vm"
)
type VMEnv struct {
@@ -33,3 +34,7 @@ func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
func (self *VMEnv) Value() *big.Int { return self.value }
func (self *VMEnv) State() *ethstate.State { return self.state }
+func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
+func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
+ return vm.Transfer(from, to, amount)
+}