diff --git a/Makefile b/Makefile deleted file mode 100644 index 4da4c551c..000000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -UNAME = $(shell uname) - -# Default is building -all: - go install - -install: -# Linux build -ifeq ($(UNAME),Linux) - mkdir /usr/local/ethereal - files=(wallet.qml net.png network.png new.png tx.png) - for file in "${files[@]}"; do - cp $file /usr/share/ethereal - done - cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal -endif -# OS X build -ifeq ($(UNAME),Darwin) - # Execute py script -endif diff --git a/README.md b/README.md index 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). diff --git a/ethereal/Makefile b/ethereal/Makefile new file mode 100644 index 000000000..1acf03049 --- /dev/null +++ b/ethereal/Makefile @@ -0,0 +1,22 @@ +UNAME = $(shell uname) +FILES=qml *.png +GOPATH=$(PWD) + + +# Default is building +all: + 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) + cp -r assets/* /usr/share/ethereal + cp go-ethereum /usr/local/bin/ethereal +endif +# OS X build +ifeq ($(UNAME),Darwin) + # Execute py script +endif diff --git a/facet.png b/ethereal/assets/facet.png similarity index 100% rename from facet.png rename to ethereal/assets/facet.png diff --git a/net.png b/ethereal/assets/net.png similarity index 100% rename from net.png rename to ethereal/assets/net.png diff --git a/network.png b/ethereal/assets/network.png similarity index 100% rename from network.png rename to ethereal/assets/network.png diff --git a/new.png b/ethereal/assets/new.png similarity index 100% rename from new.png rename to ethereal/assets/new.png diff --git a/qml/test_app.qml b/ethereal/assets/qml/test_app.qml similarity index 100% rename from qml/test_app.qml rename to ethereal/assets/qml/test_app.qml diff --git a/qml/transactions.qml b/ethereal/assets/qml/transactions.qml similarity index 100% rename from qml/transactions.qml rename to ethereal/assets/qml/transactions.qml diff --git a/qml/wallet.qml b/ethereal/assets/qml/wallet.qml similarity index 100% rename from qml/wallet.qml rename to ethereal/assets/qml/wallet.qml diff --git a/tx.png b/ethereal/assets/tx.png similarity index 100% rename from tx.png rename to ethereal/assets/tx.png 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/ui/gui.go b/ethereal/ui/gui.go similarity index 98% rename from ui/gui.go rename to ethereal/ui/gui.go index 5f0b6e52d..c8f4bedab 100644 --- a/ui/gui.go +++ b/ethereal/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/ethereal/ui/library.go similarity index 96% rename from ui/library.go rename to ethereal/ui/library.go index d6ce94b75..05fffd579 100644 --- a/ui/library.go +++ b/ethereal/ui/library.go @@ -36,8 +36,6 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { tx.Sign(keyPair.PrivateKey) - ethutil.Config.Log.Infof("nonce: %x", tx.Nonce) - lib.txPool.QueueTransaction(tx) if len(receiver) == 0 { diff --git a/ui/ui_lib.go b/ethereal/ui/ui_lib.go similarity index 95% rename from ui/ui_lib.go rename to ethereal/ui/ui_lib.go index 518a21bc5..edff02286 100644 --- a/ui/ui_lib.go +++ b/ethereal/ui/ui_lib.go @@ -54,8 +54,8 @@ func AssetPath(p string) string { // 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 + 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": diff --git a/config.go b/ethereum/config.go similarity index 93% rename from config.go rename to ethereum/config.go index bafc3e300..e4935dfed 100644 --- a/config.go +++ b/ethereum/config.go @@ -15,14 +15,15 @@ var GenAddr bool var UseSeed bool var ImportKey string var ExportKey bool -var UseGui 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(&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") diff --git a/dev_console.go b/ethereum/dev_console.go similarity index 100% rename from dev_console.go rename to ethereum/dev_console.go diff --git a/ethereum.go b/ethereum/ethereum.go similarity index 51% rename from ethereum.go rename to ethereum/ethereum.go index 556a33851..3f5e4a8f5 100644 --- a/ethereum.go +++ b/ethereum/ethereum.go @@ -4,11 +4,9 @@ import ( "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethminer" "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/go-ethereum/ui" - "github.com/niemeyer/qml" - "github.com/obscuren/secp256k1-go" + "github.com/ethereum/eth-go/ethwire" + "github.com/ethereum/go-ethereum/utils" "log" "os" "os/signal" @@ -32,58 +30,9 @@ func RegisterInterupts(s *eth.Ethereum) { }() } -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() @@ -112,7 +61,7 @@ func main() { } if r == "y" { - CreateKeyPair(true) + utils.CreateKeyPair(true) } os.Exit(0) } else { @@ -129,11 +78,11 @@ func main() { } if r == "y" { - ImportPrivateKey(ImportKey) + utils.ImportPrivateKey(ImportKey) os.Exit(0) } } else { - CreateKeyPair(false) + utils.CreateKeyPair(false) } } @@ -164,29 +113,46 @@ func main() { go console.Start() } - if UseGui { - gui := ethui.New(ethereum) - gui.Start() - //ethereum.Stop() - } else { - RegisterInterupts(ethereum) - ethereum.Start() + RegisterInterupts(ethereum) + ethereum.Start() - if StartMining { - log.Printf("Miner started\n") + if StartMining { + log.Printf("Miner started\n") - go func() { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() + // 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() - miner := ethminer.NewDefaultMiner(addr, ethereum) - miner.Start() + 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) - // Wait for shutdown - ethereum.WaitForShutdown() + // 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/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/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) +}