浏览代码

merge upstream

zelig 11 年之前
父节点
当前提交
08de13a57b

+ 3 - 0
ethereal/assets/ext/ethereum.js

@@ -58,6 +58,9 @@ window.eth = {
 	getBalanceAt: function(address, cb) {
 		postData({call: "getBalance", args: [address]}, cb);
 	},
+	getTransactionsFor: function(address, cb) {
+		postData({call: "getTransactionsFor", args: [address]}, cb);
+	},
 
 	getSecretToAddress: function(sec, cb) {
 		postData({call: "getSecretToAddress", args: [sec]}, cb);

+ 22 - 0
ethereal/assets/qml/QmlApp.qml

@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import Ethereum 1.0
+
+ApplicationWindow {
+	minimumWidth: 500
+	maximumWidth: 500
+	maximumHeight: 400
+	minimumHeight: 400
+
+	function onNewBlockCb(block) {
+		console.log("Please overwrite onNewBlock(block):", block)
+	}
+	function onObjectChangeCb(stateObject) {
+		console.log("Please overwrite onObjectChangeCb(object)", stateObject)
+	}
+	function onStorageChangeCb(storageObject) {
+		var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":");
+		console.log("Please overwrite onStorageChangeCb(object)", ev)
+	}
+}

+ 58 - 23
ethereal/assets/qml/test_app.qml

@@ -3,33 +3,68 @@ import QtQuick.Controls 1.0;
 import QtQuick.Layouts 1.0;
 import Ethereum 1.0
 
-ApplicationWindow {
-	minimumWidth: 500
-	maximumWidth: 500
-	maximumHeight: 100
-	minimumHeight: 100
+QmlApp {
+	minimumWidth: 350
+	maximumWidth: 350
+	maximumHeight: 80
+	minimumHeight: 80
 
-	title: "Ethereum Dice"
+	title: "Generic Coin"
 
-	TextField {
-		id: textField
-		anchors.verticalCenter: parent.verticalCenter
-		anchors.horizontalCenter: parent.horizontalCenter
-		placeholderText: "Amount"
+	property string contractAddr: "f299f6c74515620e4c4cd8fe3d205b5c4f2e25c8"
+	property string addr: "2ef47100e0787b915105fd5e3f4ff6752079d5cb"
+
+	Component.onCompleted: {
+		eth.watch(contractAddr, addr)
+		eth.watch(addr, contractAddr)
+		setAmount()
+	}
+
+	function onStorageChangeCb(storageObject) {
+		setAmount()
 	}
-	Label {
-		id: txHash
-		anchors.bottom: textField.top
-		anchors.bottomMargin: 5
-		anchors.horizontalCenter: parent.horizontalCenter
+
+	function setAmount(){
+		var state = eth.getStateObject(contractAddr)
+		var storage = state.getStorage(addr)
+		amountLabel.text = storage
 	}
-	Button {
-		anchors.top: textField.bottom
-		anchors.horizontalCenter: parent.horizontalCenter
-		anchors.topMargin: 5
-		text: "Place bet"
-		onClicked: {
-			txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", textField.text)
+	Column {
+		spacing: 5
+		Row {
+			spacing: 20
+			Label {
+				id: genLabel
+				text: "Generic coin balance:"
+			}
+			Label {
+				id: amountLabel
+			}
+		}
+		Row {
+			spacing: 20
+			TextField {
+				id: address
+				placeholderText: "Address"
+			}
+			TextField {
+				id: amount
+				placeholderText: "Amount"
+			}
+		}
+		Button {
+			text: "Send coins"
+			onClicked: {
+				var privKey = eth.getKey().privateKey
+				if(privKey){
+					var result = eth.transact(privKey, contractAddr, 0,"100000","250", "0x" + address.text + "\n" + amount.text)
+					resultTx.text = result.hash
+				}
+			}
+		}
+		Label {
+			id: resultTx
 		}
 	}
+
 }

+ 9 - 1
ethereal/assets/qml/wallet.qml

@@ -372,7 +372,15 @@ ApplicationWindow {
 		onAccepted: {
 			//ui.open(openAppDialog.fileUrl.toString())
 			//ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html")))
-			ui.openHtml(openAppDialog.fileUrl.toString())
+			var path = openAppDialog.fileUrl.toString()
+			console.log(path)
+			var ext = path.split('.').pop()
+			console.log(ext)
+			if(ext == "html" || ext == "htm") {
+				ui.openHtml(path)
+			}else if(ext == "qml"){
+				ui.openQml(path)
+			}
 		}
 	}
 

+ 6 - 0
ethereal/assets/qml/webapp.qml

@@ -103,6 +103,12 @@ ApplicationWindow {
 					      postData(data._seed,stateObject)
 
 						break
+					case "getTransactionsFor":
+					      require(1);
+					      var txs = eth.getTransactionsFor(data.args[0], true)
+					      postData(data._seed, txs)
+
+					      break
 					case "getBalance":
 						require(1);
 

+ 59 - 0
ethereal/ui/qml_app.go

@@ -0,0 +1,59 @@
+package ethui
+
+import (
+	"github.com/ethereum/eth-go/ethchain"
+	"github.com/ethereum/eth-go/ethpub"
+	"github.com/ethereum/eth-go/ethutil"
+	"github.com/go-qml/qml"
+)
+
+type QmlApplication struct {
+	win    *qml.Window
+	engine *qml.Engine
+	lib    *UiLib
+	path   string
+}
+
+func NewQmlApplication(path string, lib *UiLib) *QmlApplication {
+	engine := qml.NewEngine()
+	return &QmlApplication{engine: engine, path: path, lib: lib}
+}
+
+func (app *QmlApplication) Create() error {
+	component, err := app.engine.LoadFile(app.path)
+	if err != nil {
+		ethutil.Config.Log.Debugln(err)
+	}
+	app.win = component.CreateWindow(nil)
+
+	return nil
+}
+
+func (app *QmlApplication) Destroy() {
+	app.engine.Destroy()
+}
+
+func (app *QmlApplication) NewWatcher(quitChan chan bool) {
+}
+
+// Events
+func (app *QmlApplication) NewBlock(block *ethchain.Block) {
+	pblock := &ethpub.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
+	app.win.Call("onNewBlockCb", pblock)
+}
+
+func (app *QmlApplication) ObjectChanged(stateObject *ethchain.StateObject) {
+	app.win.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject))
+}
+
+func (app *QmlApplication) StorageChanged(storageObject *ethchain.StorageState) {
+	app.win.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject))
+}
+
+// Getters
+func (app *QmlApplication) Engine() *qml.Engine {
+	return app.engine
+}
+func (app *QmlApplication) Window() *qml.Window {
+	return app.win
+}

+ 4 - 11
ethereal/ui/ui_lib.go

@@ -28,18 +28,11 @@ func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
 	return &UiLib{engine: engine, eth: eth, assetPath: assetPath}
 }
 
-// Opens a QML file (external application)
-func (ui *UiLib) Open(path string) {
-	component, err := ui.engine.LoadFile(path[7:])
-	if err != nil {
-		logger.Debugln(err)
-	}
-	win := component.CreateWindow(nil)
+func (ui *UiLib) OpenQml(path string) {
+	container := NewQmlApplication(path[7:], ui)
+	app := NewExtApplication(container, ui)
 
-	go func() {
-		win.Show()
-		win.Wait()
-	}()
+	go app.run()
 }
 
 func (ui *UiLib) OpenHtml(path string) {

+ 2 - 2
ethereum/javascript_runtime.go

@@ -144,7 +144,7 @@ func (self *JSRE) initStdFuncs() {
 	eth.Set("require", self.require)
 	eth.Set("stopMining", self.stopMining)
 	eth.Set("startMining", self.startMining)
-	eth.Set("blockDo", self.execBlock)
+	eth.Set("execBlock", self.execBlock)
 }
 
 /*
@@ -221,7 +221,7 @@ func (self *JSRE) execBlock(call otto.FunctionCall) otto.Value {
 		return otto.UndefinedValue()
 	}
 
-	err = self.ethereum.BlockDo(ethutil.FromHex(hash))
+	err = utils.BlockDo(self.ethereum, ethutil.FromHex(hash))
 	if err != nil {
 		fmt.Println(err)
 		return otto.FalseValue()

+ 26 - 1
ethereum/repl.go

@@ -1,10 +1,15 @@
 package main
 
 import (
+	"bufio"
 	"fmt"
 	"github.com/ethereum/eth-go"
 	"github.com/ethereum/eth-go/ethpub"
+	"github.com/ethereum/eth-go/ethutil"
 	"github.com/obscuren/otto"
+	"io"
+	"os"
+	"path"
 )
 
 type Repl interface {
@@ -16,20 +21,40 @@ type JSRepl struct {
 	re *JSRE
 
 	prompt string
+
+	history *os.File
 }
 
 func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
-	return &JSRepl{re: NewJSRE(ethereum), prompt: "> "}
+	hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
+	if err != nil {
+		panic(err)
+	}
+
+	return &JSRepl{re: NewJSRE(ethereum), prompt: "> ", history: hist}
 }
 
 func (self *JSRepl) Start() {
 	logger.Infoln("init JS Console")
+	reader := bufio.NewReader(self.history)
+	for {
+		line, err := reader.ReadString('\n')
+		if err != nil && err == io.EOF {
+			break
+		} else if err != nil {
+			fmt.Println("error reading history", err)
+			break
+		}
+
+		addHistory(line[:len(line)-1])
+	}
 	self.read()
 }
 
 func (self *JSRepl) Stop() {
 	self.re.Stop()
 	logger.Infoln("exit JS Console")
+	self.history.Close()
 }
 
 func (self *JSRepl) parseInput(code string) {

+ 3 - 1
ethereum/repl_darwin.go

@@ -102,7 +102,9 @@ L:
 					break L
 				}
 
-				addHistory(str[:len(str)-1]) //allow user to recall this line
+				hist := str[:len(str)-1]
+				addHistory(hist) //allow user to recall this line
+				self.history.WriteString(str)
 
 				self.parseInput(str)
 

+ 18 - 0
utils/cmd.go

@@ -219,3 +219,21 @@ func StopMining(ethereum *eth.Ethereum) bool {
   }
   return false
 }
+
+// Replay block
+func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
+	block := ethereum.BlockChain().GetBlock(hash)
+	if block == nil {
+		return fmt.Errorf("unknown block %x", hash)
+	}
+
+	parent := ethereum.BlockChain().GetBlock(block.PrevHash)
+
+	_, err := ethereum.StateManager().ApplyDiff(parent.State(), parent, block)
+	if err != nil {
+		return err
+	}
+
+	return nil
+
+}