From 13e18e1d8f717ffab1b59a39cf67ef169a542e74 Mon Sep 17 00:00:00 2001 From: Cayman Nava Date: Sat, 15 Mar 2014 16:46:10 -0700 Subject: working linux makefile when building develop branch, checkout of eth-go develop branch is required --- Makefile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 4da4c551c..709c416db 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,23 @@ UNAME = $(shell uname) +FILES=qml *.png +GOPATH=$(PWD) + # Default is building all: - go install + go get -d + cp *.go $(GOPATH)/src/github.com/ethereum/go-ethereum + cp -r ui $(GOPATH)/src/github.com/ethereum/go-ethereum + go build 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 + mkdir -p /usr/share/ethereal + for file in $(FILES); do \ + cp -r $$file /usr/share/ethereal; \ done - cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal + cp go-ethereum /usr/local/bin/ethereal endif # OS X build ifeq ($(UNAME),Darwin) -- cgit From 0db86e4485176aff7c45f0ce673174ec8407c0fc Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Mar 2014 11:16:41 +0100 Subject: Updated to work with the new chain --- Makefile | 5 +++-- ethereum.go | 7 +++++-- ui/gui.go | 1 + ui/library.go | 6 +++--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 4da4c551c..02d127963 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,12 @@ all: install: # Linux build ifeq ($(UNAME),Linux) - mkdir /usr/local/ethereal - files=(wallet.qml net.png network.png new.png tx.png) + mkdir -p /usr/local/ethereal + files=(net.png network.png new.png tx.png) for file in "${files[@]}"; do cp $file /usr/share/ethereal done + cp -r qml /usr/share/ethereal/qml cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal endif # OS X build diff --git a/ethereum.go b/ethereum.go index 36cd75e47..ac1de5af4 100644 --- a/ethereum.go +++ b/ethereum.go @@ -190,16 +190,19 @@ func main() { // Apply all transactions to the block ethereum.StateManager().ApplyTransactions(block, block.Transactions()) - ethereum.StateManager().AccumelateRewards(block, block) + ethereum.StateManager().Prepare(block.State(), block.State()) + 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) if err != nil { log.Println(err) } else { - //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) log.Printf("🔨 Mined block %x\n", block.Hash()) } } diff --git a/ui/gui.go b/ui/gui.go index 5f0b6e52d..c8f4bedab 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -81,6 +81,7 @@ func (ui *Gui) Start() { Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, }}) + ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.1")) ethutil.Config.Log.Infoln("[GUI] Starting GUI") // Create a new QML engine ui.engine = qml.NewEngine() diff --git a/ui/library.go b/ui/library.go index 8dda0a89e..05fffd579 100644 --- a/ui/library.go +++ b/ui/library.go @@ -27,14 +27,14 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { } k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(k) + keyPair := ethutil.NewKeyFromBytes(k) amount := ethutil.Big(a) code := ethchain.Compile(strings.Split(data, "\n")) tx := ethchain.NewTransaction(hash, amount, code) - tx.Nonce = lib.stateManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce - tx.Sign(keyRing.Get(0).Bytes()) + tx.Sign(keyPair.PrivateKey) lib.txPool.QueueTransaction(tx) -- cgit From 22b4e9b6173437b28045d69e8fd0b468e526e559 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Mar 2014 00:35:53 +0100 Subject: . --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd9286659..a29bfb6d3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Ethereum Ethereum Go Client (c) Jeffrey Wilcke -The current state is "Proof of Concept 3". +The current state is "Proof of Concept 3.5". For the development Go Package please see [eth-go package](https://github.com/ethereum/eth-go). -- cgit From 1f2547b8a7cfe100f64428d20f4bcf95eb9ecc5c Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Mar 2014 01:02:24 +0100 Subject: Major re-organisation. The Ethereum node and Gui are now separated. --- Makefile | 21 -- config.go | 36 ---- dev_console.go | 253 ---------------------- ethereal/Makefile | 21 ++ ethereal/assets/facet.png | Bin 0 -> 27302 bytes ethereal/assets/net.png | Bin 0 -> 4669 bytes ethereal/assets/network.png | Bin 0 -> 2900 bytes ethereal/assets/new.png | Bin 0 -> 4776 bytes ethereal/assets/qml/test_app.qml | 35 +++ ethereal/assets/qml/transactions.qml | 9 + ethereal/assets/qml/wallet.qml | 408 +++++++++++++++++++++++++++++++++++ ethereal/assets/tx.png | Bin 0 -> 4070 bytes ethereal/config.go | 34 +++ ethereal/ethereum.go | 110 ++++++++++ ethereal/ui/gui.go | 218 +++++++++++++++++++ ethereal/ui/library.go | 60 ++++++ ethereal/ui/ui_lib.go | 76 +++++++ ethereum.go | 215 ------------------ facet.png | Bin 27302 -> 0 bytes net.png | Bin 4669 -> 0 bytes network.png | Bin 2900 -> 0 bytes new.png | Bin 4776 -> 0 bytes node/config.go | 37 ++++ node/dev_console.go | 253 ++++++++++++++++++++++ node/ethereum.go | 158 ++++++++++++++ node/node | Bin 0 -> 8154988 bytes qml/test_app.qml | 35 --- qml/transactions.qml | 9 - qml/wallet.qml | 408 ----------------------------------- test_runner.go | 35 --- test_runner_test.go | 36 ---- testing.go | 33 --- tx.png | Bin 4070 -> 0 bytes ui/gui.go | 218 ------------------- ui/library.go | 60 ------ ui/ui_lib.go | 76 ------- utils/keys.go | 50 +++++ 37 files changed, 1469 insertions(+), 1435 deletions(-) delete mode 100644 Makefile delete mode 100644 config.go delete mode 100644 dev_console.go create mode 100644 ethereal/Makefile create mode 100644 ethereal/assets/facet.png create mode 100644 ethereal/assets/net.png create mode 100644 ethereal/assets/network.png create mode 100644 ethereal/assets/new.png create mode 100644 ethereal/assets/qml/test_app.qml create mode 100644 ethereal/assets/qml/transactions.qml create mode 100644 ethereal/assets/qml/wallet.qml create mode 100644 ethereal/assets/tx.png create mode 100644 ethereal/config.go create mode 100644 ethereal/ethereum.go create mode 100644 ethereal/ui/gui.go create mode 100644 ethereal/ui/library.go create mode 100644 ethereal/ui/ui_lib.go delete mode 100644 ethereum.go delete mode 100644 facet.png delete mode 100644 net.png delete mode 100644 network.png delete mode 100644 new.png create mode 100644 node/config.go create mode 100644 node/dev_console.go create mode 100644 node/ethereum.go create mode 100755 node/node delete mode 100644 qml/test_app.qml delete mode 100644 qml/transactions.qml delete mode 100644 qml/wallet.qml delete mode 100644 test_runner.go delete mode 100644 test_runner_test.go delete mode 100644 testing.go delete mode 100644 tx.png delete mode 100644 ui/gui.go delete mode 100644 ui/library.go delete mode 100644 ui/ui_lib.go create mode 100644 utils/keys.go diff --git a/Makefile b/Makefile deleted file mode 100644 index 02d127963..000000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -UNAME = $(shell uname) - -# Default is building -all: - go install - -install: -# Linux build -ifeq ($(UNAME),Linux) - mkdir -p /usr/local/ethereal - files=(net.png network.png new.png tx.png) - for file in "${files[@]}"; do - cp $file /usr/share/ethereal - done - cp -r qml /usr/share/ethereal/qml - cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal -endif -# OS X build -ifeq ($(UNAME),Darwin) - # Execute py script -endif diff --git a/config.go b/config.go deleted file mode 100644 index bafc3e300..000000000 --- a/config.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "flag" -) - -var StartConsole bool -var StartMining bool -var UseUPnP bool -var OutboundPort string -var ShowGenesis bool -var AddPeer string -var MaxPeer int -var GenAddr bool -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") - flag.BoolVar(&StartMining, "m", false, "start dagger mining") - flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") - flag.BoolVar(&UseGui, "gui", true, "use the gui") - flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") - flag.BoolVar(&UseSeed, "seed", true, "seed peers") - 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") - - flag.Parse() -} diff --git a/dev_console.go b/dev_console.go deleted file mode 100644 index ead4b55e5..000000000 --- a/dev_console.go +++ /dev/null @@ -1,253 +0,0 @@ -package main - -import ( - "bufio" - "bytes" - "encoding/hex" - "errors" - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethdb" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" - _ "math/big" - "os" - "strings" -) - -type Console struct { - db *ethdb.MemDatabase - trie *ethutil.Trie - ethereum *eth.Ethereum -} - -func NewConsole(s *eth.Ethereum) *Console { - db, _ := ethdb.NewMemDatabase() - trie := ethutil.NewTrie(db, "") - - return &Console{db: db, trie: trie, ethereum: s} -} - -func (i *Console) ValidateInput(action string, argumentLength int) error { - err := false - var expArgCount int - - switch { - case action == "update" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "get" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "dag" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "decode" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "encode" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "gettx" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "tx" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "getaddr" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "contract" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "say" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "addp" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "block" && argumentLength != 1: - err = true - expArgCount = 1 - } - - if err { - return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) - } else { - return nil - } -} - -func (i *Console) Editor() []string { - var buff bytes.Buffer - for { - reader := bufio.NewReader(os.Stdin) - str, _, err := reader.ReadLine() - if len(str) > 0 { - buff.Write(str) - buff.WriteString("\n") - } - - if err != nil && err.Error() == "EOF" { - break - } - } - - scanner := bufio.NewScanner(strings.NewReader(buff.String())) - scanner.Split(bufio.ScanLines) - - var lines []string - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - - return lines -} - -func (i *Console) PrintRoot() { - root := ethutil.NewValue(i.trie.Root) - if len(root.Bytes()) != 0 { - fmt.Println(hex.EncodeToString(root.Bytes())) - } else { - fmt.Println(i.trie.Root) - } -} - -func (i *Console) ParseInput(input string) bool { - scanner := bufio.NewScanner(strings.NewReader(input)) - scanner.Split(bufio.ScanWords) - - count := 0 - var tokens []string - for scanner.Scan() { - count++ - tokens = append(tokens, scanner.Text()) - } - if err := scanner.Err(); err != nil { - fmt.Fprintln(os.Stderr, "reading input:", err) - } - - if len(tokens) == 0 { - return true - } - - err := i.ValidateInput(tokens[0], count-1) - if err != nil { - fmt.Println(err) - } else { - switch tokens[0] { - case "update": - i.trie.Update(tokens[1], tokens[2]) - - i.PrintRoot() - case "get": - fmt.Println(i.trie.Get(tokens[1])) - case "root": - i.PrintRoot() - case "rawroot": - fmt.Println(i.trie.Root) - case "print": - i.db.Print() - case "dag": - fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash - ethutil.BigPow(2, 36), // diff - ethutil.Big(tokens[2]))) // nonce - case "decode": - value := ethutil.NewValueFromBytes([]byte(tokens[1])) - fmt.Println(value) - case "getaddr": - encoded, _ := hex.DecodeString(tokens[1]) - addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) - fmt.Println("addr:", addr) - case "block": - encoded, _ := hex.DecodeString(tokens[1]) - block := i.ethereum.BlockChain().GetBlock(encoded) - info := block.BlockInfo() - fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) - case "say": - i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) - case "addp": - i.ethereum.ConnectToPeer(tokens[1]) - case "pcount": - fmt.Println("peers:", i.ethereum.Peers().Len()) - case "encode": - fmt.Printf("%q\n", ethutil.Encode(tokens[1])) - case "tx": - recipient, err := hex.DecodeString(tokens[1]) - if err != nil { - fmt.Println("recipient err:", err) - } else { - tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) - - key := ethutil.Config.Db.GetKeys()[0] - tx.Sign(key.PrivateKey) - i.ethereum.TxPool().QueueTransaction(tx) - - fmt.Printf("%x\n", tx.Hash()) - } - case "gettx": - addr, _ := hex.DecodeString(tokens[1]) - data, _ := ethutil.Config.Db.Get(addr) - if len(data) != 0 { - decoder := ethutil.NewValueFromBytes(data) - fmt.Println(decoder) - } else { - fmt.Println("gettx: tx not found") - } - case "contract": - fmt.Println("Contract editor (Ctrl-D = done)") - code := ethchain.Compile(i.Editor()) - - contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) - - key := ethutil.Config.Db.GetKeys()[0] - contract.Sign(key.PrivateKey) - - i.ethereum.TxPool().QueueTransaction(contract) - - fmt.Printf("%x\n", contract.Hash()[12:]) - case "exit", "quit", "q": - return false - case "help": - fmt.Printf("COMMANDS:\n" + - "\033[1m= DB =\033[0m\n" + - "update KEY VALUE - Updates/Creates a new value for the given key\n" + - "get KEY - Retrieves the given key\n" + - "root - Prints the hex encoded merkle root\n" + - "rawroot - Prints the raw merkle root\n" + - "block HASH - Prints the block\n" + - "getaddr ADDR - Prints the account associated with the address\n" + - "\033[1m= Dagger =\033[0m\n" + - "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + - "\033[1m= Encoding =\033[0m\n" + - "decode STR\n" + - "encode STR\n" + - "\033[1m= Other =\033[0m\n" + - "addp HOST:PORT\n" + - "tx TO AMOUNT\n" + - "contract AMOUNT\n") - - default: - fmt.Println("Unknown command:", tokens[0]) - } - } - - return true -} - -func (i *Console) Start() { - fmt.Printf("Eth Console. Type (help) for help\n") - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("eth >>> ") - str, _, err := reader.ReadLine() - if err != nil { - fmt.Println("Error reading input", err) - } else { - if !i.ParseInput(string(str)) { - return - } - } - } -} diff --git a/ethereal/Makefile b/ethereal/Makefile new file mode 100644 index 000000000..02d127963 --- /dev/null +++ b/ethereal/Makefile @@ -0,0 +1,21 @@ +UNAME = $(shell uname) + +# Default is building +all: + go install + +install: +# Linux build +ifeq ($(UNAME),Linux) + mkdir -p /usr/local/ethereal + files=(net.png network.png new.png tx.png) + for file in "${files[@]}"; do + cp $file /usr/share/ethereal + done + cp -r qml /usr/share/ethereal/qml + cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal +endif +# OS X build +ifeq ($(UNAME),Darwin) + # Execute py script +endif diff --git a/ethereal/assets/facet.png b/ethereal/assets/facet.png new file mode 100644 index 000000000..49a266e96 Binary files /dev/null and b/ethereal/assets/facet.png differ diff --git a/ethereal/assets/net.png b/ethereal/assets/net.png new file mode 100644 index 000000000..65a20ea00 Binary files /dev/null and b/ethereal/assets/net.png differ diff --git a/ethereal/assets/network.png b/ethereal/assets/network.png new file mode 100644 index 000000000..0a9ffe2ec Binary files /dev/null and b/ethereal/assets/network.png differ diff --git a/ethereal/assets/new.png b/ethereal/assets/new.png new file mode 100644 index 000000000..e80096748 Binary files /dev/null and b/ethereal/assets/new.png differ diff --git a/ethereal/assets/qml/test_app.qml b/ethereal/assets/qml/test_app.qml new file mode 100644 index 000000000..aace4e881 --- /dev/null +++ b/ethereal/assets/qml/test_app.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; +import Ethereum 1.0 + +ApplicationWindow { + minimumWidth: 500 + maximumWidth: 500 + maximumHeight: 100 + minimumHeight: 100 + + title: "Ethereum Dice" + + TextField { + id: textField + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "Amount" + } + Label { + id: txHash + anchors.bottom: textField.top + anchors.bottomMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + } + Button { + anchors.top: textField.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 5 + text: "Place bet" + onClicked: { + txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", textField.text) + } + } +} diff --git a/ethereal/assets/qml/transactions.qml b/ethereal/assets/qml/transactions.qml new file mode 100644 index 000000000..e9a035a85 --- /dev/null +++ b/ethereal/assets/qml/transactions.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; + +Rectangle { + id: transactionView + visible: false + Text { text: "TX VIEW" } +} diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml new file mode 100644 index 000000000..7fc7f5447 --- /dev/null +++ b/ethereal/assets/qml/wallet.qml @@ -0,0 +1,408 @@ +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 + +ApplicationWindow { + id: root + + width: 900 + height: 600 + minimumHeight: 300 + + title: "Ethereal" + + 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() + } + } + + Menu { + title: "Help" + MenuItem { + text: "About" + onTriggered: { + aboutWin.visible = true + } + } + } + + } + + + property var blockModel: ListModel { + id: blockModel + } + + function setView(view) { + networkView.visible = false + historyView.visible = false + newTxView.visible = false + view.visible = true + //root.title = "Ethereal - " = view.title + } + + SplitView { + anchors.fill: parent + resizing: false + + Rectangle { + id: menu + Layout.minimumWidth: 80 + Layout.maximumWidth: 80 + anchors.bottom: parent.bottom + anchors.top: parent.top + //color: "#D9DDE7" + color: "#252525" + + ColumnLayout { + y: 50 + anchors.left: parent.left + anchors.right: parent.right + height: 200 + Image { + source: ui.assetPath("tx.png") + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(historyView) + } + } + } + Image { + source: ui.assetPath("new.png") + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(newTxView) + } + } + } + Image { + source: ui.assetPath("net.png") + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(networkView) + } + } + } + } + } + + Rectangle { + id: mainView + color: "#00000000" + anchors.right: parent.right + anchors.left: menu.right + anchors.bottom: parent.bottom + anchors.top: parent.top + + property var txModel: ListModel { + id: txModel + } + + Rectangle { + id: historyView + anchors.fill: parent + + property var title: "Transactions" + TableView { + id: txTableView + anchors.fill: parent + TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } + TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } + + model: txModel + } + } + + 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 + TextField { + id: txAmount + width: 200 + placeholderText: "Amount" + } + + TextField { + id: txReceiver + placeholderText: "Receiver Address (or empty for contract)" + Layout.fillWidth: true + } + + 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.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 + } + */ + } + + property var logModel: ListModel { + id: logModel + } + + TableView { + id: logView + width: parent.width + height: 150 + anchors.bottom: parent.bottom + TableViewColumn{ role: "description" ; title: "log" } + + model: 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) + } + } + + onAddPlugin: { + var pluginWin = pluginWindow.createObject(mainView) + console.log(pluginWin) + pluginWin.pluginTitle.text = "Test" + } + */ + } + } + + FileDialog { + id: openAppDialog + title: "Open QML Application" + onAccepted: { + ui.open(openAppDialog.fileUrl.toString()) + } + } + + statusBar: StatusBar { + RowLayout { + anchors.fill: parent + Button { + property var enabled: true + id: connectButton + onClicked: { + if(this.enabled) { + ui.connect(this) + } + } + text: "Connect" + } + + Button { + id: importAppButton + anchors.left: connectButton.right + anchors.leftMargin: 5 + onClicked: openAppDialog.open() + text: "Import App" + } + + Label { + anchors.left: importAppButton.right + anchors.leftMargin: 5 + id: walletValueLabel + } + + Label { + anchors.right: peerImage.left + anchors.rightMargin: 5 + id: peerLabel + font.pixelSize: 8 + text: "0 / 0" + } + Image { + id: peerImage + anchors.right: parent.right + width: 10; height: 10 + source: ui.assetPath("network.png") + } + } + } + + Window { + id: popup + visible: false + property var block + Label { + id: hashLabel + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + } + + 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" + onAccepted: { + ui.connectToPeer(addrField.text) + addPeerWin.visible = false + } + } + Button { + anchors.left: addrField.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 5 + text: "Add" + onClicked: { + ui.connectToPeer(addrField.text) + addPeerWin.visible = false + } + } + Component.onCompleted: { + addrField.focus = true + } + } + + Window { + id: aboutWin + visible: false + title: "About" + minimumWidth: 350 + maximumWidth: 350 + maximumHeight: 200 + minimumHeight: 200 + + Image { + id: aboutIcon + height: 150 + width: 150 + fillMode: Image.PreserveAspectFit + smooth: true + source: ui.assetPath("facet.png") + x: 10 + y: 10 + } + + Text { + anchors.left: aboutIcon.right + anchors.leftMargin: 10 + font.pointSize: 12 + text: "

Ethereum(Go)


Development

Jeffrey Wilcke

Binary Distribution

Jarrad Hope
" + } + + } + + function loadPlugin(name) { + console.log("Loading plugin" + name) + mainView.addPlugin(name) + } + + function setWalletValue(value) { + walletValueLabel.text = value + } + + function addTx(tx) { + txModel.insert(0, {hash: tx.hash, address: tx.address, value: tx.value}) + } + + function addBlock(block) { + blockModel.insert(0, {number: block.number, hash: block.hash}) + } + + function addLog(str) { + if(str.len != 0) { + logModel.append({description: str}) + } + } + + function setPeers(text) { + peerLabel.text = text + } +} diff --git a/ethereal/assets/tx.png b/ethereal/assets/tx.png new file mode 100644 index 000000000..62204c315 Binary files /dev/null and b/ethereal/assets/tx.png differ diff --git a/ethereal/config.go b/ethereal/config.go new file mode 100644 index 000000000..a534bb182 --- /dev/null +++ b/ethereal/config.go @@ -0,0 +1,34 @@ +package main + +import ( + "flag" +) + +var StartConsole bool +var StartMining bool +var UseUPnP bool +var OutboundPort string +var ShowGenesis bool +var AddPeer string +var MaxPeer int +var GenAddr bool +var UseSeed bool +var ImportKey string +var ExportKey bool +var DataDir string + +func Init() { + flag.BoolVar(&StartConsole, "c", false, "debug and testing console") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") + flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.BoolVar(&UseSeed, "seed", true, "seed peers") + 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", ".ethereal", "ethereum data directory") + flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") + flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") + + flag.Parse() +} diff --git a/ethereal/ethereum.go b/ethereal/ethereum.go new file mode 100644 index 000000000..618d2b00f --- /dev/null +++ b/ethereal/ethereum.go @@ -0,0 +1,110 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/go-ethereum/ethereal/ui" + "github.com/ethereum/go-ethereum/utils" + "github.com/niemeyer/qml" + "log" + "os" + "os/signal" + "runtime" +) + +const Debug = true + +// Register interrupt handlers so we can stop the ethereum +func RegisterInterupts(s *eth.Ethereum) { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Printf("Shutting down (%v) ... \n", sig) + + s.Stop() + } + }() +} + +func main() { + Init() + + qml.Init(nil) + + runtime.GOMAXPROCS(runtime.NumCPU()) + + ethchain.InitFees() + ethutil.ReadConfig(DataDir) + ethutil.Config.Seed = UseSeed + + // Instantiated a eth stack + ethereum, err := eth.New(eth.CapDefault, UseUPnP) + if err != nil { + log.Println("eth start err:", err) + return + } + ethereum.Port = OutboundPort + + if GenAddr { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.CreateKeyPair(true) + } + os.Exit(0) + } else { + if len(ImportKey) > 0 { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.ImportPrivateKey(ImportKey) + os.Exit(0) + } + } else { + utils.CreateKeyPair(false) + } + } + + if ExportKey { + key := ethutil.Config.Db.GetKeys()[0] + fmt.Printf("%x\n", key.PrivateKey) + os.Exit(0) + } + + if ShowGenesis { + fmt.Println(ethereum.BlockChain().Genesis()) + os.Exit(0) + } + + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + + // Set the max peers + ethereum.MaxPeers = MaxPeer + + gui := ethui.New(ethereum) + gui.Start() +} diff --git a/ethereal/ui/gui.go b/ethereal/ui/gui.go new file mode 100644 index 000000000..c8f4bedab --- /dev/null +++ b/ethereal/ui/gui.go @@ -0,0 +1,218 @@ +package ethui + +import ( + "bytes" + "encoding/hex" + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethdb" + "github.com/ethereum/eth-go/ethutil" + "github.com/niemeyer/qml" + "math/big" + "strings" +) + +// Block interface exposed to QML +type Block struct { + Number int + Hash string +} + +type Tx struct { + Value, Hash, Address string +} + +func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { + hash := hex.EncodeToString(tx.Hash()) + sender := hex.EncodeToString(tx.Recipient) + + return &Tx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender} +} + +// Creates a new QML Block from a chain block +func NewBlockFromBlock(block *ethchain.Block) *Block { + info := block.BlockInfo() + hash := hex.EncodeToString(block.Hash()) + + 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 + + txDb *ethdb.LDBDatabase + + addr []byte +} + +// Create GUI, but doesn't start it +func New(ethereum *eth.Ethereum) *Gui { + lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} + db, err := ethdb.NewLDBDatabase("tx_database") + if err != nil { + panic(err) + } + + key := ethutil.Config.Db.GetKeys()[0] + addr := key.Address() + + ethereum.StateManager().WatchAddr(addr) + + return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} +} + +func (ui *Gui) Start() { + defer ui.txDb.Close() + + // Register ethereum functions + qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ + Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, + }, { + Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, + }}) + + ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.1")) + ethutil.Config.Log.Infoln("[GUI] Starting GUI") + // Create a new QML engine + ui.engine = qml.NewEngine() + 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}) + + // Load the main QML interface + component, err := ui.engine.LoadFile(AssetPath("qml/wallet.qml")) + if err != nil { + panic(err) + } + ui.engine.LoadFile(AssetPath("qml/transactions.qml")) + + ui.win = component.CreateWindow(nil) + + // Register the ui as a block processor + //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 + ethutil.Config.Log.AddLogSystem(ui) + + // Loads previous blocks + go ui.setInitialBlockChain() + go ui.readPreviousTransactions() + go ui.update() + + ui.win.Show() + ui.win.Wait() + + ui.eth.Stop() +} + +func (ui *Gui) setInitialBlockChain() { + // Load previous 10 blocks + chain := ui.eth.BlockChain().GetChain(ui.eth.BlockChain().CurrentBlock.Hash(), 10) + for _, block := range chain { + ui.ProcessBlock(block) + } + +} + +func (ui *Gui) readPreviousTransactions() { + it := ui.txDb.Db().NewIterator(nil, nil) + for it.Next() { + tx := ethchain.NewTransactionFromBytes(it.Value()) + + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + } + it.Release() +} + +func (ui *Gui) ProcessBlock(block *ethchain.Block) { + ui.win.Root().Call("addBlock", NewBlockFromBlock(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) + + 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 { + select { + case txMsg := <-txChan: + tx := txMsg.Tx + + if txMsg.Type == ethchain.TxPre { + if bytes.Compare(tx.Sender(), ui.addr) == 0 { + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + + 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)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + + unconfirmedFunds.Add(unconfirmedFunds, tx.Value) + } + + pos := "+" + if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 { + pos = "-" + } + val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds))) + str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(account.Amount), pos, val) + + ui.win.Root().Call("setWalletValue", str) + } else { + amount := account.Amount + if bytes.Compare(tx.Sender(), ui.addr) == 0 { + amount.Sub(account.Amount, tx.Value) + } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { + amount.Add(account.Amount, tx.Value) + } + + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + } + } + + /* + accountAmount := ui.eth.BlockManager.GetAddrState(ui.addr).Account.Amount + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", accountAmount)) + + ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) + + time.Sleep(1 * time.Second) + */ + + } +} + +// Logging functions that log directly to the GUI interface +func (ui *Gui) Println(v ...interface{}) { + 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") + lines := strings.Split(str, "\n") + for _, line := range lines { + ui.win.Root().Call("addLog", line) + } +} diff --git a/ethereal/ui/library.go b/ethereal/ui/library.go new file mode 100644 index 000000000..05fffd579 --- /dev/null +++ b/ethereal/ui/library.go @@ -0,0 +1,60 @@ +package ethui + +import ( + "encoding/hex" + "fmt" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "strings" +) + +type EthLib struct { + stateManager *ethchain.StateManager + blockChain *ethchain.BlockChain + txPool *ethchain.TxPool +} + +func (lib *EthLib) CreateTx(receiver, a, data string) string { + var hash []byte + if len(receiver) == 0 { + hash = ethchain.ContractAddr + } else { + var err error + hash, err = hex.DecodeString(receiver) + if err != nil { + return err.Error() + } + } + + k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyPair := ethutil.NewKeyFromBytes(k) + + amount := ethutil.Big(a) + code := ethchain.Compile(strings.Split(data, "\n")) + tx := ethchain.NewTransaction(hash, amount, code) + tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce + + tx.Sign(keyPair.PrivateKey) + + lib.txPool.QueueTransaction(tx) + + if len(receiver) == 0 { + 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) GetBlock(hexHash string) *Block { + hash, err := hex.DecodeString(hexHash) + if err != nil { + return nil + } + + block := lib.blockChain.GetBlock(hash) + fmt.Println(block) + + return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} +} diff --git a/ethereal/ui/ui_lib.go b/ethereal/ui/ui_lib.go new file mode 100644 index 000000000..3997191fa --- /dev/null +++ b/ethereal/ui/ui_lib.go @@ -0,0 +1,76 @@ +package ethui + +import ( + "bitbucket.org/kardianos/osext" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethutil" + "github.com/niemeyer/qml" + "os" + "path" + "path/filepath" + "runtime" +) + +// 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 { + ethutil.Config.Log.Debugln(err) + } + win := component.CreateWindow(nil) + + go func() { + win.Show() + win.Wait() + }() +} + +func (ui *UiLib) Connect(button qml.Object) { + if !ui.connected { + ui.eth.Start() + ui.connected = true + button.Set("enabled", false) + } +} + +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 + + // If the current working directory is the go-ethereum dir + // assume a debug build and use the source directory as + // asset directory. + pwd, _ := os.Getwd() + if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal") { + base = path.Join(pwd, "assets") + } else { + switch runtime.GOOS { + case "darwin": + // Get Binary Directory + exedir, _ := osext.ExecutableFolder() + base = filepath.Join(exedir, "../Resources") + case "linux": + base = "/usr/share/ethereal" + case "window": + fallthrough + default: + base = "." + } + } + + return path.Join(base, p) +} diff --git a/ethereum.go b/ethereum.go deleted file mode 100644 index ac1de5af4..000000000 --- a/ethereum.go +++ /dev/null @@ -1,215 +0,0 @@ -package main - -import ( - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" - "github.com/ethereum/go-ethereum/ui" - "github.com/niemeyer/qml" - "github.com/obscuren/secp256k1-go" - "log" - "os" - "os/signal" - "runtime" -) - -const Debug = true - -// Register interrupt handlers so we can stop the ethereum -func RegisterInterupts(s *eth.Ethereum) { - // Buffered chan of one is enough - c := make(chan os.Signal, 1) - // Notify about interrupts for now - signal.Notify(c, os.Interrupt) - go func() { - for sig := range c { - fmt.Printf("Shutting down (%v) ... \n", sig) - - s.Stop() - } - }() -} - -func CreateKeyPair(force bool) { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - if len(data) == 0 || force { - pub, prv := secp256k1.GenerateKeyPair() - pair := ðutil.Key{PrivateKey: prv, PublicKey: pub} - ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) - - fmt.Printf(` -Generating new address and keypair. -Please keep your keys somewhere save. - -++++++++++++++++ KeyRing +++++++++++++++++++ -addr: %x -prvk: %x -pubk: %x -++++++++++++++++++++++++++++++++++++++++++++ - -`, pair.Address(), prv, pub) - - } -} - -func ImportPrivateKey(prvKey string) { - key := ethutil.FromHex(prvKey) - msg := []byte("tmp") - // Couldn't think of a better way to get the pub key - sig, _ := secp256k1.Sign(msg, key) - pub, _ := secp256k1.RecoverPubkey(msg, sig) - pair := ðutil.Key{PrivateKey: key, PublicKey: pub} - ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) - - fmt.Printf(` -Importing private key - -++++++++++++++++ KeyRing +++++++++++++++++++ -addr: %x -prvk: %x -pubk: %x -++++++++++++++++++++++++++++++++++++++++++++ - -`, pair.Address(), key, pub) -} - -func main() { - Init() - - // Qt has to be initialized in the main thread or it will throw errors - // It has to be called BEFORE setting the maximum procs. - if UseGui { - qml.Init(nil) - } - - runtime.GOMAXPROCS(runtime.NumCPU()) - - ethchain.InitFees() - ethutil.ReadConfig(DataDir) - ethutil.Config.Seed = UseSeed - - // Instantiated a eth stack - ethereum, err := eth.New(eth.CapDefault, UseUPnP) - if err != nil { - log.Println("eth start err:", err) - return - } - ethereum.Port = OutboundPort - - if GenAddr { - fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") - - var r string - fmt.Scanln(&r) - for ; ; fmt.Scanln(&r) { - if r == "n" || r == "y" { - break - } else { - fmt.Printf("Yes or no?", r) - } - } - - if r == "y" { - CreateKeyPair(true) - } - os.Exit(0) - } else { - if len(ImportKey) > 0 { - fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") - var r string - fmt.Scanln(&r) - for ; ; fmt.Scanln(&r) { - if r == "n" || r == "y" { - break - } else { - fmt.Printf("Yes or no?", r) - } - } - - if r == "y" { - ImportPrivateKey(ImportKey) - os.Exit(0) - } - } else { - CreateKeyPair(false) - } - } - - if ExportKey { - key := ethutil.Config.Db.GetKeys()[0] - fmt.Printf("%x\n", key.PrivateKey) - os.Exit(0) - } - - if ShowGenesis { - fmt.Println(ethereum.BlockChain().Genesis()) - os.Exit(0) - } - - log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) - - // Set the max peers - ethereum.MaxPeers = MaxPeer - - if StartConsole { - err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) - // Error is OK if the error is ErrExist - if err != nil && !os.IsExist(err) { - log.Panic("Unable to create EXECPATH:", err) - } - - console := NewConsole(ethereum) - go console.Start() - } - - if UseGui { - gui := ethui.New(ethereum) - gui.Start() - //ethereum.Stop() - } else { - RegisterInterupts(ethereum) - ethereum.Start() - - if StartMining { - log.Printf("Miner started\n") - - // Fake block mining. It broadcasts a new block every 5 seconds - go func() { - pow := ðchain.EasyPow{} - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() - - for { - txs := ethereum.TxPool().Flush() - // 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()) - 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) - if err != nil { - log.Println(err) - } else { - log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) - log.Printf("🔨 Mined block %x\n", block.Hash()) - } - } - }() - } - - // Wait for shutdown - ethereum.WaitForShutdown() - } -} diff --git a/facet.png b/facet.png deleted file mode 100644 index 49a266e96..000000000 Binary files a/facet.png and /dev/null differ diff --git a/net.png b/net.png deleted file mode 100644 index 65a20ea00..000000000 Binary files a/net.png and /dev/null differ diff --git a/network.png b/network.png deleted file mode 100644 index 0a9ffe2ec..000000000 Binary files a/network.png and /dev/null differ diff --git a/new.png b/new.png deleted file mode 100644 index e80096748..000000000 Binary files a/new.png and /dev/null differ diff --git a/node/config.go b/node/config.go new file mode 100644 index 000000000..e4935dfed --- /dev/null +++ b/node/config.go @@ -0,0 +1,37 @@ +package main + +import ( + "flag" +) + +var StartConsole bool +var StartMining bool +var UseUPnP bool +var OutboundPort string +var ShowGenesis bool +var AddPeer string +var MaxPeer int +var GenAddr bool +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") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") + //flag.BoolVar(&UseGui, "gui", true, "use the gui") + flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.BoolVar(&UseSeed, "seed", true, "seed peers") + 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") + + flag.Parse() +} diff --git a/node/dev_console.go b/node/dev_console.go new file mode 100644 index 000000000..ead4b55e5 --- /dev/null +++ b/node/dev_console.go @@ -0,0 +1,253 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/hex" + "errors" + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethdb" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" + _ "math/big" + "os" + "strings" +) + +type Console struct { + db *ethdb.MemDatabase + trie *ethutil.Trie + ethereum *eth.Ethereum +} + +func NewConsole(s *eth.Ethereum) *Console { + db, _ := ethdb.NewMemDatabase() + trie := ethutil.NewTrie(db, "") + + return &Console{db: db, trie: trie, ethereum: s} +} + +func (i *Console) ValidateInput(action string, argumentLength int) error { + err := false + var expArgCount int + + switch { + case action == "update" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "get" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "dag" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "decode" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "encode" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "gettx" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "tx" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "getaddr" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "contract" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "say" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "addp" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "block" && argumentLength != 1: + err = true + expArgCount = 1 + } + + if err { + return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) + } else { + return nil + } +} + +func (i *Console) Editor() []string { + var buff bytes.Buffer + for { + reader := bufio.NewReader(os.Stdin) + str, _, err := reader.ReadLine() + if len(str) > 0 { + buff.Write(str) + buff.WriteString("\n") + } + + if err != nil && err.Error() == "EOF" { + break + } + } + + scanner := bufio.NewScanner(strings.NewReader(buff.String())) + scanner.Split(bufio.ScanLines) + + var lines []string + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + return lines +} + +func (i *Console) PrintRoot() { + root := ethutil.NewValue(i.trie.Root) + if len(root.Bytes()) != 0 { + fmt.Println(hex.EncodeToString(root.Bytes())) + } else { + fmt.Println(i.trie.Root) + } +} + +func (i *Console) ParseInput(input string) bool { + scanner := bufio.NewScanner(strings.NewReader(input)) + scanner.Split(bufio.ScanWords) + + count := 0 + var tokens []string + for scanner.Scan() { + count++ + tokens = append(tokens, scanner.Text()) + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "reading input:", err) + } + + if len(tokens) == 0 { + return true + } + + err := i.ValidateInput(tokens[0], count-1) + if err != nil { + fmt.Println(err) + } else { + switch tokens[0] { + case "update": + i.trie.Update(tokens[1], tokens[2]) + + i.PrintRoot() + case "get": + fmt.Println(i.trie.Get(tokens[1])) + case "root": + i.PrintRoot() + case "rawroot": + fmt.Println(i.trie.Root) + case "print": + i.db.Print() + case "dag": + fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash + ethutil.BigPow(2, 36), // diff + ethutil.Big(tokens[2]))) // nonce + case "decode": + value := ethutil.NewValueFromBytes([]byte(tokens[1])) + fmt.Println(value) + case "getaddr": + encoded, _ := hex.DecodeString(tokens[1]) + addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) + fmt.Println("addr:", addr) + case "block": + encoded, _ := hex.DecodeString(tokens[1]) + block := i.ethereum.BlockChain().GetBlock(encoded) + info := block.BlockInfo() + fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) + case "say": + i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) + case "addp": + i.ethereum.ConnectToPeer(tokens[1]) + case "pcount": + fmt.Println("peers:", i.ethereum.Peers().Len()) + case "encode": + fmt.Printf("%q\n", ethutil.Encode(tokens[1])) + case "tx": + recipient, err := hex.DecodeString(tokens[1]) + if err != nil { + fmt.Println("recipient err:", err) + } else { + tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) + + key := ethutil.Config.Db.GetKeys()[0] + tx.Sign(key.PrivateKey) + i.ethereum.TxPool().QueueTransaction(tx) + + fmt.Printf("%x\n", tx.Hash()) + } + case "gettx": + addr, _ := hex.DecodeString(tokens[1]) + data, _ := ethutil.Config.Db.Get(addr) + if len(data) != 0 { + decoder := ethutil.NewValueFromBytes(data) + fmt.Println(decoder) + } else { + fmt.Println("gettx: tx not found") + } + case "contract": + fmt.Println("Contract editor (Ctrl-D = done)") + code := ethchain.Compile(i.Editor()) + + contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) + + key := ethutil.Config.Db.GetKeys()[0] + contract.Sign(key.PrivateKey) + + i.ethereum.TxPool().QueueTransaction(contract) + + fmt.Printf("%x\n", contract.Hash()[12:]) + case "exit", "quit", "q": + return false + case "help": + fmt.Printf("COMMANDS:\n" + + "\033[1m= DB =\033[0m\n" + + "update KEY VALUE - Updates/Creates a new value for the given key\n" + + "get KEY - Retrieves the given key\n" + + "root - Prints the hex encoded merkle root\n" + + "rawroot - Prints the raw merkle root\n" + + "block HASH - Prints the block\n" + + "getaddr ADDR - Prints the account associated with the address\n" + + "\033[1m= Dagger =\033[0m\n" + + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + + "\033[1m= Encoding =\033[0m\n" + + "decode STR\n" + + "encode STR\n" + + "\033[1m= Other =\033[0m\n" + + "addp HOST:PORT\n" + + "tx TO AMOUNT\n" + + "contract AMOUNT\n") + + default: + fmt.Println("Unknown command:", tokens[0]) + } + } + + return true +} + +func (i *Console) Start() { + fmt.Printf("Eth Console. Type (help) for help\n") + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("eth >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + if !i.ParseInput(string(str)) { + return + } + } + } +} diff --git a/node/ethereum.go b/node/ethereum.go new file mode 100644 index 000000000..3f5e4a8f5 --- /dev/null +++ b/node/ethereum.go @@ -0,0 +1,158 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" + "github.com/ethereum/go-ethereum/utils" + "log" + "os" + "os/signal" + "runtime" +) + +const Debug = true + +// Register interrupt handlers so we can stop the ethereum +func RegisterInterupts(s *eth.Ethereum) { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Printf("Shutting down (%v) ... \n", sig) + + s.Stop() + } + }() +} + +func main() { + Init() + + runtime.GOMAXPROCS(runtime.NumCPU()) + + ethchain.InitFees() + ethutil.ReadConfig(DataDir) + ethutil.Config.Seed = UseSeed + + // Instantiated a eth stack + ethereum, err := eth.New(eth.CapDefault, UseUPnP) + if err != nil { + log.Println("eth start err:", err) + return + } + ethereum.Port = OutboundPort + + if GenAddr { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.CreateKeyPair(true) + } + os.Exit(0) + } else { + if len(ImportKey) > 0 { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.ImportPrivateKey(ImportKey) + os.Exit(0) + } + } else { + utils.CreateKeyPair(false) + } + } + + if ExportKey { + key := ethutil.Config.Db.GetKeys()[0] + fmt.Printf("%x\n", key.PrivateKey) + os.Exit(0) + } + + if ShowGenesis { + fmt.Println(ethereum.BlockChain().Genesis()) + os.Exit(0) + } + + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + + // Set the max peers + ethereum.MaxPeers = MaxPeer + + if StartConsole { + err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) + // Error is OK if the error is ErrExist + if err != nil && !os.IsExist(err) { + log.Panic("Unable to create EXECPATH:", err) + } + + console := NewConsole(ethereum) + go console.Start() + } + + RegisterInterupts(ethereum) + ethereum.Start() + + if StartMining { + log.Printf("Miner started\n") + + // Fake block mining. It broadcasts a new block every 5 seconds + go func() { + pow := ðchain.EasyPow{} + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() + + for { + txs := ethereum.TxPool().Flush() + // 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()) + 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) + if err != nil { + log.Println(err) + } else { + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Printf("🔨 Mined block %x\n", block.Hash()) + } + } + }() + } + + // Wait for shutdown + ethereum.WaitForShutdown() +} diff --git a/node/node b/node/node new file mode 100755 index 000000000..48452886c Binary files /dev/null and b/node/node differ diff --git a/qml/test_app.qml b/qml/test_app.qml deleted file mode 100644 index aace4e881..000000000 --- a/qml/test_app.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; -import Ethereum 1.0 - -ApplicationWindow { - minimumWidth: 500 - maximumWidth: 500 - maximumHeight: 100 - minimumHeight: 100 - - title: "Ethereum Dice" - - TextField { - id: textField - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - placeholderText: "Amount" - } - Label { - id: txHash - anchors.bottom: textField.top - anchors.bottomMargin: 5 - anchors.horizontalCenter: parent.horizontalCenter - } - Button { - anchors.top: textField.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: 5 - text: "Place bet" - onClicked: { - txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", textField.text) - } - } -} diff --git a/qml/transactions.qml b/qml/transactions.qml deleted file mode 100644 index e9a035a85..000000000 --- a/qml/transactions.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0; -import QtQuick.Layouts 1.0; - -Rectangle { - id: transactionView - visible: false - Text { text: "TX VIEW" } -} diff --git a/qml/wallet.qml b/qml/wallet.qml deleted file mode 100644 index 7fc7f5447..000000000 --- a/qml/wallet.qml +++ /dev/null @@ -1,408 +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 - -ApplicationWindow { - id: root - - width: 900 - height: 600 - minimumHeight: 300 - - title: "Ethereal" - - 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() - } - } - - Menu { - title: "Help" - MenuItem { - text: "About" - onTriggered: { - aboutWin.visible = true - } - } - } - - } - - - property var blockModel: ListModel { - id: blockModel - } - - function setView(view) { - networkView.visible = false - historyView.visible = false - newTxView.visible = false - view.visible = true - //root.title = "Ethereal - " = view.title - } - - SplitView { - anchors.fill: parent - resizing: false - - Rectangle { - id: menu - Layout.minimumWidth: 80 - Layout.maximumWidth: 80 - anchors.bottom: parent.bottom - anchors.top: parent.top - //color: "#D9DDE7" - color: "#252525" - - ColumnLayout { - y: 50 - anchors.left: parent.left - anchors.right: parent.right - height: 200 - Image { - source: ui.assetPath("tx.png") - anchors.horizontalCenter: parent.horizontalCenter - MouseArea { - anchors.fill: parent - onClicked: { - setView(historyView) - } - } - } - Image { - source: ui.assetPath("new.png") - anchors.horizontalCenter: parent.horizontalCenter - MouseArea { - anchors.fill: parent - onClicked: { - setView(newTxView) - } - } - } - Image { - source: ui.assetPath("net.png") - anchors.horizontalCenter: parent.horizontalCenter - MouseArea { - anchors.fill: parent - onClicked: { - setView(networkView) - } - } - } - } - } - - Rectangle { - id: mainView - color: "#00000000" - anchors.right: parent.right - anchors.left: menu.right - anchors.bottom: parent.bottom - anchors.top: parent.top - - property var txModel: ListModel { - id: txModel - } - - Rectangle { - id: historyView - anchors.fill: parent - - property var title: "Transactions" - TableView { - id: txTableView - anchors.fill: parent - TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } - - model: txModel - } - } - - 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 - TextField { - id: txAmount - width: 200 - placeholderText: "Amount" - } - - TextField { - id: txReceiver - placeholderText: "Receiver Address (or empty for contract)" - Layout.fillWidth: true - } - - 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.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 - } - */ - } - - property var logModel: ListModel { - id: logModel - } - - TableView { - id: logView - width: parent.width - height: 150 - anchors.bottom: parent.bottom - TableViewColumn{ role: "description" ; title: "log" } - - model: 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) - } - } - - onAddPlugin: { - var pluginWin = pluginWindow.createObject(mainView) - console.log(pluginWin) - pluginWin.pluginTitle.text = "Test" - } - */ - } - } - - FileDialog { - id: openAppDialog - title: "Open QML Application" - onAccepted: { - ui.open(openAppDialog.fileUrl.toString()) - } - } - - statusBar: StatusBar { - RowLayout { - anchors.fill: parent - Button { - property var enabled: true - id: connectButton - onClicked: { - if(this.enabled) { - ui.connect(this) - } - } - text: "Connect" - } - - Button { - id: importAppButton - anchors.left: connectButton.right - anchors.leftMargin: 5 - onClicked: openAppDialog.open() - text: "Import App" - } - - Label { - anchors.left: importAppButton.right - anchors.leftMargin: 5 - id: walletValueLabel - } - - Label { - anchors.right: peerImage.left - anchors.rightMargin: 5 - id: peerLabel - font.pixelSize: 8 - text: "0 / 0" - } - Image { - id: peerImage - anchors.right: parent.right - width: 10; height: 10 - source: ui.assetPath("network.png") - } - } - } - - Window { - id: popup - visible: false - property var block - Label { - id: hashLabel - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - } - } - - 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" - onAccepted: { - ui.connectToPeer(addrField.text) - addPeerWin.visible = false - } - } - Button { - anchors.left: addrField.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: 5 - text: "Add" - onClicked: { - ui.connectToPeer(addrField.text) - addPeerWin.visible = false - } - } - Component.onCompleted: { - addrField.focus = true - } - } - - Window { - id: aboutWin - visible: false - title: "About" - minimumWidth: 350 - maximumWidth: 350 - maximumHeight: 200 - minimumHeight: 200 - - Image { - id: aboutIcon - height: 150 - width: 150 - fillMode: Image.PreserveAspectFit - smooth: true - source: ui.assetPath("facet.png") - x: 10 - y: 10 - } - - Text { - anchors.left: aboutIcon.right - anchors.leftMargin: 10 - font.pointSize: 12 - text: "

Ethereum(Go)


Development

Jeffrey Wilcke

Binary Distribution

Jarrad Hope
" - } - - } - - function loadPlugin(name) { - console.log("Loading plugin" + name) - mainView.addPlugin(name) - } - - function setWalletValue(value) { - walletValueLabel.text = value - } - - function addTx(tx) { - txModel.insert(0, {hash: tx.hash, address: tx.address, value: tx.value}) - } - - function addBlock(block) { - blockModel.insert(0, {number: block.number, hash: block.hash}) - } - - function addLog(str) { - if(str.len != 0) { - logModel.append({description: str}) - } - } - - function setPeers(text) { - peerLabel.text = text - } -} diff --git a/test_runner.go b/test_runner.go deleted file mode 100644 index e8a1698ce..000000000 --- a/test_runner.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "testing" -) - -type TestSource struct { - Inputs map[string]string - Expectation string -} - -func NewTestSource(source string) *TestSource { - s := &TestSource{} - err := json.Unmarshal([]byte(source), s) - if err != nil { - fmt.Println(err) - } - - return s -} - -type TestRunner struct { - source *TestSource -} - -func NewTestRunner(t *testing.T) *TestRunner { - return &TestRunner{} -} - -func (runner *TestRunner) RunFromString(input string, Cb func(*TestSource)) { - source := NewTestSource(input) - Cb(source) -} diff --git a/test_runner_test.go b/test_runner_test.go deleted file mode 100644 index a5672eb7a..000000000 --- a/test_runner_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -/* -import ( - "encoding/hex" - _ "fmt" - "github.com/ethereum/ethdb-go" - "github.com/ethereum/ethutil-go" - "testing" -) - -var testsource = ` -{ - "inputs":{ - "doe": "reindeer", - "dog": "puppy", - "dogglesworth": "cat" - }, - "expectation":"e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" -}` - -func TestTestRunner(t *testing.T) { - db, _ := ethdb.NewMemDatabase() - trie := ethutil.NewTrie(db, "") - - runner := NewTestRunner(t) - runner.RunFromString(testsource, func(source *TestSource) { - for key, value := range source.Inputs { - trie.Update(key, value) - } - if hex.EncodeToString(trie.Root.([]byte)) != source.Expectation { - t.Error("trie root did not match") - } - }) -} -*/ diff --git a/testing.go b/testing.go deleted file mode 100644 index 849089a5d..000000000 --- a/testing.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -/* - -import ( - _"fmt" -) - -// This will eventually go away -var Db *MemDatabase - -func Testing() { - db, _ := NewMemDatabase() - Db = db - - bm := NewBlockManager() - - tx := NewTransaction("\x00", 20, []string{"PUSH"}) - txData := tx.RlpEncode() - //fmt.Printf("%q\n", txData) - - copyTx := &Transaction{} - copyTx.RlpDecode(txData) - //fmt.Println(tx) - //fmt.Println(copyTx) - - tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) - - blck := CreateTestBlock([]*Transaction{tx2, tx}) - - bm.ProcessBlock( blck ) -} -*/ diff --git a/tx.png b/tx.png deleted file mode 100644 index 62204c315..000000000 Binary files a/tx.png and /dev/null differ diff --git a/ui/gui.go b/ui/gui.go deleted file mode 100644 index c8f4bedab..000000000 --- a/ui/gui.go +++ /dev/null @@ -1,218 +0,0 @@ -package ethui - -import ( - "bytes" - "encoding/hex" - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethdb" - "github.com/ethereum/eth-go/ethutil" - "github.com/niemeyer/qml" - "math/big" - "strings" -) - -// Block interface exposed to QML -type Block struct { - Number int - Hash string -} - -type Tx struct { - Value, Hash, Address string -} - -func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { - hash := hex.EncodeToString(tx.Hash()) - sender := hex.EncodeToString(tx.Recipient) - - return &Tx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender} -} - -// Creates a new QML Block from a chain block -func NewBlockFromBlock(block *ethchain.Block) *Block { - info := block.BlockInfo() - hash := hex.EncodeToString(block.Hash()) - - 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 - - txDb *ethdb.LDBDatabase - - addr []byte -} - -// Create GUI, but doesn't start it -func New(ethereum *eth.Ethereum) *Gui { - lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} - db, err := ethdb.NewLDBDatabase("tx_database") - if err != nil { - panic(err) - } - - key := ethutil.Config.Db.GetKeys()[0] - addr := key.Address() - - ethereum.StateManager().WatchAddr(addr) - - return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} -} - -func (ui *Gui) Start() { - defer ui.txDb.Close() - - // Register ethereum functions - qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ - Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, - }, { - Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, - }}) - - ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.1")) - ethutil.Config.Log.Infoln("[GUI] Starting GUI") - // Create a new QML engine - ui.engine = qml.NewEngine() - 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}) - - // Load the main QML interface - component, err := ui.engine.LoadFile(AssetPath("qml/wallet.qml")) - if err != nil { - panic(err) - } - ui.engine.LoadFile(AssetPath("qml/transactions.qml")) - - ui.win = component.CreateWindow(nil) - - // Register the ui as a block processor - //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 - ethutil.Config.Log.AddLogSystem(ui) - - // Loads previous blocks - go ui.setInitialBlockChain() - go ui.readPreviousTransactions() - go ui.update() - - ui.win.Show() - ui.win.Wait() - - ui.eth.Stop() -} - -func (ui *Gui) setInitialBlockChain() { - // Load previous 10 blocks - chain := ui.eth.BlockChain().GetChain(ui.eth.BlockChain().CurrentBlock.Hash(), 10) - for _, block := range chain { - ui.ProcessBlock(block) - } - -} - -func (ui *Gui) readPreviousTransactions() { - it := ui.txDb.Db().NewIterator(nil, nil) - for it.Next() { - tx := ethchain.NewTransactionFromBytes(it.Value()) - - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - } - it.Release() -} - -func (ui *Gui) ProcessBlock(block *ethchain.Block) { - ui.win.Root().Call("addBlock", NewBlockFromBlock(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) - - 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 { - select { - case txMsg := <-txChan: - tx := txMsg.Tx - - if txMsg.Type == ethchain.TxPre { - if bytes.Compare(tx.Sender(), ui.addr) == 0 { - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - - 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)) - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - - unconfirmedFunds.Add(unconfirmedFunds, tx.Value) - } - - pos := "+" - if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 { - pos = "-" - } - val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds))) - str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(account.Amount), pos, val) - - ui.win.Root().Call("setWalletValue", str) - } else { - amount := account.Amount - if bytes.Compare(tx.Sender(), ui.addr) == 0 { - amount.Sub(account.Amount, tx.Value) - } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - amount.Add(account.Amount, tx.Value) - } - - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) - } - } - - /* - accountAmount := ui.eth.BlockManager.GetAddrState(ui.addr).Account.Amount - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", accountAmount)) - - ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) - - time.Sleep(1 * time.Second) - */ - - } -} - -// Logging functions that log directly to the GUI interface -func (ui *Gui) Println(v ...interface{}) { - 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") - lines := strings.Split(str, "\n") - for _, line := range lines { - ui.win.Root().Call("addLog", line) - } -} diff --git a/ui/library.go b/ui/library.go deleted file mode 100644 index 05fffd579..000000000 --- a/ui/library.go +++ /dev/null @@ -1,60 +0,0 @@ -package ethui - -import ( - "encoding/hex" - "fmt" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethutil" - "strings" -) - -type EthLib struct { - stateManager *ethchain.StateManager - blockChain *ethchain.BlockChain - txPool *ethchain.TxPool -} - -func (lib *EthLib) CreateTx(receiver, a, data string) string { - var hash []byte - if len(receiver) == 0 { - hash = ethchain.ContractAddr - } else { - var err error - hash, err = hex.DecodeString(receiver) - if err != nil { - return err.Error() - } - } - - k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyPair := ethutil.NewKeyFromBytes(k) - - amount := ethutil.Big(a) - code := ethchain.Compile(strings.Split(data, "\n")) - tx := ethchain.NewTransaction(hash, amount, code) - tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce - - tx.Sign(keyPair.PrivateKey) - - lib.txPool.QueueTransaction(tx) - - if len(receiver) == 0 { - 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) GetBlock(hexHash string) *Block { - hash, err := hex.DecodeString(hexHash) - if err != nil { - return nil - } - - block := lib.blockChain.GetBlock(hash) - fmt.Println(block) - - return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} -} diff --git a/ui/ui_lib.go b/ui/ui_lib.go deleted file mode 100644 index 83e8bf2d1..000000000 --- a/ui/ui_lib.go +++ /dev/null @@ -1,76 +0,0 @@ -package ethui - -import ( - "bitbucket.org/kardianos/osext" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethutil" - "github.com/niemeyer/qml" - "os" - "path" - "path/filepath" - "runtime" -) - -// 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 { - ethutil.Config.Log.Debugln(err) - } - win := component.CreateWindow(nil) - - go func() { - win.Show() - win.Wait() - }() -} - -func (ui *UiLib) Connect(button qml.Object) { - if !ui.connected { - ui.eth.Start() - ui.connected = true - button.Set("enabled", false) - } -} - -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 - - // If the current working directory is the go-ethereum dir - // assume a debug build and use the source directory as - // asset directory. - pwd, _ := os.Getwd() - if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum") { - base = pwd - } else { - switch runtime.GOOS { - case "darwin": - // Get Binary Directory - exedir, _ := osext.ExecutableFolder() - base = filepath.Join(exedir, "../Resources") - case "linux": - base = "/usr/share/ethereal" - case "window": - fallthrough - default: - base = "." - } - } - - return path.Join(base, p) -} diff --git a/utils/keys.go b/utils/keys.go new file mode 100644 index 000000000..910c8c477 --- /dev/null +++ b/utils/keys.go @@ -0,0 +1,50 @@ +package utils + +import ( + "fmt" + "github.com/ethereum/eth-go/ethutil" + "github.com/obscuren/secp256k1-go" +) + +func CreateKeyPair(force bool) { + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + if len(data) == 0 || force { + pub, prv := secp256k1.GenerateKeyPair() + pair := ðutil.Key{PrivateKey: prv, PublicKey: pub} + ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) + + fmt.Printf(` +Generating new address and keypair. +Please keep your keys somewhere save. + +++++++++++++++++ KeyRing +++++++++++++++++++ +addr: %x +prvk: %x +pubk: %x +++++++++++++++++++++++++++++++++++++++++++++ + +`, pair.Address(), prv, pub) + + } +} + +func ImportPrivateKey(prvKey string) { + key := ethutil.FromHex(prvKey) + msg := []byte("tmp") + // Couldn't think of a better way to get the pub key + sig, _ := secp256k1.Sign(msg, key) + pub, _ := secp256k1.RecoverPubkey(msg, sig) + pair := ðutil.Key{PrivateKey: key, PublicKey: pub} + ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) + + fmt.Printf(` +Importing private key + +++++++++++++++++ KeyRing +++++++++++++++++++ +addr: %x +prvk: %x +pubk: %x +++++++++++++++++++++++++++++++++++++++++++++ + +`, pair.Address(), key, pub) +} -- cgit From 45ec9c88e4bb5060455df4c12891f94fb5bb28c6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Mar 2014 12:03:03 +0100 Subject: Moved node to ethereum --- node/config.go | 37 -------- node/dev_console.go | 253 ---------------------------------------------------- node/ethereum.go | 158 -------------------------------- node/node | Bin 8154988 -> 0 bytes 4 files changed, 448 deletions(-) delete mode 100644 node/config.go delete mode 100644 node/dev_console.go delete mode 100644 node/ethereum.go delete mode 100755 node/node diff --git a/node/config.go b/node/config.go deleted file mode 100644 index e4935dfed..000000000 --- a/node/config.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "flag" -) - -var StartConsole bool -var StartMining bool -var UseUPnP bool -var OutboundPort string -var ShowGenesis bool -var AddPeer string -var MaxPeer int -var GenAddr bool -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") - flag.BoolVar(&StartMining, "m", false, "start dagger mining") - flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") - //flag.BoolVar(&UseGui, "gui", true, "use the gui") - flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") - flag.BoolVar(&UseSeed, "seed", true, "seed peers") - 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") - - flag.Parse() -} diff --git a/node/dev_console.go b/node/dev_console.go deleted file mode 100644 index ead4b55e5..000000000 --- a/node/dev_console.go +++ /dev/null @@ -1,253 +0,0 @@ -package main - -import ( - "bufio" - "bytes" - "encoding/hex" - "errors" - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethdb" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" - _ "math/big" - "os" - "strings" -) - -type Console struct { - db *ethdb.MemDatabase - trie *ethutil.Trie - ethereum *eth.Ethereum -} - -func NewConsole(s *eth.Ethereum) *Console { - db, _ := ethdb.NewMemDatabase() - trie := ethutil.NewTrie(db, "") - - return &Console{db: db, trie: trie, ethereum: s} -} - -func (i *Console) ValidateInput(action string, argumentLength int) error { - err := false - var expArgCount int - - switch { - case action == "update" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "get" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "dag" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "decode" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "encode" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "gettx" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "tx" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "getaddr" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "contract" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "say" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "addp" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "block" && argumentLength != 1: - err = true - expArgCount = 1 - } - - if err { - return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) - } else { - return nil - } -} - -func (i *Console) Editor() []string { - var buff bytes.Buffer - for { - reader := bufio.NewReader(os.Stdin) - str, _, err := reader.ReadLine() - if len(str) > 0 { - buff.Write(str) - buff.WriteString("\n") - } - - if err != nil && err.Error() == "EOF" { - break - } - } - - scanner := bufio.NewScanner(strings.NewReader(buff.String())) - scanner.Split(bufio.ScanLines) - - var lines []string - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - - return lines -} - -func (i *Console) PrintRoot() { - root := ethutil.NewValue(i.trie.Root) - if len(root.Bytes()) != 0 { - fmt.Println(hex.EncodeToString(root.Bytes())) - } else { - fmt.Println(i.trie.Root) - } -} - -func (i *Console) ParseInput(input string) bool { - scanner := bufio.NewScanner(strings.NewReader(input)) - scanner.Split(bufio.ScanWords) - - count := 0 - var tokens []string - for scanner.Scan() { - count++ - tokens = append(tokens, scanner.Text()) - } - if err := scanner.Err(); err != nil { - fmt.Fprintln(os.Stderr, "reading input:", err) - } - - if len(tokens) == 0 { - return true - } - - err := i.ValidateInput(tokens[0], count-1) - if err != nil { - fmt.Println(err) - } else { - switch tokens[0] { - case "update": - i.trie.Update(tokens[1], tokens[2]) - - i.PrintRoot() - case "get": - fmt.Println(i.trie.Get(tokens[1])) - case "root": - i.PrintRoot() - case "rawroot": - fmt.Println(i.trie.Root) - case "print": - i.db.Print() - case "dag": - fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash - ethutil.BigPow(2, 36), // diff - ethutil.Big(tokens[2]))) // nonce - case "decode": - value := ethutil.NewValueFromBytes([]byte(tokens[1])) - fmt.Println(value) - case "getaddr": - encoded, _ := hex.DecodeString(tokens[1]) - addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) - fmt.Println("addr:", addr) - case "block": - encoded, _ := hex.DecodeString(tokens[1]) - block := i.ethereum.BlockChain().GetBlock(encoded) - info := block.BlockInfo() - fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) - case "say": - i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) - case "addp": - i.ethereum.ConnectToPeer(tokens[1]) - case "pcount": - fmt.Println("peers:", i.ethereum.Peers().Len()) - case "encode": - fmt.Printf("%q\n", ethutil.Encode(tokens[1])) - case "tx": - recipient, err := hex.DecodeString(tokens[1]) - if err != nil { - fmt.Println("recipient err:", err) - } else { - tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) - - key := ethutil.Config.Db.GetKeys()[0] - tx.Sign(key.PrivateKey) - i.ethereum.TxPool().QueueTransaction(tx) - - fmt.Printf("%x\n", tx.Hash()) - } - case "gettx": - addr, _ := hex.DecodeString(tokens[1]) - data, _ := ethutil.Config.Db.Get(addr) - if len(data) != 0 { - decoder := ethutil.NewValueFromBytes(data) - fmt.Println(decoder) - } else { - fmt.Println("gettx: tx not found") - } - case "contract": - fmt.Println("Contract editor (Ctrl-D = done)") - code := ethchain.Compile(i.Editor()) - - contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) - - key := ethutil.Config.Db.GetKeys()[0] - contract.Sign(key.PrivateKey) - - i.ethereum.TxPool().QueueTransaction(contract) - - fmt.Printf("%x\n", contract.Hash()[12:]) - case "exit", "quit", "q": - return false - case "help": - fmt.Printf("COMMANDS:\n" + - "\033[1m= DB =\033[0m\n" + - "update KEY VALUE - Updates/Creates a new value for the given key\n" + - "get KEY - Retrieves the given key\n" + - "root - Prints the hex encoded merkle root\n" + - "rawroot - Prints the raw merkle root\n" + - "block HASH - Prints the block\n" + - "getaddr ADDR - Prints the account associated with the address\n" + - "\033[1m= Dagger =\033[0m\n" + - "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + - "\033[1m= Encoding =\033[0m\n" + - "decode STR\n" + - "encode STR\n" + - "\033[1m= Other =\033[0m\n" + - "addp HOST:PORT\n" + - "tx TO AMOUNT\n" + - "contract AMOUNT\n") - - default: - fmt.Println("Unknown command:", tokens[0]) - } - } - - return true -} - -func (i *Console) Start() { - fmt.Printf("Eth Console. Type (help) for help\n") - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("eth >>> ") - str, _, err := reader.ReadLine() - if err != nil { - fmt.Println("Error reading input", err) - } else { - if !i.ParseInput(string(str)) { - return - } - } - } -} diff --git a/node/ethereum.go b/node/ethereum.go deleted file mode 100644 index 3f5e4a8f5..000000000 --- a/node/ethereum.go +++ /dev/null @@ -1,158 +0,0 @@ -package main - -import ( - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" - "github.com/ethereum/go-ethereum/utils" - "log" - "os" - "os/signal" - "runtime" -) - -const Debug = true - -// Register interrupt handlers so we can stop the ethereum -func RegisterInterupts(s *eth.Ethereum) { - // Buffered chan of one is enough - c := make(chan os.Signal, 1) - // Notify about interrupts for now - signal.Notify(c, os.Interrupt) - go func() { - for sig := range c { - fmt.Printf("Shutting down (%v) ... \n", sig) - - s.Stop() - } - }() -} - -func main() { - Init() - - runtime.GOMAXPROCS(runtime.NumCPU()) - - ethchain.InitFees() - ethutil.ReadConfig(DataDir) - ethutil.Config.Seed = UseSeed - - // Instantiated a eth stack - ethereum, err := eth.New(eth.CapDefault, UseUPnP) - if err != nil { - log.Println("eth start err:", err) - return - } - ethereum.Port = OutboundPort - - if GenAddr { - fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") - - var r string - fmt.Scanln(&r) - for ; ; fmt.Scanln(&r) { - if r == "n" || r == "y" { - break - } else { - fmt.Printf("Yes or no?", r) - } - } - - if r == "y" { - utils.CreateKeyPair(true) - } - os.Exit(0) - } else { - if len(ImportKey) > 0 { - fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") - var r string - fmt.Scanln(&r) - for ; ; fmt.Scanln(&r) { - if r == "n" || r == "y" { - break - } else { - fmt.Printf("Yes or no?", r) - } - } - - if r == "y" { - utils.ImportPrivateKey(ImportKey) - os.Exit(0) - } - } else { - utils.CreateKeyPair(false) - } - } - - if ExportKey { - key := ethutil.Config.Db.GetKeys()[0] - fmt.Printf("%x\n", key.PrivateKey) - os.Exit(0) - } - - if ShowGenesis { - fmt.Println(ethereum.BlockChain().Genesis()) - os.Exit(0) - } - - log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) - - // Set the max peers - ethereum.MaxPeers = MaxPeer - - if StartConsole { - err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) - // Error is OK if the error is ErrExist - if err != nil && !os.IsExist(err) { - log.Panic("Unable to create EXECPATH:", err) - } - - console := NewConsole(ethereum) - go console.Start() - } - - RegisterInterupts(ethereum) - ethereum.Start() - - if StartMining { - log.Printf("Miner started\n") - - // Fake block mining. It broadcasts a new block every 5 seconds - go func() { - pow := ðchain.EasyPow{} - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() - - for { - txs := ethereum.TxPool().Flush() - // 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()) - 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) - if err != nil { - log.Println(err) - } else { - log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) - log.Printf("🔨 Mined block %x\n", block.Hash()) - } - } - }() - } - - // Wait for shutdown - ethereum.WaitForShutdown() -} diff --git a/node/node b/node/node deleted file mode 100755 index 48452886c..000000000 Binary files a/node/node and /dev/null differ -- cgit From 642630db15a793cf0a0f7fbd827daee364df5423 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Mar 2014 12:03:10 +0100 Subject: Moved node to ethereum --- ethereum/config.go | 37 +++++++ ethereum/dev_console.go | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ ethereum/ethereum.go | 158 ++++++++++++++++++++++++++++++ 3 files changed, 448 insertions(+) create mode 100644 ethereum/config.go create mode 100644 ethereum/dev_console.go create mode 100644 ethereum/ethereum.go diff --git a/ethereum/config.go b/ethereum/config.go new file mode 100644 index 000000000..e4935dfed --- /dev/null +++ b/ethereum/config.go @@ -0,0 +1,37 @@ +package main + +import ( + "flag" +) + +var StartConsole bool +var StartMining bool +var UseUPnP bool +var OutboundPort string +var ShowGenesis bool +var AddPeer string +var MaxPeer int +var GenAddr bool +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") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") + //flag.BoolVar(&UseGui, "gui", true, "use the gui") + flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.BoolVar(&UseSeed, "seed", true, "seed peers") + 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") + + flag.Parse() +} diff --git a/ethereum/dev_console.go b/ethereum/dev_console.go new file mode 100644 index 000000000..ead4b55e5 --- /dev/null +++ b/ethereum/dev_console.go @@ -0,0 +1,253 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/hex" + "errors" + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethdb" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" + _ "math/big" + "os" + "strings" +) + +type Console struct { + db *ethdb.MemDatabase + trie *ethutil.Trie + ethereum *eth.Ethereum +} + +func NewConsole(s *eth.Ethereum) *Console { + db, _ := ethdb.NewMemDatabase() + trie := ethutil.NewTrie(db, "") + + return &Console{db: db, trie: trie, ethereum: s} +} + +func (i *Console) ValidateInput(action string, argumentLength int) error { + err := false + var expArgCount int + + switch { + case action == "update" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "get" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "dag" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "decode" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "encode" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "gettx" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "tx" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "getaddr" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "contract" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "say" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "addp" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "block" && argumentLength != 1: + err = true + expArgCount = 1 + } + + if err { + return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) + } else { + return nil + } +} + +func (i *Console) Editor() []string { + var buff bytes.Buffer + for { + reader := bufio.NewReader(os.Stdin) + str, _, err := reader.ReadLine() + if len(str) > 0 { + buff.Write(str) + buff.WriteString("\n") + } + + if err != nil && err.Error() == "EOF" { + break + } + } + + scanner := bufio.NewScanner(strings.NewReader(buff.String())) + scanner.Split(bufio.ScanLines) + + var lines []string + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + return lines +} + +func (i *Console) PrintRoot() { + root := ethutil.NewValue(i.trie.Root) + if len(root.Bytes()) != 0 { + fmt.Println(hex.EncodeToString(root.Bytes())) + } else { + fmt.Println(i.trie.Root) + } +} + +func (i *Console) ParseInput(input string) bool { + scanner := bufio.NewScanner(strings.NewReader(input)) + scanner.Split(bufio.ScanWords) + + count := 0 + var tokens []string + for scanner.Scan() { + count++ + tokens = append(tokens, scanner.Text()) + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "reading input:", err) + } + + if len(tokens) == 0 { + return true + } + + err := i.ValidateInput(tokens[0], count-1) + if err != nil { + fmt.Println(err) + } else { + switch tokens[0] { + case "update": + i.trie.Update(tokens[1], tokens[2]) + + i.PrintRoot() + case "get": + fmt.Println(i.trie.Get(tokens[1])) + case "root": + i.PrintRoot() + case "rawroot": + fmt.Println(i.trie.Root) + case "print": + i.db.Print() + case "dag": + fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash + ethutil.BigPow(2, 36), // diff + ethutil.Big(tokens[2]))) // nonce + case "decode": + value := ethutil.NewValueFromBytes([]byte(tokens[1])) + fmt.Println(value) + case "getaddr": + encoded, _ := hex.DecodeString(tokens[1]) + addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) + fmt.Println("addr:", addr) + case "block": + encoded, _ := hex.DecodeString(tokens[1]) + block := i.ethereum.BlockChain().GetBlock(encoded) + info := block.BlockInfo() + fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) + case "say": + i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) + case "addp": + i.ethereum.ConnectToPeer(tokens[1]) + case "pcount": + fmt.Println("peers:", i.ethereum.Peers().Len()) + case "encode": + fmt.Printf("%q\n", ethutil.Encode(tokens[1])) + case "tx": + recipient, err := hex.DecodeString(tokens[1]) + if err != nil { + fmt.Println("recipient err:", err) + } else { + tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) + + key := ethutil.Config.Db.GetKeys()[0] + tx.Sign(key.PrivateKey) + i.ethereum.TxPool().QueueTransaction(tx) + + fmt.Printf("%x\n", tx.Hash()) + } + case "gettx": + addr, _ := hex.DecodeString(tokens[1]) + data, _ := ethutil.Config.Db.Get(addr) + if len(data) != 0 { + decoder := ethutil.NewValueFromBytes(data) + fmt.Println(decoder) + } else { + fmt.Println("gettx: tx not found") + } + case "contract": + fmt.Println("Contract editor (Ctrl-D = done)") + code := ethchain.Compile(i.Editor()) + + contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) + + key := ethutil.Config.Db.GetKeys()[0] + contract.Sign(key.PrivateKey) + + i.ethereum.TxPool().QueueTransaction(contract) + + fmt.Printf("%x\n", contract.Hash()[12:]) + case "exit", "quit", "q": + return false + case "help": + fmt.Printf("COMMANDS:\n" + + "\033[1m= DB =\033[0m\n" + + "update KEY VALUE - Updates/Creates a new value for the given key\n" + + "get KEY - Retrieves the given key\n" + + "root - Prints the hex encoded merkle root\n" + + "rawroot - Prints the raw merkle root\n" + + "block HASH - Prints the block\n" + + "getaddr ADDR - Prints the account associated with the address\n" + + "\033[1m= Dagger =\033[0m\n" + + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + + "\033[1m= Encoding =\033[0m\n" + + "decode STR\n" + + "encode STR\n" + + "\033[1m= Other =\033[0m\n" + + "addp HOST:PORT\n" + + "tx TO AMOUNT\n" + + "contract AMOUNT\n") + + default: + fmt.Println("Unknown command:", tokens[0]) + } + } + + return true +} + +func (i *Console) Start() { + fmt.Printf("Eth Console. Type (help) for help\n") + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("eth >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + if !i.ParseInput(string(str)) { + return + } + } + } +} diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go new file mode 100644 index 000000000..3f5e4a8f5 --- /dev/null +++ b/ethereum/ethereum.go @@ -0,0 +1,158 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" + "github.com/ethereum/go-ethereum/utils" + "log" + "os" + "os/signal" + "runtime" +) + +const Debug = true + +// Register interrupt handlers so we can stop the ethereum +func RegisterInterupts(s *eth.Ethereum) { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Printf("Shutting down (%v) ... \n", sig) + + s.Stop() + } + }() +} + +func main() { + Init() + + runtime.GOMAXPROCS(runtime.NumCPU()) + + ethchain.InitFees() + ethutil.ReadConfig(DataDir) + ethutil.Config.Seed = UseSeed + + // Instantiated a eth stack + ethereum, err := eth.New(eth.CapDefault, UseUPnP) + if err != nil { + log.Println("eth start err:", err) + return + } + ethereum.Port = OutboundPort + + if GenAddr { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.CreateKeyPair(true) + } + os.Exit(0) + } else { + if len(ImportKey) > 0 { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.ImportPrivateKey(ImportKey) + os.Exit(0) + } + } else { + utils.CreateKeyPair(false) + } + } + + if ExportKey { + key := ethutil.Config.Db.GetKeys()[0] + fmt.Printf("%x\n", key.PrivateKey) + os.Exit(0) + } + + if ShowGenesis { + fmt.Println(ethereum.BlockChain().Genesis()) + os.Exit(0) + } + + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + + // Set the max peers + ethereum.MaxPeers = MaxPeer + + if StartConsole { + err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) + // Error is OK if the error is ErrExist + if err != nil && !os.IsExist(err) { + log.Panic("Unable to create EXECPATH:", err) + } + + console := NewConsole(ethereum) + go console.Start() + } + + RegisterInterupts(ethereum) + ethereum.Start() + + if StartMining { + log.Printf("Miner started\n") + + // Fake block mining. It broadcasts a new block every 5 seconds + go func() { + pow := ðchain.EasyPow{} + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() + + for { + txs := ethereum.TxPool().Flush() + // 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()) + 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) + if err != nil { + log.Println(err) + } else { + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Printf("🔨 Mined block %x\n", block.Hash()) + } + } + }() + } + + // Wait for shutdown + ethereum.WaitForShutdown() +} -- cgit