forked from cerc-io/plugeth
		
	Added some ui elements to make it easier to connect to nodes
This commit is contained in:
		
							parent
							
								
									2b967558ce
								
							
						
					
					
						commit
						aa33a4b2fb
					
				| @ -16,6 +16,7 @@ var UseSeed bool | ||||
| var ImportKey string | ||||
| var ExportKey bool | ||||
| var UseGui bool | ||||
| var DataDir string | ||||
| 
 | ||||
| func Init() { | ||||
| 	flag.BoolVar(&StartConsole, "c", false, "debug and testing console") | ||||
| @ -27,6 +28,7 @@ func Init() { | ||||
| 	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(&DataDir, "dir", ".ethereum", "ethereum data directory") | ||||
| 	flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") | ||||
| 	flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") | ||||
| 
 | ||||
|  | ||||
| @ -89,11 +89,12 @@ func main() { | ||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| 
 | ||||
| 	ethchain.InitFees() | ||||
| 	ethutil.ReadConfig(".ethereum") | ||||
| 	ethutil.ReadConfig(DataDir) | ||||
| 	ethutil.Config.Seed = UseSeed | ||||
| 
 | ||||
| 	// Instantiated a eth stack
 | ||||
| 	ethereum, err := eth.New(eth.CapDefault, UseUPnP) | ||||
| 	ethereum.Port = OutboundPort | ||||
| 	if err != nil { | ||||
| 		log.Println("eth start err:", err) | ||||
| 		return | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| import QtQuick 2.0 | ||||
| import QtQuick.Controls 1.0; | ||||
| import QtQuick.Layouts 1.0; | ||||
| import GoExtensions 1.0 | ||||
| import Ethereum 1.0 | ||||
| 
 | ||||
| ApplicationWindow { | ||||
| 	minimumWidth: 500 | ||||
| @ -29,7 +29,7 @@ ApplicationWindow { | ||||
| 		anchors.topMargin: 5 | ||||
| 		text: "Place bet" | ||||
| 		onClicked: { | ||||
| 			txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", parseInt(textField.text)) | ||||
| 			txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", textField.text) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										79
									
								
								ui/gui.go
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								ui/gui.go
									
									
									
									
									
								
							| @ -12,27 +12,13 @@ import ( | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| type Gui struct { | ||||
| 	win       *qml.Window | ||||
| 	engine    *qml.Engine | ||||
| 	component *qml.Common | ||||
| 	eth       *eth.Ethereum | ||||
| 
 | ||||
| 	// The Ethereum library
 | ||||
| 	lib *EthLib | ||||
| } | ||||
| 
 | ||||
| func New(ethereum *eth.Ethereum) *Gui { | ||||
| 	lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} | ||||
| 
 | ||||
| 	return &Gui{eth: ethereum, lib: lib} | ||||
| } | ||||
| 
 | ||||
| // Block interface exposed to QML
 | ||||
| type Block struct { | ||||
| 	Number int | ||||
| 	Hash   string | ||||
| } | ||||
| 
 | ||||
| // Creates a new QML Block from a chain block
 | ||||
| func NewBlockFromBlock(block *ethchain.Block) *Block { | ||||
| 	info := block.BlockInfo() | ||||
| 	hash := hex.EncodeToString(block.Hash()) | ||||
| @ -40,13 +26,42 @@ func NewBlockFromBlock(block *ethchain.Block) *Block { | ||||
| 	return &Block{Number: int(info.Number), Hash: hash} | ||||
| } | ||||
| 
 | ||||
| type Gui struct { | ||||
| 	// The main application window
 | ||||
| 	win *qml.Window | ||||
| 	// QML Engine
 | ||||
| 	engine    *qml.Engine | ||||
| 	component *qml.Common | ||||
| 	// The ethereum interface
 | ||||
| 	eth *eth.Ethereum | ||||
| 
 | ||||
| 	// The public Ethereum library
 | ||||
| 	lib *EthLib | ||||
| } | ||||
| 
 | ||||
| // Create GUI, but doesn't start it
 | ||||
| func New(ethereum *eth.Ethereum) *Gui { | ||||
| 	lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} | ||||
| 
 | ||||
| 	data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) | ||||
| 	keyRing := ethutil.NewValueFromBytes(data) | ||||
| 	addr := keyRing.Get(1).Bytes() | ||||
| 
 | ||||
| 	ethereum.BlockManager.WatchAddr(addr) | ||||
| 
 | ||||
| 	return &Gui{eth: ethereum, lib: lib} | ||||
| } | ||||
| 
 | ||||
| func (ui *Gui) Start() { | ||||
| 	qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{ | ||||
| 	// Register ethereum functions
 | ||||
| 	qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ | ||||
| 		Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, | ||||
| 	}}) | ||||
| 
 | ||||
| 	ethutil.Config.Log.Infoln("[GUI] Starting GUI") | ||||
| 	// Create a new QML engine
 | ||||
| 	ui.engine = qml.NewEngine() | ||||
| 	// Load the main QML interface
 | ||||
| 	component, err := ui.engine.LoadFile("wallet.qml") | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| @ -55,13 +70,18 @@ func (ui *Gui) Start() { | ||||
| 	ui.win = component.CreateWindow(nil) | ||||
| 
 | ||||
| 	context := ui.engine.Context() | ||||
| 
 | ||||
| 	// Expose the eth library and the ui library to QML
 | ||||
| 	context.SetVar("eth", ui.lib) | ||||
| 	context.SetVar("ui", &UiLib{engine: ui.engine, eth: ui.eth}) | ||||
| 
 | ||||
| 	// Register the ui as a block processor
 | ||||
| 	ui.eth.BlockManager.SecondaryBlockProcessor = ui | ||||
| 
 | ||||
| 	// Add the ui as a log system so we can log directly to the UGI
 | ||||
| 	ethutil.Config.Log.AddLogSystem(ui) | ||||
| 
 | ||||
| 	// Loads previous blocks
 | ||||
| 	go ui.setInitialBlockChain() | ||||
| 	go ui.updatePeers() | ||||
| 
 | ||||
| @ -70,6 +90,7 @@ func (ui *Gui) Start() { | ||||
| } | ||||
| 
 | ||||
| func (ui *Gui) setInitialBlockChain() { | ||||
| 	// Load previous 10 blocks
 | ||||
| 	chain := ui.eth.BlockManager.BlockChain().GetChain(ui.eth.BlockManager.BlockChain().CurrentBlock.Hash(), 10) | ||||
| 	for _, block := range chain { | ||||
| 		ui.ProcessBlock(block) | ||||
| @ -81,17 +102,24 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { | ||||
| 	ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) | ||||
| } | ||||
| 
 | ||||
| // Logging functions that log directly to the GUI interface
 | ||||
| func (ui *Gui) Println(v ...interface{}) { | ||||
| 	str := fmt.Sprintln(v...) | ||||
| 	// remove last \n
 | ||||
| 	ui.win.Root().Call("addLog", str[:len(str)-1]) | ||||
| 	str := strings.TrimRight(fmt.Sprintln(v...), "\n") | ||||
| 	lines := strings.Split(str, "\n") | ||||
| 	for _, line := range lines { | ||||
| 		ui.win.Root().Call("addLog", line) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (ui *Gui) Printf(format string, v ...interface{}) { | ||||
| 	str := strings.TrimRight(fmt.Sprintf(format, v...), "\n") | ||||
| 	ui.win.Root().Call("addLog", str) | ||||
| 	lines := strings.Split(str, "\n") | ||||
| 	for _, line := range lines { | ||||
| 		ui.win.Root().Call("addLog", line) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Simple go routine function that updates the list of peers in the GUI
 | ||||
| func (ui *Gui) updatePeers() { | ||||
| 	for { | ||||
| 		ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) | ||||
| @ -99,11 +127,14 @@ func (ui *Gui) updatePeers() { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // UI Library that has some basic functionality exposed
 | ||||
| type UiLib struct { | ||||
| 	engine    *qml.Engine | ||||
| 	eth       *eth.Ethereum | ||||
| 	connected bool | ||||
| } | ||||
| 
 | ||||
| // Opens a QML file (external application)
 | ||||
| func (ui *UiLib) Open(path string) { | ||||
| 	component, err := ui.engine.LoadFile(path[7:]) | ||||
| 	if err != nil { | ||||
| @ -118,8 +149,14 @@ func (ui *UiLib) Open(path string) { | ||||
| } | ||||
| 
 | ||||
| func (ui *UiLib) Connect() { | ||||
| 	if !ui.connected { | ||||
| 		ui.eth.Start() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (ui *UiLib) ConnectToPeer(addr string) { | ||||
| 	ui.eth.ConnectToPeer(addr) | ||||
| } | ||||
| 
 | ||||
| type Tester struct { | ||||
| 	root qml.Object | ||||
|  | ||||
| @ -5,7 +5,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go/ethchain" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"math/big" | ||||
| ) | ||||
| 
 | ||||
| type EthLib struct { | ||||
| @ -14,15 +13,18 @@ type EthLib struct { | ||||
| 	txPool       *ethchain.TxPool | ||||
| } | ||||
| 
 | ||||
| func (lib *EthLib) CreateTx(receiver string, amount uint64) string { | ||||
| func (lib *EthLib) CreateTx(receiver, a string) string { | ||||
| 	hash, err := hex.DecodeString(receiver) | ||||
| 	if err != nil { | ||||
| 		return err.Error() | ||||
| 	} | ||||
| 
 | ||||
| 	tx := ethchain.NewTransaction(hash, big.NewInt(int64(amount)), []string{""}) | ||||
| 	data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) | ||||
| 	keyRing := ethutil.NewValueFromBytes(data) | ||||
| 
 | ||||
| 	amount := ethutil.Big(a) | ||||
| 	tx := ethchain.NewTransaction(hash, amount, []string{""}) | ||||
| 	tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce | ||||
| 
 | ||||
| 	tx.Sign(keyRing.Get(0).Bytes()) | ||||
| 
 | ||||
| 	lib.txPool.QueueTransaction(tx) | ||||
|  | ||||
							
								
								
									
										64
									
								
								wallet.qml
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								wallet.qml
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ import QtQuick.Controls 1.0; | ||||
| import QtQuick.Layouts 1.0; | ||||
| import QtQuick.Dialogs 1.0; | ||||
| import QtQuick.Window 2.1; | ||||
| import GoExtensions 1.0 | ||||
| import Ethereum 1.0 | ||||
| 
 | ||||
| ApplicationWindow { | ||||
| 	id: root | ||||
| @ -22,15 +22,19 @@ ApplicationWindow { | ||||
| 			width: parent.width | ||||
| 			Button { | ||||
| 			      text: "Send" | ||||
| 			      onClicked: console.log("SEND") | ||||
| 			      onClicked: { | ||||
| 				      console.log(eth.createTx(txReceiver.text, txAmount.text)) | ||||
| 			      } | ||||
| 			} | ||||
| 
 | ||||
| 			TextField { | ||||
| 			      id: txAmount | ||||
| 			      width: 200 | ||||
| 			      placeholderText: "Amount" | ||||
| 			} | ||||
| 
 | ||||
| 			TextField { | ||||
| 			      id: txReceiver | ||||
| 			      width: 300 | ||||
| 			      placeholderText: "Receiver Address (or empty for contract)" | ||||
| 			      Layout.fillWidth: true | ||||
| @ -56,6 +60,34 @@ ApplicationWindow { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	MenuBar { | ||||
| 		Menu { | ||||
| 			title: "File" | ||||
| 			MenuItem { | ||||
| 				text: "Import App" | ||||
| 				shortcut: "Ctrl+o" | ||||
| 				onTriggered: openAppDialog.open() | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		Menu { | ||||
| 			title: "Network" | ||||
| 			MenuItem { | ||||
| 				text: "Add Peer" | ||||
| 				shortcut: "Ctrl+p" | ||||
| 				onTriggered: { | ||||
| 					addPeerWin.visible = true | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			MenuItem { | ||||
| 				text: "Start" | ||||
| 				onTriggered: ui.connect() | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	property var blockModel: ListModel { | ||||
| 		id: blockModel | ||||
| 	} | ||||
| @ -142,6 +174,34 @@ ApplicationWindow { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	Window { | ||||
| 		id: addPeerWin | ||||
| 		visible: false | ||||
| 		minimumWidth: 230 | ||||
| 		maximumWidth: 230 | ||||
| 		maximumHeight: 50 | ||||
| 		minimumHeight: 50 | ||||
| 
 | ||||
| 		TextField { | ||||
| 			id: addrField | ||||
| 			anchors.verticalCenter: parent.verticalCenter | ||||
| 			anchors.left: parent.left | ||||
| 			anchors.leftMargin: 10 | ||||
| 			placeholderText: "address:port" | ||||
| 		} | ||||
| 		Button { | ||||
| 			anchors.left: addrField.right | ||||
| 			anchors.verticalCenter: parent.verticalCenter | ||||
| 			anchors.leftMargin: 5 | ||||
| 			text: "Add" | ||||
| 			onClicked: { | ||||
| 				ui.connectToPeer(addrField.text) | ||||
| 				addrPeerWin.visible = false | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	function addBlock(block) { | ||||
| 		blockModel.insert(0, {number: block.number, hash: block.hash}) | ||||
| 	} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user