From 49c710bf442940b3abc68123964b56b211b92c12 Mon Sep 17 00:00:00 2001 From: zelig Date: Thu, 27 Mar 2014 17:14:04 +0700 Subject: [PATCH 1/7] assetPath configurable on command line for ethereal GUI - solves the problem of non-standard installs - add AssetPath to config as string var - introduced UiLib constructor which falls back to defaultAssetPath (earlier behaviour) if no assetPath is set - defaultAssetPath now internal concern of UiLib - gui.Start(assetPath) argument passed from ethereal main() as set Init() in config.go - informative log message if wallet.qml fails to open --- ethereal/config.go | 2 ++ ethereal/ethereum.go | 4 ++-- ethereal/ui/gui.go | 11 +++++++---- ethereal/ui/ui_lib.go | 14 +++++++++++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ethereal/config.go b/ethereal/config.go index a534bb182a..ac4484d0bd 100644 --- a/ethereal/config.go +++ b/ethereal/config.go @@ -16,6 +16,7 @@ var UseSeed bool var ImportKey string var ExportKey bool var DataDir string +var AssetPath string func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") @@ -29,6 +30,7 @@ func Init() { flag.StringVar(&DataDir, "dir", ".ethereal", "ethereum data directory") flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") + flag.StringVar(&AssetPath, "asset_path", "", "absolute path to GUI assets directory") flag.Parse() } diff --git a/ethereal/ethereum.go b/ethereal/ethereum.go index 618d2b00f7..99f3b0b525 100644 --- a/ethereal/ethereum.go +++ b/ethereal/ethereum.go @@ -100,11 +100,11 @@ func main() { os.Exit(0) } - log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + log.Printf("Starting Ethereum GUI v%s\n", ethutil.Config.Ver) // Set the max peers ethereum.MaxPeers = MaxPeer gui := ethui.New(ethereum) - gui.Start() + gui.Start(AssetPath) } diff --git a/ethereal/ui/gui.go b/ethereal/ui/gui.go index c8f4bedabf..89736ac29c 100644 --- a/ethereal/ui/gui.go +++ b/ethereal/ui/gui.go @@ -53,6 +53,7 @@ type Gui struct { txDb *ethdb.LDBDatabase addr []byte + } // Create GUI, but doesn't start it @@ -71,7 +72,7 @@ func New(ethereum *eth.Ethereum) *Gui { return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} } -func (ui *Gui) Start() { +func (ui *Gui) Start(assetPath string) { defer ui.txDb.Close() // Register ethereum functions @@ -89,14 +90,16 @@ func (ui *Gui) Start() { // 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}) + uiLib := NewUiLib(ui.engine, ui.eth, assetPath) + context.SetVar("ui", uiLib) // Load the main QML interface - component, err := ui.engine.LoadFile(AssetPath("qml/wallet.qml")) + component, err := ui.engine.LoadFile(uiLib.AssetPath("qml/wallet.qml")) if err != nil { + ethutil.Config.Log.Infoln("FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'") panic(err) } - ui.engine.LoadFile(AssetPath("qml/transactions.qml")) + ui.engine.LoadFile(uiLib.AssetPath("qml/transactions.qml")) ui.win = component.CreateWindow(nil) diff --git a/ethereal/ui/ui_lib.go b/ethereal/ui/ui_lib.go index 3997191fa4..4441a72389 100644 --- a/ethereal/ui/ui_lib.go +++ b/ethereal/ui/ui_lib.go @@ -16,6 +16,14 @@ type UiLib struct { engine *qml.Engine eth *eth.Ethereum connected bool + assetPath string +} + +func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { + if assetPath == "" { + assetPath = DefaultAssetPath() + } + return &UiLib{engine: engine, eth: eth, assetPath: assetPath} } // Opens a QML file (external application) @@ -45,10 +53,10 @@ func (ui *UiLib) ConnectToPeer(addr string) { } func (ui *UiLib) AssetPath(p string) string { - return AssetPath(p) + return path.Join(ui.assetPath, p) } -func AssetPath(p string) string { +func DefaultAssetPath() string { var base string // If the current working directory is the go-ethereum dir @@ -72,5 +80,5 @@ func AssetPath(p string) string { } } - return path.Join(base, p) + return base } From e65c4ee93e9dad629997c7839df7a8a0e7cff353 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 27 Mar 2014 15:22:20 +0100 Subject: [PATCH 2/7] Updated transaction constructor --- .gitignore | 1 + ethereum/dev_console.go | 25 ++++++++++--------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index f725d58d14..f816a06a17 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ *un~ .DS_Store */**/.DS_Store +./ethereum/ethereum diff --git a/ethereum/dev_console.go b/ethereum/dev_console.go index ead4b55e5e..5452b9a615 100644 --- a/ethereum/dev_console.go +++ b/ethereum/dev_console.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" + "github.com/obscuren/mutan" _ "math/big" "os" "strings" @@ -58,9 +59,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "getaddr" && argumentLength != 1: err = true expArgCount = 1 - case action == "contract" && argumentLength != 1: + case action == "contract" && argumentLength != 2: err = true - expArgCount = 1 + expArgCount = 2 case action == "say" && argumentLength != 1: err = true expArgCount = 1 @@ -79,7 +80,7 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { } } -func (i *Console) Editor() []string { +func (i *Console) Editor() string { var buff bytes.Buffer for { reader := bufio.NewReader(os.Stdin) @@ -94,15 +95,7 @@ func (i *Console) Editor() []string { } } - scanner := bufio.NewScanner(strings.NewReader(buff.String())) - scanner.Split(bufio.ScanLines) - - var lines []string - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - - return lines + return buff.String() } func (i *Console) PrintRoot() { @@ -178,7 +171,7 @@ func (i *Console) ParseInput(input string) bool { if err != nil { fmt.Println("recipient err:", err) } else { - tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) + tx := ethchain.NewTx(recipient, ethutil.Big(tokens[2]), []string{""}) key := ethutil.Config.Db.GetKeys()[0] tx.Sign(key.PrivateKey) @@ -197,9 +190,11 @@ func (i *Console) ParseInput(input string) bool { } case "contract": fmt.Println("Contract editor (Ctrl-D = done)") - code := ethchain.Compile(i.Editor()) + asm := mutan.NewCompiler().Compile(strings.NewReader(i.Editor())) + + code := ethutil.Assemble(asm) - contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) + contract := ethchain.NewContractCreationTx(ethutil.Big(tokens[0]), ethutil.Big(tokens[1]), code) key := ethutil.Config.Db.GetKeys()[0] contract.Sign(key.PrivateKey) From c5215fd4fb9de7594fdb812f8f9e4c471ee8d003 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 27 Mar 2014 19:41:42 +0100 Subject: [PATCH 3/7] Added gas and gas price. * library's `createTx` method changed so it accepts a gas price * dev console accepts code as well as the library --- ethereal/assets/qml/wallet.qml | 29 +++++++++++++++----- ethereal/ui/library.go | 48 +++++++++++++++++++++++++++++++++- ethereum/dev_console.go | 6 ++++- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index 7fc7f5447d..f6b31f0fd4 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -158,20 +158,35 @@ ApplicationWindow { anchors.leftMargin: 5 anchors.topMargin: 5 TextField { - id: txAmount + id: txRecipient + placeholderText: "Recipient address (or empty for contract)" + Layout.fillWidth: true + } + + TextField { + id: txValue width: 200 placeholderText: "Amount" } - TextField { - id: txReceiver - placeholderText: "Receiver Address (or empty for contract)" - Layout.fillWidth: true + id: txGas + width: 200 + placeholderText: "Gas" + anchors.left: txValue + anchors.leftMargin: 5 + } + TextField { + id: txGasPrice + width: 200 + placeholderText: "Gas price" + anchors.left: txGas + anchors.leftMargin: 5 } Label { text: "Transaction data" } + TextArea { id: codeView anchors.topMargin: 5 @@ -180,9 +195,11 @@ ApplicationWindow { } Button { + id: txButton text: "Send" onClicked: { - console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + this.enabled = false + console.log(eth.createTx(txRecipient.text, txValue.text, txGas.text, txGasPrice.text, codeView.text)) } } } diff --git a/ethereal/ui/library.go b/ethereal/ui/library.go index 05fffd579a..bd67f3c201 100644 --- a/ethereal/ui/library.go +++ b/ethereal/ui/library.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" + "github.com/obscuren/mutan" "strings" ) @@ -14,6 +15,50 @@ type EthLib struct { txPool *ethchain.TxPool } +func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, data string) string { + var hash []byte + var contractCreation bool + if len(recipient) == 0 { + contractCreation = true + } else { + var err error + hash, err = hex.DecodeString(recipient) + if err != nil { + return err.Error() + } + } + + keyPair := ethutil.Config.Db.GetKeys()[0] + value := ethutil.Big(valueStr) + gas := ethutil.Big(valueStr) + gasPrice := ethutil.Big(gasPriceStr) + var tx *ethchain.Transaction + // Compile and assemble the given data + if contractCreation { + asm, err := mutan.NewCompiler().Compile(strings.NewReader(data)) + if err != nil { + return err.Error() + } + + code := ethutil.Assemble(asm) + tx = ethchain.NewContractCreationTx(value, gasPrice, code) + } else { + tx = ethchain.NewTransactionMessage(hash, value, gasPrice, gas, []string{}) + } + tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce + tx.Sign(keyPair.PrivateKey) + lib.txPool.QueueTransaction(tx) + + if contractCreation { + ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:]) + } else { + ethutil.Config.Log.Infof("Tx hash %x", tx.Hash()) + } + + return ethutil.Hex(tx.Hash()) +} + +/* func (lib *EthLib) CreateTx(receiver, a, data string) string { var hash []byte if len(receiver) == 0 { @@ -31,7 +76,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 := ethchain.NewTx(hash, amount, code) tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce tx.Sign(keyPair.PrivateKey) @@ -46,6 +91,7 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { return ethutil.Hex(tx.Hash()) } +*/ func (lib *EthLib) GetBlock(hexHash string) *Block { hash, err := hex.DecodeString(hexHash) diff --git a/ethereum/dev_console.go b/ethereum/dev_console.go index 5452b9a615..5fdf905096 100644 --- a/ethereum/dev_console.go +++ b/ethereum/dev_console.go @@ -190,7 +190,11 @@ func (i *Console) ParseInput(input string) bool { } case "contract": fmt.Println("Contract editor (Ctrl-D = done)") - asm := mutan.NewCompiler().Compile(strings.NewReader(i.Editor())) + asm, err := mutan.NewCompiler().Compile(strings.NewReader(i.Editor())) + if err != nil { + fmt.Println(err) + break + } code := ethutil.Assemble(asm) From 3fb7ae2fa19fede545466694fbf9d86a85310bd9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 27 Mar 2014 19:45:55 +0100 Subject: [PATCH 4/7] Removed CreateTx --- ethereum/dev_console.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereum/dev_console.go b/ethereum/dev_console.go index 5fdf905096..ff25d694cb 100644 --- a/ethereum/dev_console.go +++ b/ethereum/dev_console.go @@ -53,9 +53,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "gettx" && argumentLength != 1: err = true expArgCount = 1 - case action == "tx" && argumentLength != 2: + case action == "tx" && argumentLength != 4: err = true - expArgCount = 2 + expArgCount = 4 case action == "getaddr" && argumentLength != 1: err = true expArgCount = 1 @@ -171,7 +171,7 @@ func (i *Console) ParseInput(input string) bool { if err != nil { fmt.Println("recipient err:", err) } else { - tx := ethchain.NewTx(recipient, ethutil.Big(tokens[2]), []string{""}) + tx := ethchain.NewTransactionMessage(recipient, ethutil.Big(tokens[2]), ethutil.Big(tokens[3]), ethutil.Big(tokens[4]), []string{""}) key := ethutil.Config.Db.GetKeys()[0] tx.Sign(key.PrivateKey) From ebbc5e7cb8b3886c8557f9f8623113f52f7f5e4a Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 30 Mar 2014 22:03:29 +0200 Subject: [PATCH 5/7] Updated to new mutan api --- README.md | 12 ++++++------ ethereal/ui/library.go | 2 +- ethereum/dev_console.go | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a29bfb6d36..04c0cf78ac 100644 --- a/README.md +++ b/README.md @@ -13,18 +13,17 @@ Build ======= For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)) -Command line options +General command line options ==================== ``` --c Launch the developer console +-c Launch the developer console (node only) -m Start mining blocks -genaddr Generates a new address and private key (destructive action) -p Port on which the server will accept incomming connections (= 30303) -upnp Enable UPnP (= false) -x Desired amount of peers (= 5) -h This help --gui Launch with GUI (= true) -dir Data directory used to store configs and databases (=".ethereum") -import Import a private key (hex) ``` @@ -33,8 +32,9 @@ Developer console commands ========================== ``` -addp : Connect to the given host -tx Send Wei to the specified +addp : Connect to the given host +tx Send Wei to the specified +contract Creates a new contract and launches the editor ``` See the "help" command for *developer* options. @@ -57,7 +57,7 @@ Coding standards Sources should be formatted according to the [Go Formatting Style](http://golang.org/doc/effective_go.html#formatting). -Unless structs fields are supposed to be directly accesible, provide +Unless structs fields are supposed to be directly accessible, provide Getters and hide the fields through Go's exporting facility. When you comment put meaningfull comments. Describe in detail what you diff --git a/ethereal/ui/library.go b/ethereal/ui/library.go index bd67f3c201..692ec454c8 100644 --- a/ethereal/ui/library.go +++ b/ethereal/ui/library.go @@ -35,7 +35,7 @@ func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, data strin var tx *ethchain.Transaction // Compile and assemble the given data if contractCreation { - asm, err := mutan.NewCompiler().Compile(strings.NewReader(data)) + asm, err := mutan.Compile(strings.NewReader(data), false) if err != nil { return err.Error() } diff --git a/ethereum/dev_console.go b/ethereum/dev_console.go index ff25d694cb..421c3fa60f 100644 --- a/ethereum/dev_console.go +++ b/ethereum/dev_console.go @@ -190,7 +190,7 @@ func (i *Console) ParseInput(input string) bool { } case "contract": fmt.Println("Contract editor (Ctrl-D = done)") - asm, err := mutan.NewCompiler().Compile(strings.NewReader(i.Editor())) + asm, err := mutan.Compile(strings.NewReader(i.Editor()), false) if err != nil { fmt.Println(err) break From 97b98b1250890977ea622af378fe864e4620e313 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 31 Mar 2014 00:22:50 +0200 Subject: [PATCH 6/7] Fixed an issue with sending gas to a contract --- ethereal/assets/qml/wallet.qml | 2 +- ethereal/ui/library.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index f6b31f0fd4..9093e3ca86 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -198,7 +198,7 @@ ApplicationWindow { id: txButton text: "Send" onClicked: { - this.enabled = false + //this.enabled = false console.log(eth.createTx(txRecipient.text, txValue.text, txGas.text, txGasPrice.text, codeView.text)) } } diff --git a/ethereal/ui/library.go b/ethereal/ui/library.go index 692ec454c8..6f8cb6f65e 100644 --- a/ethereal/ui/library.go +++ b/ethereal/ui/library.go @@ -30,7 +30,7 @@ func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, data strin keyPair := ethutil.Config.Db.GetKeys()[0] value := ethutil.Big(valueStr) - gas := ethutil.Big(valueStr) + gas := ethutil.Big(gasStr) gasPrice := ethutil.Big(gasPriceStr) var tx *ethchain.Transaction // Compile and assemble the given data @@ -40,7 +40,7 @@ func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, data strin return err.Error() } - code := ethutil.Assemble(asm) + code := ethutil.Assemble(asm...) tx = ethchain.NewContractCreationTx(value, gasPrice, code) } else { tx = ethchain.NewTransactionMessage(hash, value, gasPrice, gas, []string{}) From e403b28eea6959c1d0ed003d955df3dee586083b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 31 Mar 2014 01:02:00 +0200 Subject: [PATCH 7/7] Fixed miner --- ethereum/ethereum.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index 3f5e4a8f55..666c75117f 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -131,15 +131,14 @@ func main() { // Create a new block which we're going to mine block := ethereum.BlockChain().NewBlock(addr, txs) log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") - // Apply all transactions to the block - ethereum.StateManager().ApplyTransactions(block, block.Transactions()) ethereum.StateManager().Prepare(block.State(), block.State()) + // Apply all transactions to the block + ethereum.StateManager().ApplyTransactions(block, block.Transactions()) ethereum.StateManager().AccumelateRewards(block) // Search the nonce block.Nonce = pow.Search(block) - ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) ethereum.StateManager().PrepareDefault(block) err := ethereum.StateManager().ProcessBlock(block) @@ -148,6 +147,7 @@ func main() { } else { log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) log.Printf("🔨 Mined block %x\n", block.Hash()) + ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) } } }()