diff --git a/Makefile b/Makefile new file mode 100644 index 000000000000..4da4c551c824 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +UNAME = $(shell uname) + +# Default is building +all: + go install + +install: +# Linux build +ifeq ($(UNAME),Linux) + mkdir /usr/local/ethereal + files=(wallet.qml net.png network.png new.png tx.png) + for file in "${files[@]}"; do + cp $file /usr/share/ethereal + done + cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal +endif +# OS X build +ifeq ($(UNAME),Darwin) + # Execute py script +endif diff --git a/README.md b/README.md index 11f5f9f9691d..cd9286659433 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ Ethereum Ethereum Go Client (c) Jeffrey Wilcke -The current state is "Proof of Concept 3". For build instructions see -the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). +The current state is "Proof of Concept 3". For the development Go Package please see [eth-go package](https://github.com/ethereum/eth-go). diff --git a/dev_console.go b/dev_console.go index 09e06aa22e09..ead4b55e5ecf 100644 --- a/dev_console.go +++ b/dev_console.go @@ -158,11 +158,11 @@ func (i *Console) ParseInput(input string) bool { fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) - addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.GetAddr(encoded) + addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) fmt.Println("addr:", addr) case "block": encoded, _ := hex.DecodeString(tokens[1]) - block := i.ethereum.BlockManager.BlockChain().GetBlock(encoded) + block := i.ethereum.BlockChain().GetBlock(encoded) info := block.BlockInfo() fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) case "say": @@ -182,7 +182,7 @@ func (i *Console) ParseInput(input string) bool { key := ethutil.Config.Db.GetKeys()[0] tx.Sign(key.PrivateKey) - i.ethereum.TxPool.QueueTransaction(tx) + i.ethereum.TxPool().QueueTransaction(tx) fmt.Printf("%x\n", tx.Hash()) } @@ -204,7 +204,7 @@ func (i *Console) ParseInput(input string) bool { key := ethutil.Config.Db.GetKeys()[0] contract.Sign(key.PrivateKey) - i.ethereum.TxPool.QueueTransaction(contract) + i.ethereum.TxPool().QueueTransaction(contract) fmt.Printf("%x\n", contract.Hash()[12:]) case "exit", "quit", "q": diff --git a/ethereum.go b/ethereum.go index 336cd4d0011f..36cd75e4771d 100644 --- a/ethereum.go +++ b/ethereum.go @@ -144,7 +144,7 @@ func main() { } if ShowGenesis { - fmt.Println(ethereum.BlockManager.BlockChain().Genesis()) + fmt.Println(ethereum.BlockChain().Genesis()) os.Exit(0) } @@ -183,22 +183,24 @@ func main() { addr := keyRing.Get(1).Bytes() for { - txs := ethereum.TxPool.Flush() + txs := ethereum.TxPool().Flush() // Create a new block which we're going to mine - block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) + block := ethereum.BlockChain().NewBlock(addr, txs) + log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") // Apply all transactions to the block - ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) + ethereum.StateManager().ApplyTransactions(block, block.Transactions()) - ethereum.BlockManager.AccumelateRewards(block, block) + ethereum.StateManager().AccumelateRewards(block, block) // Search the nonce block.Nonce = pow.Search(block) ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) - err := ethereum.BlockManager.ProcessBlock(block) + err := ethereum.StateManager().ProcessBlock(block) if err != nil { log.Println(err) } else { - log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockManager.BlockChain().CurrentBlock) + //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Printf("🔨 Mined block %x\n", block.Hash()) } } }() diff --git a/net.pxm b/net.pxm deleted file mode 100644 index 20d45d08c652..000000000000 Binary files a/net.pxm and /dev/null differ diff --git a/test_app.qml b/qml/test_app.qml similarity index 100% rename from test_app.qml rename to qml/test_app.qml diff --git a/transactions.qml b/qml/transactions.qml similarity index 100% rename from transactions.qml rename to qml/transactions.qml diff --git a/wallet.qml b/qml/wallet.qml similarity index 62% rename from wallet.qml rename to qml/wallet.qml index e86551ad68b9..7fc7f5447d8f 100644 --- a/wallet.qml +++ b/qml/wallet.qml @@ -85,7 +85,7 @@ ApplicationWindow { anchors.right: parent.right height: 200 Image { - source: "tx.png" + source: ui.assetPath("tx.png") anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent @@ -95,7 +95,7 @@ ApplicationWindow { } } Image { - source: "new.png" + source: ui.assetPath("new.png") anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent @@ -105,7 +105,7 @@ ApplicationWindow { } } Image { - source: "net.png" + source: ui.assetPath("net.png") anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent @@ -115,116 +115,141 @@ ApplicationWindow { } } } - - } - - property var txModel: ListModel { - id: txModel } Rectangle { - id: historyView - property var title: "Transactions" + id: mainView + color: "#00000000" anchors.right: parent.right anchors.left: menu.right anchors.bottom: parent.bottom anchors.top: parent.top - TableView { - id: txTableView - anchors.fill: parent - TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } - model: txModel + property var txModel: ListModel { + id: txModel } - } - Rectangle { - id: newTxView - property var title: "New transaction" - visible: false - anchors.right: parent.right - anchors.left: menu.right - anchors.bottom: parent.bottom - anchors.top: parent.top - color: "#00000000" + Rectangle { + id: historyView + anchors.fill: parent - ColumnLayout { - width: 400 - anchors.left: parent.left - anchors.top: parent.top - anchors.leftMargin: 5 - anchors.topMargin: 5 - TextField { - id: txAmount - width: 200 - placeholderText: "Amount" - } + property var title: "Transactions" + TableView { + id: txTableView + anchors.fill: parent + TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } + TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } - TextField { - id: txReceiver - placeholderText: "Receiver Address (or empty for contract)" - Layout.fillWidth: true + model: txModel } + } - Label { - text: "Transaction data" - } - TextArea { - id: codeView + Rectangle { + id: newTxView + property var title: "New transaction" + visible: false + anchors.fill: parent + color: "#00000000" + + ColumnLayout { + width: 400 + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: 5 anchors.topMargin: 5 - Layout.fillWidth: true - width: parent.width /2 - } + TextField { + id: txAmount + width: 200 + placeholderText: "Amount" + } + + TextField { + id: txReceiver + placeholderText: "Receiver Address (or empty for contract)" + Layout.fillWidth: true + } - Button { - text: "Send" - onClicked: { - console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + Label { + text: "Transaction data" + } + TextArea { + id: codeView + anchors.topMargin: 5 + Layout.fillWidth: true + width: parent.width /2 + } + + Button { + text: "Send" + onClicked: { + console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + } } } } - } - Rectangle { - id: networkView - property var title: "Network" - visible: false - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.top: parent.top + Rectangle { + id: networkView + property var title: "Network" + visible: false + anchors.fill: parent + + TableView { + id: blockTable + width: parent.width + anchors.top: parent.top + anchors.bottom: logView.top + TableViewColumn{ role: "number" ; title: "#" ; width: 100 } + TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } + + model: blockModel + + /* + onDoubleClicked: { + popup.visible = true + popup.block = eth.getBlock(blockModel.get(row).hash) + popup.hashLabel.text = popup.block.hash + } + */ + } - TableView { - id: blockTable - width: parent.width - anchors.top: parent.top - anchors.bottom: logView.top - TableViewColumn{ role: "number" ; title: "#" ; width: 100 } - TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } + property var logModel: ListModel { + id: logModel + } - model: blockModel + TableView { + id: logView + width: parent.width + height: 150 + anchors.bottom: parent.bottom + TableViewColumn{ role: "description" ; title: "log" } - onDoubleClicked: { - popup.visible = true - popup.block = eth.getBlock(blockModel.get(row).hash) - popup.hashLabel.text = popup.block.hash + model: logModel } } - property var logModel: ListModel { - id: logModel + /* + signal addPlugin(string name) + Component { + id: pluginWindow + Rectangle { + anchors.fill: parent + Label { + id: pluginTitle + anchors.centerIn: parent + text: "Hello world" + } + Component.onCompleted: setView(this) + } } - TableView { - id: logView - width: parent.width - height: 150 - anchors.bottom: parent.bottom - TableViewColumn{ role: "description" ; title: "log" } - - model: logModel + onAddPlugin: { + var pluginWin = pluginWindow.createObject(mainView) + console.log(pluginWin) + pluginWin.pluginTitle.text = "Test" } + */ } } @@ -249,6 +274,7 @@ ApplicationWindow { } text: "Connect" } + Button { id: importAppButton anchors.left: connectButton.right @@ -274,7 +300,7 @@ ApplicationWindow { id: peerImage anchors.right: parent.right width: 10; height: 10 - source: "network.png" + source: ui.assetPath("network.png") } } } @@ -304,6 +330,10 @@ ApplicationWindow { anchors.left: parent.left anchors.leftMargin: 10 placeholderText: "address:port" + onAccepted: { + ui.connectToPeer(addrField.text) + addPeerWin.visible = false + } } Button { anchors.left: addrField.right @@ -315,6 +345,9 @@ ApplicationWindow { addPeerWin.visible = false } } + Component.onCompleted: { + addrField.focus = true + } } Window { @@ -332,7 +365,7 @@ ApplicationWindow { width: 150 fillMode: Image.PreserveAspectFit smooth: true - source: "facet.png" + source: ui.assetPath("facet.png") x: 10 y: 10 } @@ -346,6 +379,11 @@ ApplicationWindow { } + function loadPlugin(name) { + console.log("Loading plugin" + name) + mainView.addPlugin(name) + } + function setWalletValue(value) { walletValueLabel.text = value } diff --git a/tx.pxm b/tx.pxm deleted file mode 100644 index 881420da9670..000000000000 Binary files a/tx.pxm and /dev/null differ diff --git a/ui/gui.go b/ui/gui.go index 389fe4f68e22..5f0b6e52d68a 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,8 +9,6 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" - "bitbucket.org/kardianos/osext" - "path/filepath" "math/big" "strings" ) @@ -59,7 +57,7 @@ type Gui struct { // 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} + lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} db, err := ethdb.NewLDBDatabase("tx_database") if err != nil { panic(err) @@ -68,7 +66,7 @@ func New(ethereum *eth.Ethereum) *Gui { key := ethutil.Config.Db.GetKeys()[0] addr := key.Address() - ethereum.BlockManager.WatchAddr(addr) + ethereum.StateManager().WatchAddr(addr) return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} } @@ -86,27 +84,23 @@ func (ui *Gui) Start() { ethutil.Config.Log.Infoln("[GUI] Starting GUI") // Create a new QML engine ui.engine = qml.NewEngine() + context := ui.engine.Context() - // Get Binary Directory - exedir , _ := osext.ExecutableFolder() + // 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}) // Load the main QML interface - component, err := ui.engine.LoadFile(filepath.Join(exedir, "wallet.qml")) + component, err := ui.engine.LoadFile(AssetPath("qml/wallet.qml")) if err != nil { panic(err) } - ui.engine.LoadFile(filepath.Join(exedir, "transactions.qml")) + ui.engine.LoadFile(AssetPath("qml/transactions.qml")) 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 + //ui.eth.BlockManager.SecondaryBlockProcessor = ui //ui.eth.TxPool.SecondaryProcessor = ui // Add the ui as a log system so we can log directly to the UGI @@ -125,7 +119,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) + chain := ui.eth.BlockChain().GetChain(ui.eth.BlockChain().CurrentBlock.Hash(), 10) for _, block := range chain { ui.ProcessBlock(block) } @@ -149,9 +143,9 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { // Simple go routine function that updates the list of peers in the GUI func (ui *Gui) update() { txChan := make(chan ethchain.TxMsg, 1) - ui.eth.TxPool.Subscribe(txChan) + ui.eth.TxPool().Subscribe(txChan) - account := ui.eth.BlockManager.GetAddrState(ui.addr).Account + account := ui.eth.StateManager().GetAddrState(ui.addr).Account unconfirmedFunds := new(big.Int) ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { @@ -164,7 +158,7 @@ func (ui *Gui) update() { ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 + ui.eth.StateManager().GetAddrState(ui.addr).Nonce += 1 unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) diff --git a/ui/library.go b/ui/library.go index 3bbb01314dcd..8dda0a89e994 100644 --- a/ui/library.go +++ b/ui/library.go @@ -9,7 +9,7 @@ import ( ) type EthLib struct { - blockManager *ethchain.BlockManager + stateManager *ethchain.StateManager blockChain *ethchain.BlockChain txPool *ethchain.TxPool } @@ -32,7 +32,7 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { amount := ethutil.Big(a) code := ethchain.Compile(strings.Split(data, "\n")) tx := ethchain.NewTransaction(hash, amount, code) - tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Nonce = lib.stateManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce tx.Sign(keyRing.Get(0).Bytes()) diff --git a/ui/ui_lib.go b/ui/ui_lib.go index c956fd03241d..2a1abee237ea 100644 --- a/ui/ui_lib.go +++ b/ui/ui_lib.go @@ -1,9 +1,13 @@ package ethui import ( + "bitbucket.org/kardianos/osext" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "path" + "path/filepath" + "runtime" ) // UI Library that has some basic functionality exposed @@ -38,3 +42,26 @@ func (ui *UiLib) Connect(button qml.Object) { func (ui *UiLib) ConnectToPeer(addr string) { ui.eth.ConnectToPeer(addr) } + +func (ui *UiLib) AssetPath(p string) string { + return AssetPath(p) +} + +func AssetPath(p string) string { + var base string + switch runtime.GOOS { + case "darwin": + // Get Binary Directory + exedir, _ := osext.ExecutableFolder() + base = filepath.Join(exedir, "../Resources") + base = "/Users/jeffrey/go/src/github.com/ethereum/go-ethereum" + case "linux": + base = "/usr/share/ethereal" + case "window": + fallthrough + default: + base = "." + } + + return path.Join(base, p) +}