Merge branch 'release/0.5.15'
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -9,5 +9,6 @@
 | 
			
		||||
*un~
 | 
			
		||||
.DS_Store
 | 
			
		||||
*/**/.DS_Store
 | 
			
		||||
./ethereum/ethereum
 | 
			
		||||
ethereum/ethereum
 | 
			
		||||
ethereal/ethereal
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ Ethereum
 | 
			
		||||
 | 
			
		||||
Ethereum Go Client © 2014 Jeffrey Wilcke.
 | 
			
		||||
 | 
			
		||||
Current state: Proof of Concept 5.0 RC14.
 | 
			
		||||
Current state: Proof of Concept 0.5.15.
 | 
			
		||||
 | 
			
		||||
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,9 +10,9 @@ ApplicationWindow {
 | 
			
		||||
	visible: false
 | 
			
		||||
	title: "IceCREAM"
 | 
			
		||||
	minimumWidth: 1280
 | 
			
		||||
	minimumHeight: 900
 | 
			
		||||
	minimumHeight: 700
 | 
			
		||||
	width: 1290
 | 
			
		||||
	height: 900
 | 
			
		||||
	height: 700
 | 
			
		||||
 | 
			
		||||
	property alias codeText: codeEditor.text
 | 
			
		||||
	property alias dataText: rawDataField.text
 | 
			
		||||
@@ -42,7 +42,7 @@ ApplicationWindow {
 | 
			
		||||
		TableView {
 | 
			
		||||
			id: asmTableView
 | 
			
		||||
			width: 200
 | 
			
		||||
			TableViewColumn{ role: "value" ; title: "" ; width: 100 }
 | 
			
		||||
			TableViewColumn{ role: "value" ; title: "" ; width: 200 }
 | 
			
		||||
			model: asmModel
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -56,7 +56,7 @@ ApplicationWindow {
 | 
			
		||||
 | 
			
		||||
				Rectangle {
 | 
			
		||||
					color: "#00000000"
 | 
			
		||||
					height: 500
 | 
			
		||||
					height: 330
 | 
			
		||||
					anchors.left: parent.left
 | 
			
		||||
					anchors.right: parent.right
 | 
			
		||||
 | 
			
		||||
@@ -208,6 +208,12 @@ ApplicationWindow {
 | 
			
		||||
				}
 | 
			
		||||
				text: "Next"
 | 
			
		||||
			}
 | 
			
		||||
			CheckBox {
 | 
			
		||||
				id: breakEachLine
 | 
			
		||||
				objectName: "breakEachLine"
 | 
			
		||||
				text: "Break each instruction"
 | 
			
		||||
				checked: true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,9 @@ window.eth = {
 | 
			
		||||
	getBalanceAt: function(address, cb) {
 | 
			
		||||
		postData({call: "getBalance", args: [address]}, cb);
 | 
			
		||||
	},
 | 
			
		||||
	getTransactionsFor: function(address, cb) {
 | 
			
		||||
		postData({call: "getTransactionsFor", args: [address]}, cb);
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	getSecretToAddress: function(sec, cb) {
 | 
			
		||||
		postData({call: "getSecretToAddress", args: [sec]}, cb);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								ethereal/assets/qml/QmlApp.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ethereal/assets/qml/QmlApp.qml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import QtQuick 2.0
 | 
			
		||||
import QtQuick.Controls 1.0;
 | 
			
		||||
import QtQuick.Layouts 1.0;
 | 
			
		||||
import Ethereum 1.0
 | 
			
		||||
 | 
			
		||||
ApplicationWindow {
 | 
			
		||||
	minimumWidth: 500
 | 
			
		||||
	maximumWidth: 500
 | 
			
		||||
	maximumHeight: 400
 | 
			
		||||
	minimumHeight: 400
 | 
			
		||||
 | 
			
		||||
	function onNewBlockCb(block) {
 | 
			
		||||
		console.log("Please overwrite onNewBlock(block):", block)
 | 
			
		||||
	}
 | 
			
		||||
	function onObjectChangeCb(stateObject) {
 | 
			
		||||
		console.log("Please overwrite onObjectChangeCb(object)", stateObject)
 | 
			
		||||
	}
 | 
			
		||||
	function onStorageChangeCb(storageObject) {
 | 
			
		||||
		var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":");
 | 
			
		||||
		console.log("Please overwrite onStorageChangeCb(object)", ev)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -3,33 +3,68 @@ import QtQuick.Controls 1.0;
 | 
			
		||||
import QtQuick.Layouts 1.0;
 | 
			
		||||
import Ethereum 1.0
 | 
			
		||||
 | 
			
		||||
ApplicationWindow {
 | 
			
		||||
	minimumWidth: 500
 | 
			
		||||
	maximumWidth: 500
 | 
			
		||||
	maximumHeight: 100
 | 
			
		||||
	minimumHeight: 100
 | 
			
		||||
QmlApp {
 | 
			
		||||
	minimumWidth: 350
 | 
			
		||||
	maximumWidth: 350
 | 
			
		||||
	maximumHeight: 80
 | 
			
		||||
	minimumHeight: 80
 | 
			
		||||
 | 
			
		||||
	title: "Ethereum Dice"
 | 
			
		||||
	title: "Generic Coin"
 | 
			
		||||
 | 
			
		||||
	TextField {
 | 
			
		||||
		id: textField
 | 
			
		||||
		anchors.verticalCenter: parent.verticalCenter
 | 
			
		||||
		anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
		placeholderText: "Amount"
 | 
			
		||||
	property string contractAddr: "f299f6c74515620e4c4cd8fe3d205b5c4f2e25c8"
 | 
			
		||||
	property string addr: "2ef47100e0787b915105fd5e3f4ff6752079d5cb"
 | 
			
		||||
 | 
			
		||||
	Component.onCompleted: {
 | 
			
		||||
		eth.watch(contractAddr, addr)
 | 
			
		||||
		eth.watch(addr, contractAddr)
 | 
			
		||||
		setAmount()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function onStorageChangeCb(storageObject) {
 | 
			
		||||
		setAmount()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function setAmount(){
 | 
			
		||||
		var state = eth.getStateObject(contractAddr)
 | 
			
		||||
		var storage = state.getStorage(addr)
 | 
			
		||||
		amountLabel.text = storage
 | 
			
		||||
	}
 | 
			
		||||
	Column {
 | 
			
		||||
		spacing: 5
 | 
			
		||||
		Row {
 | 
			
		||||
			spacing: 20
 | 
			
		||||
			Label {
 | 
			
		||||
				id: genLabel
 | 
			
		||||
				text: "Generic coin balance:"
 | 
			
		||||
			}
 | 
			
		||||
			Label {
 | 
			
		||||
		id: txHash
 | 
			
		||||
		anchors.bottom: textField.top
 | 
			
		||||
		anchors.bottomMargin: 5
 | 
			
		||||
		anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
				id: amountLabel
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Row {
 | 
			
		||||
			spacing: 20
 | 
			
		||||
			TextField {
 | 
			
		||||
				id: address
 | 
			
		||||
				placeholderText: "Address"
 | 
			
		||||
			}
 | 
			
		||||
			TextField {
 | 
			
		||||
				id: amount
 | 
			
		||||
				placeholderText: "Amount"
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Button {
 | 
			
		||||
		anchors.top: textField.bottom
 | 
			
		||||
		anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
		anchors.topMargin: 5
 | 
			
		||||
		text: "Place bet"
 | 
			
		||||
			text: "Send coins"
 | 
			
		||||
			onClicked: {
 | 
			
		||||
			txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", textField.text)
 | 
			
		||||
				var privKey = eth.getKey().privateKey
 | 
			
		||||
				if(privKey){
 | 
			
		||||
					var result = eth.transact(privKey, contractAddr, 0,"100000","250", "0x" + address.text + "\n" + amount.text)
 | 
			
		||||
					resultTx.text = result.hash
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Label {
 | 
			
		||||
			id: resultTx
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -319,7 +319,7 @@ ApplicationWindow {
 | 
			
		||||
 | 
			
		||||
					Slider {
 | 
			
		||||
						id: logLevelSlider
 | 
			
		||||
						value: 1
 | 
			
		||||
						value: eth.getLogLevelInt()
 | 
			
		||||
						anchors {
 | 
			
		||||
							right: parent.right
 | 
			
		||||
							top: parent.top
 | 
			
		||||
@@ -332,7 +332,7 @@ ApplicationWindow {
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						orientation: Qt.Vertical
 | 
			
		||||
						maximumValue: 3
 | 
			
		||||
						maximumValue: 5
 | 
			
		||||
						stepSize: 1
 | 
			
		||||
 | 
			
		||||
						onValueChanged: {
 | 
			
		||||
@@ -372,7 +372,15 @@ ApplicationWindow {
 | 
			
		||||
		onAccepted: {
 | 
			
		||||
			//ui.open(openAppDialog.fileUrl.toString())
 | 
			
		||||
			//ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html")))
 | 
			
		||||
			ui.openHtml(openAppDialog.fileUrl.toString())
 | 
			
		||||
			var path = openAppDialog.fileUrl.toString()
 | 
			
		||||
			console.log(path)
 | 
			
		||||
			var ext = path.split('.').pop()
 | 
			
		||||
			console.log(ext)
 | 
			
		||||
			if(ext == "html" || ext == "htm") {
 | 
			
		||||
				ui.openHtml(path)
 | 
			
		||||
			}else if(ext == "qml"){
 | 
			
		||||
				ui.openQml(path)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -102,6 +102,12 @@ ApplicationWindow {
 | 
			
		||||
					      var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true)
 | 
			
		||||
					      postData(data._seed,stateObject)
 | 
			
		||||
 | 
			
		||||
						break
 | 
			
		||||
					case "getTransactionsFor":
 | 
			
		||||
					      require(1);
 | 
			
		||||
					      var txs = eth.getTransactionsFor(data.args[0], true)
 | 
			
		||||
					      postData(data._seed, txs)
 | 
			
		||||
 | 
			
		||||
					      break
 | 
			
		||||
					case "getBalance":
 | 
			
		||||
						require(1);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,43 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"flag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var Identifier string
 | 
			
		||||
 | 
			
		||||
//var StartMining bool
 | 
			
		||||
var StartRpc bool
 | 
			
		||||
var RpcPort int
 | 
			
		||||
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 AssetPath string
 | 
			
		||||
 | 
			
		||||
var Datadir string
 | 
			
		||||
 | 
			
		||||
func Init() {
 | 
			
		||||
	flag.StringVar(&Identifier, "id", "", "Custom client identifier")
 | 
			
		||||
	flag.StringVar(&OutboundPort, "port", "30303", "listening port")
 | 
			
		||||
	flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support")
 | 
			
		||||
	flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
 | 
			
		||||
	flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
 | 
			
		||||
	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
 | 
			
		||||
	flag.StringVar(&AssetPath, "asset_path", "", "absolute path to GUI assets directory")
 | 
			
		||||
 | 
			
		||||
	flag.BoolVar(&ShowGenesis, "genesis", false, "prints genesis header and exits")
 | 
			
		||||
	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(&ImportKey, "import", "", "imports the given private key (hex)")
 | 
			
		||||
 | 
			
		||||
	flag.StringVar(&Datadir, "datadir", ".ethereal", "specifies the datadir to use. Takes precedence over config file.")
 | 
			
		||||
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
}
 | 
			
		||||
@@ -1,142 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/ethereal/ui"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
	"github.com/go-qml/qml"
 | 
			
		||||
	"github.com/rakyll/globalconf"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
	"path"
 | 
			
		||||
	"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())
 | 
			
		||||
 | 
			
		||||
	g, err := globalconf.NewWithOptions(&globalconf.Options{
 | 
			
		||||
		Filename: path.Join(ethutil.ApplicationFolder(Datadir), "conf.ini"),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		g.ParseAll()
 | 
			
		||||
	}
 | 
			
		||||
	ethutil.ReadConfig(Datadir, ethutil.LogFile|ethutil.LogStd, g, Identifier)
 | 
			
		||||
 | 
			
		||||
	// 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)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ExportKey {
 | 
			
		||||
		keyPair := ethutil.GetKeyRing().Get(0)
 | 
			
		||||
		fmt.Printf(`
 | 
			
		||||
Generating new address and keypair.
 | 
			
		||||
Please keep your keys somewhere save.
 | 
			
		||||
 | 
			
		||||
++++++++++++++++ KeyRing +++++++++++++++++++
 | 
			
		||||
addr: %x
 | 
			
		||||
prvk: %x
 | 
			
		||||
pubk: %x
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
save these words so you can restore your account later: %s
 | 
			
		||||
`, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey)
 | 
			
		||||
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ShowGenesis {
 | 
			
		||||
		fmt.Println(ethereum.BlockChain().Genesis())
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		if StartMining {
 | 
			
		||||
			utils.DoMining(ethereum)
 | 
			
		||||
		}
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	if StartRpc {
 | 
			
		||||
		utils.DoRpc(ethereum, RpcPort)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log.Printf("Starting Ethereum GUI v%s\n", ethutil.Config.Ver)
 | 
			
		||||
 | 
			
		||||
	// Set the max peers
 | 
			
		||||
	ethereum.MaxPeers = MaxPeer
 | 
			
		||||
 | 
			
		||||
	gui := ethui.New(ethereum)
 | 
			
		||||
 | 
			
		||||
	ethereum.Start(UseSeed)
 | 
			
		||||
 | 
			
		||||
	gui.Start(AssetPath)
 | 
			
		||||
 | 
			
		||||
	// Wait for shutdown
 | 
			
		||||
	ethereum.WaitForShutdown()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								ethereal/flags.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								ethereal/flags.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bitbucket.org/kardianos/osext"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/user"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var Identifier string
 | 
			
		||||
var StartRpc bool
 | 
			
		||||
var RpcPort int
 | 
			
		||||
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 NonInteractive bool
 | 
			
		||||
var Datadir string
 | 
			
		||||
var LogFile string
 | 
			
		||||
var ConfigFile string
 | 
			
		||||
var DebugFile string
 | 
			
		||||
var LogLevel int
 | 
			
		||||
 | 
			
		||||
// flags specific to gui client
 | 
			
		||||
var AssetPath string
 | 
			
		||||
 | 
			
		||||
func defaultAssetPath() string {
 | 
			
		||||
	var assetPath 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") {
 | 
			
		||||
		assetPath = path.Join(pwd, "assets")
 | 
			
		||||
	} else {
 | 
			
		||||
		switch runtime.GOOS {
 | 
			
		||||
		case "darwin":
 | 
			
		||||
			// Get Binary Directory
 | 
			
		||||
			exedir, _ := osext.ExecutableFolder()
 | 
			
		||||
			assetPath = filepath.Join(exedir, "../Resources")
 | 
			
		||||
		case "linux":
 | 
			
		||||
			assetPath = "/usr/share/ethereal"
 | 
			
		||||
		case "window":
 | 
			
		||||
			fallthrough
 | 
			
		||||
		default:
 | 
			
		||||
			assetPath = "."
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return assetPath
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func defaultDataDir() string {
 | 
			
		||||
	usr, _ := user.Current()
 | 
			
		||||
	return path.Join(usr.HomeDir, ".ethereal")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini")
 | 
			
		||||
 | 
			
		||||
func Init() {
 | 
			
		||||
	flag.Usage = func() {
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0])
 | 
			
		||||
		flag.PrintDefaults()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flag.StringVar(&Identifier, "id", "", "Custom client identifier")
 | 
			
		||||
	flag.StringVar(&OutboundPort, "port", "30303", "listening port")
 | 
			
		||||
	flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support")
 | 
			
		||||
	flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
 | 
			
		||||
	flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
 | 
			
		||||
	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
 | 
			
		||||
	flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
 | 
			
		||||
	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(&LogFile, "logfile", "", "log file (defaults to standard output)")
 | 
			
		||||
	flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)")
 | 
			
		||||
	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use")
 | 
			
		||||
	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file")
 | 
			
		||||
	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)")
 | 
			
		||||
	flag.IntVar(&LogLevel, "loglevel", int(ethlog.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)")
 | 
			
		||||
 | 
			
		||||
	flag.StringVar(&AssetPath, "asset_path", defaultAssetPath(), "absolute path to GUI assets directory")
 | 
			
		||||
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								ethereal/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								ethereal/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/ethereal/ui"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
	"github.com/go-qml/qml"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
			
		||||
 | 
			
		||||
	qml.Init(nil)
 | 
			
		||||
 | 
			
		||||
	var interrupted = false
 | 
			
		||||
	utils.RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
		interrupted = true
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	utils.HandleInterrupt()
 | 
			
		||||
 | 
			
		||||
	// precedence: code-internal flag default < config file < environment variables < command line
 | 
			
		||||
	Init() // parsing command line
 | 
			
		||||
	utils.InitConfig(ConfigFile, Datadir, Identifier, "ETH")
 | 
			
		||||
 | 
			
		||||
	utils.InitDataDir(Datadir)
 | 
			
		||||
 | 
			
		||||
	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
 | 
			
		||||
 | 
			
		||||
	ethereum := utils.NewEthereum(UseUPnP, OutboundPort, MaxPeer)
 | 
			
		||||
 | 
			
		||||
	// create, import, export keys
 | 
			
		||||
	utils.KeyTasks(GenAddr, ImportKey, ExportKey, NonInteractive)
 | 
			
		||||
 | 
			
		||||
	if ShowGenesis {
 | 
			
		||||
		utils.ShowGenesis(ethereum)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if StartRpc {
 | 
			
		||||
		utils.StartRpc(ethereum, RpcPort)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gui := ethui.New(ethereum, LogLevel)
 | 
			
		||||
 | 
			
		||||
	utils.RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
		gui.Stop()
 | 
			
		||||
	})
 | 
			
		||||
	utils.StartEthereum(ethereum, UseSeed)
 | 
			
		||||
	// gui blocks the main thread
 | 
			
		||||
	gui.Start(AssetPath)
 | 
			
		||||
	// we need to run the interrupt callbacks in case gui is closed
 | 
			
		||||
	// this skips if we got here by actual interrupt stopping the GUI
 | 
			
		||||
	if !interrupted {
 | 
			
		||||
		utils.RunInterruptCallbacks(os.Interrupt)
 | 
			
		||||
	}
 | 
			
		||||
	// this blocks the thread
 | 
			
		||||
	ethereum.WaitForShutdown()
 | 
			
		||||
	ethlog.Flush()
 | 
			
		||||
}
 | 
			
		||||
@@ -26,7 +26,7 @@ func NewDebuggerWindow(lib *UiLib) *DebuggerWindow {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	win := component.CreateWindow(nil)
 | 
			
		||||
	db := &Debugger{win, make(chan bool), make(chan bool), true, false}
 | 
			
		||||
	db := &Debugger{win, make(chan bool), make(chan bool), true, false, true}
 | 
			
		||||
 | 
			
		||||
	return &DebuggerWindow{engine: engine, win: win, lib: lib, Db: db}
 | 
			
		||||
}
 | 
			
		||||
@@ -59,6 +59,7 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
 | 
			
		||||
	if !self.Db.done {
 | 
			
		||||
		self.Db.Q <- true
 | 
			
		||||
	}
 | 
			
		||||
	self.Db.breakOnInstr = self.win.Root().ObjectByName("breakEachLine").Bool("checked")
 | 
			
		||||
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if r := recover(); r != nil {
 | 
			
		||||
@@ -95,16 +96,20 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
 | 
			
		||||
		self.win.Root().Call("setAsm", str)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gas := ethutil.Big(gasStr)
 | 
			
		||||
	gasPrice := ethutil.Big(gasPriceStr)
 | 
			
		||||
	var (
 | 
			
		||||
		gas      = ethutil.Big(gasStr)
 | 
			
		||||
		gasPrice = ethutil.Big(gasPriceStr)
 | 
			
		||||
		value    = ethutil.Big(valueStr)
 | 
			
		||||
		// Contract addr as test address
 | 
			
		||||
	keyPair := ethutil.GetKeyRing().Get(0)
 | 
			
		||||
	callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), gas, gasPrice, script)
 | 
			
		||||
		keyPair  = ethutil.GetKeyRing().Get(0)
 | 
			
		||||
		callerTx = ethchain.NewContractCreationTx(ethutil.Big(valueStr), gas, gasPrice, script)
 | 
			
		||||
	)
 | 
			
		||||
	callerTx.Sign(keyPair.PrivateKey)
 | 
			
		||||
 | 
			
		||||
	state := self.lib.eth.BlockChain().CurrentBlock.State()
 | 
			
		||||
	account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
 | 
			
		||||
	contract := ethchain.MakeContract(callerTx, state)
 | 
			
		||||
	contract.Amount = value
 | 
			
		||||
	callerClosure := ethchain.NewClosure(account, contract, script, state, gas, gasPrice)
 | 
			
		||||
 | 
			
		||||
	block := self.lib.eth.BlockChain().CurrentBlock
 | 
			
		||||
@@ -164,6 +169,7 @@ type Debugger struct {
 | 
			
		||||
	N               chan bool
 | 
			
		||||
	Q               chan bool
 | 
			
		||||
	done, interrupt bool
 | 
			
		||||
	breakOnInstr    bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type storeVal struct {
 | 
			
		||||
@@ -190,6 +196,7 @@ func (d *Debugger) halting(pc int, op ethchain.OpCode, mem *ethchain.Memory, sta
 | 
			
		||||
		d.win.Root().Call("setStorage", storeVal{fmt.Sprintf("% x", key), fmt.Sprintf("% x", node.Str())})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if d.breakOnInstr {
 | 
			
		||||
	out:
 | 
			
		||||
		for {
 | 
			
		||||
			select {
 | 
			
		||||
@@ -202,6 +209,7 @@ out:
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import (
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethchain"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethdb"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethpub"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
@@ -15,6 +16,8 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var logger = ethlog.NewLogger("GUI")
 | 
			
		||||
 | 
			
		||||
type Gui struct {
 | 
			
		||||
	// The main application window
 | 
			
		||||
	win *qml.Window
 | 
			
		||||
@@ -33,10 +36,12 @@ type Gui struct {
 | 
			
		||||
	addr []byte
 | 
			
		||||
 | 
			
		||||
	pub      *ethpub.PEthereum
 | 
			
		||||
	logLevel ethlog.LogLevel
 | 
			
		||||
	open     bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create GUI, but doesn't start it
 | 
			
		||||
func New(ethereum *eth.Ethereum) *Gui {
 | 
			
		||||
func New(ethereum *eth.Ethereum, logLevel int) *Gui {
 | 
			
		||||
	lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()}
 | 
			
		||||
	db, err := ethdb.NewLDBDatabase("tx_database")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -52,11 +57,11 @@ func New(ethereum *eth.Ethereum) *Gui {
 | 
			
		||||
 | 
			
		||||
	pub := ethpub.NewPEthereum(ethereum)
 | 
			
		||||
 | 
			
		||||
	return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub}
 | 
			
		||||
	return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub, logLevel: ethlog.LogLevel(logLevel), open: false}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) Start(assetPath string) {
 | 
			
		||||
	const version = "0.5.0 RC14"
 | 
			
		||||
	const version = "0.5.0 RC15"
 | 
			
		||||
 | 
			
		||||
	defer gui.txDb.Close()
 | 
			
		||||
 | 
			
		||||
@@ -86,25 +91,39 @@ func (gui *Gui) Start(assetPath string) {
 | 
			
		||||
 | 
			
		||||
	var win *qml.Window
 | 
			
		||||
	var err error
 | 
			
		||||
	var addlog = false
 | 
			
		||||
	if len(data) == 0 {
 | 
			
		||||
		win, err = gui.showKeyImport(context)
 | 
			
		||||
	} else {
 | 
			
		||||
		win, err = gui.showWallet(context)
 | 
			
		||||
 | 
			
		||||
		ethutil.Config.Log.AddLogSystem(gui)
 | 
			
		||||
		addlog = true
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ethutil.Config.Log.Infoln("FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'", err)
 | 
			
		||||
		logger.Errorln("asset not found: you can set an alternative asset path on the command line using option 'asset_path'", err)
 | 
			
		||||
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ethutil.Config.Log.Infoln("[GUI] Starting GUI")
 | 
			
		||||
 | 
			
		||||
	logger.Infoln("Starting GUI")
 | 
			
		||||
	gui.open = true
 | 
			
		||||
	win.Show()
 | 
			
		||||
	// only add the gui logger after window is shown otherwise slider wont be shown
 | 
			
		||||
	if addlog {
 | 
			
		||||
		ethlog.AddLogSystem(gui)
 | 
			
		||||
	}
 | 
			
		||||
	win.Wait()
 | 
			
		||||
	// need to silence gui logger after window closed otherwise logsystem hangs
 | 
			
		||||
	gui.SetLogLevel(ethlog.Silence)
 | 
			
		||||
	gui.open = false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	gui.eth.Stop()
 | 
			
		||||
func (gui *Gui) Stop() {
 | 
			
		||||
	if gui.open {
 | 
			
		||||
		gui.SetLogLevel(ethlog.Silence)
 | 
			
		||||
		gui.open = false
 | 
			
		||||
		gui.win.Hide()
 | 
			
		||||
	}
 | 
			
		||||
	logger.Infoln("Stopped")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) ToggleMining() {
 | 
			
		||||
@@ -154,10 +173,6 @@ func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
 | 
			
		||||
	gui.win = win
 | 
			
		||||
	gui.uiLib.win = win
 | 
			
		||||
 | 
			
		||||
	db := &Debugger{gui.win, make(chan bool), make(chan bool), true, false}
 | 
			
		||||
	gui.lib.Db = db
 | 
			
		||||
	gui.uiLib.Db = db
 | 
			
		||||
 | 
			
		||||
	return gui.win
 | 
			
		||||
}
 | 
			
		||||
func (gui *Gui) setInitialBlockChain() {
 | 
			
		||||
@@ -315,22 +330,6 @@ func (gui *Gui) setPeerInfo() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Logging functions that log directly to the GUI interface
 | 
			
		||||
func (gui *Gui) Println(v ...interface{}) {
 | 
			
		||||
	str := strings.TrimRight(fmt.Sprintln(v...), "\n")
 | 
			
		||||
	lines := strings.Split(str, "\n")
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		gui.win.Root().Call("addLog", line)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) Printf(format string, v ...interface{}) {
 | 
			
		||||
	str := strings.TrimRight(fmt.Sprintf(format, v...), "\n")
 | 
			
		||||
	lines := strings.Split(str, "\n")
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		gui.win.Root().Call("addLog", line)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
func (gui *Gui) RegisterName(name string) {
 | 
			
		||||
	keyPair := ethutil.GetKeyRing().Get(0)
 | 
			
		||||
	name = fmt.Sprintf("\"%s\"\n1", name)
 | 
			
		||||
@@ -357,6 +356,34 @@ func (gui *Gui) ClientId() string {
 | 
			
		||||
	return ethutil.Config.Identifier
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) SetLogLevel(level int) {
 | 
			
		||||
	ethutil.Config.Log.SetLevel(level)
 | 
			
		||||
// functions that allow Gui to implement interface ethlog.LogSystem
 | 
			
		||||
func (gui *Gui) SetLogLevel(level ethlog.LogLevel) {
 | 
			
		||||
	gui.logLevel = level
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) GetLogLevel() ethlog.LogLevel {
 | 
			
		||||
	return gui.logLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this extra function needed to give int typecast value to gui widget
 | 
			
		||||
// that sets initial loglevel to default
 | 
			
		||||
func (gui *Gui) GetLogLevelInt() int {
 | 
			
		||||
	return int(gui.logLevel)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) Println(v ...interface{}) {
 | 
			
		||||
	gui.printLog(fmt.Sprintln(v...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gui *Gui) Printf(format string, v ...interface{}) {
 | 
			
		||||
	gui.printLog(fmt.Sprintf(format, v...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Print function that logs directly to the GUI
 | 
			
		||||
func (gui *Gui) printLog(s string) {
 | 
			
		||||
	str := strings.TrimRight(s, "\n")
 | 
			
		||||
	lines := strings.Split(str, "\n")
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		gui.win.Root().Call("addLog", line)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -96,11 +96,11 @@ func (app *HtmlApplication) NewWatcher(quitChan chan bool) {
 | 
			
		||||
				app.watcher.Close()
 | 
			
		||||
				break out
 | 
			
		||||
			case <-app.watcher.Event:
 | 
			
		||||
				//ethutil.Config.Log.Debugln("Got event:", ev)
 | 
			
		||||
				//logger.Debugln("Got event:", ev)
 | 
			
		||||
				app.webView.Call("reload")
 | 
			
		||||
			case err := <-app.watcher.Error:
 | 
			
		||||
				// TODO: Do something here
 | 
			
		||||
				ethutil.Config.Log.Infoln("Watcher error:", err)
 | 
			
		||||
				logger.Infoln("Watcher error:", err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								ethereal/ui/qml_app.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								ethereal/ui/qml_app.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
package ethui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/ethereum/eth-go/ethchain"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethpub"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/go-qml/qml"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type QmlApplication struct {
 | 
			
		||||
	win    *qml.Window
 | 
			
		||||
	engine *qml.Engine
 | 
			
		||||
	lib    *UiLib
 | 
			
		||||
	path   string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewQmlApplication(path string, lib *UiLib) *QmlApplication {
 | 
			
		||||
	engine := qml.NewEngine()
 | 
			
		||||
	return &QmlApplication{engine: engine, path: path, lib: lib}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *QmlApplication) Create() error {
 | 
			
		||||
	component, err := app.engine.LoadFile(app.path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Warnln(err)
 | 
			
		||||
	}
 | 
			
		||||
	app.win = component.CreateWindow(nil)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *QmlApplication) Destroy() {
 | 
			
		||||
	app.engine.Destroy()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *QmlApplication) NewWatcher(quitChan chan bool) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Events
 | 
			
		||||
func (app *QmlApplication) NewBlock(block *ethchain.Block) {
 | 
			
		||||
	pblock := ðpub.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
 | 
			
		||||
	app.win.Call("onNewBlockCb", pblock)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *QmlApplication) ObjectChanged(stateObject *ethchain.StateObject) {
 | 
			
		||||
	app.win.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (app *QmlApplication) StorageChanged(storageObject *ethchain.StorageState) {
 | 
			
		||||
	app.win.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Getters
 | 
			
		||||
func (app *QmlApplication) Engine() *qml.Engine {
 | 
			
		||||
	return app.engine
 | 
			
		||||
}
 | 
			
		||||
func (app *QmlApplication) Window() *qml.Window {
 | 
			
		||||
	return app.win
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +1,10 @@
 | 
			
		||||
package ethui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bitbucket.org/kardianos/osext"
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/go-qml/qml"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type memAddr struct {
 | 
			
		||||
@@ -29,24 +25,14 @@ type UiLib struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
 | 
			
		||||
	if assetPath == "" {
 | 
			
		||||
		assetPath = DefaultAssetPath()
 | 
			
		||||
	}
 | 
			
		||||
	return &UiLib{engine: engine, eth: eth, assetPath: assetPath}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Opens a QML file (external application)
 | 
			
		||||
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)
 | 
			
		||||
func (ui *UiLib) OpenQml(path string) {
 | 
			
		||||
	container := NewQmlApplication(path[7:], ui)
 | 
			
		||||
	app := NewExtApplication(container, ui)
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		win.Show()
 | 
			
		||||
		win.Wait()
 | 
			
		||||
	}()
 | 
			
		||||
	go app.run()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ui *UiLib) OpenHtml(path string) {
 | 
			
		||||
@@ -59,7 +45,7 @@ func (ui *UiLib) OpenHtml(path string) {
 | 
			
		||||
func (ui *UiLib) Muted(content string) {
 | 
			
		||||
	component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ethutil.Config.Log.Debugln(err)
 | 
			
		||||
		logger.Debugln(err)
 | 
			
		||||
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@@ -88,6 +74,7 @@ func (ui *UiLib) ConnectToPeer(addr string) {
 | 
			
		||||
func (ui *UiLib) AssetPath(p string) string {
 | 
			
		||||
	return path.Join(ui.assetPath, p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *UiLib) StartDbWithContractAndData(contractHash, data string) {
 | 
			
		||||
	dbWindow := NewDebuggerWindow(self)
 | 
			
		||||
	object := self.eth.StateManager().CurrentState().GetStateObject(ethutil.FromHex(contractHash))
 | 
			
		||||
@@ -111,29 +98,3 @@ func (self *UiLib) StartDebugger() {
 | 
			
		||||
 | 
			
		||||
	dbWindow.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DefaultAssetPath() 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 base
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								ethereum/cmd.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ethereum/cmd.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func InitJsConsole(ethereum *eth.Ethereum) {
 | 
			
		||||
	repl := NewJSRepl(ethereum)
 | 
			
		||||
	go repl.Start()
 | 
			
		||||
	utils.RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
		repl.Stop()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ExecJsFile(ethereum *eth.Ethereum, InputFile string) {
 | 
			
		||||
	file, err := os.Open(InputFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Fatalln(err)
 | 
			
		||||
	}
 | 
			
		||||
	content, err := ioutil.ReadAll(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Fatalln(err)
 | 
			
		||||
	}
 | 
			
		||||
	re := NewJSRE(ethereum)
 | 
			
		||||
	utils.RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
		re.Stop()
 | 
			
		||||
	})
 | 
			
		||||
	re.Run(string(content))
 | 
			
		||||
}
 | 
			
		||||
@@ -1,193 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
	"github.com/rakyll/globalconf"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
	"path"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const Debug = true
 | 
			
		||||
 | 
			
		||||
func RegisterInterrupt(cb func(os.Signal)) {
 | 
			
		||||
	go func() {
 | 
			
		||||
		// Buffered chan of one is enough
 | 
			
		||||
		c := make(chan os.Signal, 1)
 | 
			
		||||
		// Notify about interrupts for now
 | 
			
		||||
		signal.Notify(c, os.Interrupt)
 | 
			
		||||
 | 
			
		||||
		for sig := range c {
 | 
			
		||||
			cb(sig)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func confirm(message string) bool {
 | 
			
		||||
	fmt.Println(message, "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)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return r == "y"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	Init()
 | 
			
		||||
 | 
			
		||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
			
		||||
 | 
			
		||||
	// set logger
 | 
			
		||||
	var logSys *log.Logger
 | 
			
		||||
	flags := log.LstdFlags
 | 
			
		||||
 | 
			
		||||
	var lt ethutil.LoggerType
 | 
			
		||||
	if StartJsConsole || len(InputFile) > 0 {
 | 
			
		||||
		lt = ethutil.LogFile
 | 
			
		||||
	} else {
 | 
			
		||||
		lt = ethutil.LogFile | ethutil.LogStd
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g, err := globalconf.NewWithOptions(&globalconf.Options{
 | 
			
		||||
		Filename: path.Join(ethutil.ApplicationFolder(Datadir), "conf.ini"),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		g.ParseAll()
 | 
			
		||||
	}
 | 
			
		||||
	ethutil.ReadConfig(Datadir, lt, g, Identifier)
 | 
			
		||||
 | 
			
		||||
	logger := ethutil.Config.Log
 | 
			
		||||
 | 
			
		||||
	if LogFile != "" {
 | 
			
		||||
		logfile, err := os.OpenFile(LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(fmt.Sprintf("error opening log file '%s': %v", LogFile, err))
 | 
			
		||||
		}
 | 
			
		||||
		defer logfile.Close()
 | 
			
		||||
		log.SetOutput(logfile)
 | 
			
		||||
		logSys = log.New(logfile, "", flags)
 | 
			
		||||
		logger.AddLogSystem(logSys)
 | 
			
		||||
	} else {
 | 
			
		||||
		logSys = log.New(os.Stdout, "", flags)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Instantiated a eth stack
 | 
			
		||||
	ethereum, err := eth.New(eth.CapDefault, UseUPnP)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println("eth start err:", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	ethereum.Port = OutboundPort
 | 
			
		||||
 | 
			
		||||
	// bookkeeping tasks
 | 
			
		||||
	switch {
 | 
			
		||||
	case GenAddr:
 | 
			
		||||
		if NonInteractive || confirm("This action overwrites your old private key.") {
 | 
			
		||||
			utils.CreateKeyPair(true)
 | 
			
		||||
		}
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	case len(ImportKey) > 0:
 | 
			
		||||
		if NonInteractive || confirm("This action overwrites your old private key.") {
 | 
			
		||||
			mnemonic := strings.Split(ImportKey, " ")
 | 
			
		||||
			if len(mnemonic) == 24 {
 | 
			
		||||
				logSys.Println("Got mnemonic key, importing.")
 | 
			
		||||
				key := ethutil.MnemonicDecode(mnemonic)
 | 
			
		||||
				utils.ImportPrivateKey(key)
 | 
			
		||||
			} else if len(mnemonic) == 1 {
 | 
			
		||||
				logSys.Println("Got hex key, importing.")
 | 
			
		||||
				utils.ImportPrivateKey(ImportKey)
 | 
			
		||||
			} else {
 | 
			
		||||
				logSys.Println("Did not recognise format, exiting.")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	case ExportKey:
 | 
			
		||||
		keyPair := ethutil.GetKeyRing().Get(0)
 | 
			
		||||
		fmt.Printf(`
 | 
			
		||||
Generating new address and keypair.
 | 
			
		||||
Please keep your keys somewhere save.
 | 
			
		||||
 | 
			
		||||
++++++++++++++++ KeyRing +++++++++++++++++++
 | 
			
		||||
addr: %x
 | 
			
		||||
prvk: %x
 | 
			
		||||
pubk: %x
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
save these words so you can restore your account later: %s
 | 
			
		||||
`, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey)
 | 
			
		||||
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	case ShowGenesis:
 | 
			
		||||
		logSys.Println(ethereum.BlockChain().Genesis())
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	default:
 | 
			
		||||
		// Creates a keypair if non exists
 | 
			
		||||
		utils.CreateKeyPair(false)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// client
 | 
			
		||||
	logger.Infoln(fmt.Sprintf("Starting Ethereum v%s", ethutil.Config.Ver))
 | 
			
		||||
 | 
			
		||||
	// Set the max peers
 | 
			
		||||
	ethereum.MaxPeers = MaxPeer
 | 
			
		||||
 | 
			
		||||
	// Set Mining status
 | 
			
		||||
	ethereum.Mining = StartMining
 | 
			
		||||
 | 
			
		||||
	if StartMining {
 | 
			
		||||
		utils.DoMining(ethereum)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if StartJsConsole {
 | 
			
		||||
		repl := NewJSRepl(ethereum)
 | 
			
		||||
 | 
			
		||||
		go repl.Start()
 | 
			
		||||
 | 
			
		||||
		RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
			repl.Stop()
 | 
			
		||||
		})
 | 
			
		||||
	} else if len(InputFile) > 0 {
 | 
			
		||||
		file, err := os.Open(InputFile)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ethutil.Config.Log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		content, err := ioutil.ReadAll(file)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ethutil.Config.Log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		re := NewJSRE(ethereum)
 | 
			
		||||
		RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
			re.Stop()
 | 
			
		||||
		})
 | 
			
		||||
		re.Run(string(content))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if StartRpc {
 | 
			
		||||
		utils.DoRpc(ethereum, RpcPort)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RegisterInterrupt(func(sig os.Signal) {
 | 
			
		||||
		fmt.Printf("Shutting down (%v) ... \n", sig)
 | 
			
		||||
		ethereum.Stop()
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	ethereum.Start(UseSeed)
 | 
			
		||||
 | 
			
		||||
	// Wait for shutdown
 | 
			
		||||
	ethereum.WaitForShutdown()
 | 
			
		||||
}
 | 
			
		||||
@@ -3,11 +3,13 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/user"
 | 
			
		||||
	"path"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var Identifier string
 | 
			
		||||
var StartMining bool
 | 
			
		||||
var StartRpc bool
 | 
			
		||||
var RpcPort int
 | 
			
		||||
var UseUPnP bool
 | 
			
		||||
@@ -19,16 +21,28 @@ var GenAddr bool
 | 
			
		||||
var UseSeed bool
 | 
			
		||||
var ImportKey string
 | 
			
		||||
var ExportKey bool
 | 
			
		||||
var LogFile string
 | 
			
		||||
var NonInteractive bool
 | 
			
		||||
var Datadir string
 | 
			
		||||
var LogFile string
 | 
			
		||||
var ConfigFile string
 | 
			
		||||
var DebugFile string
 | 
			
		||||
var LogLevel int
 | 
			
		||||
 | 
			
		||||
// flags specific to cli client
 | 
			
		||||
var StartMining bool
 | 
			
		||||
var StartJsConsole bool
 | 
			
		||||
var InputFile string
 | 
			
		||||
 | 
			
		||||
var Datadir string
 | 
			
		||||
func defaultDataDir() string {
 | 
			
		||||
	usr, _ := user.Current()
 | 
			
		||||
	return path.Join(usr.HomeDir, ".ethereum")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini")
 | 
			
		||||
 | 
			
		||||
func Init() {
 | 
			
		||||
	flag.Usage = func() {
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "%s [options] [filename]:\n", os.Args[0])
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0])
 | 
			
		||||
		flag.PrintDefaults()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -38,17 +52,19 @@ func Init() {
 | 
			
		||||
	flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
 | 
			
		||||
	flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
 | 
			
		||||
	flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
 | 
			
		||||
	flag.BoolVar(&StartJsConsole, "js", false, "exp")
 | 
			
		||||
 | 
			
		||||
	flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
 | 
			
		||||
	flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
 | 
			
		||||
	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(&LogFile, "logfile", "", "log file (defaults to standard output)")
 | 
			
		||||
	flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)")
 | 
			
		||||
	flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use")
 | 
			
		||||
	flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file")
 | 
			
		||||
	flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)")
 | 
			
		||||
	flag.IntVar(&LogLevel, "loglevel", int(ethlog.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)")
 | 
			
		||||
 | 
			
		||||
	flag.StringVar(&Datadir, "datadir", ".ethereum", "specifies the datadir to use. Takes precedence over config file.")
 | 
			
		||||
	flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
 | 
			
		||||
	flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
 | 
			
		||||
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethchain"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethpub"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
@@ -14,6 +15,8 @@ import (
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var jsrelogger = ethlog.NewLogger("JSRE")
 | 
			
		||||
 | 
			
		||||
type JSRE struct {
 | 
			
		||||
	ethereum *eth.Ethereum
 | 
			
		||||
	vm       *otto.Otto
 | 
			
		||||
@@ -31,7 +34,7 @@ func (jsre *JSRE) LoadExtFile(path string) {
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		jsre.vm.Run(result)
 | 
			
		||||
	} else {
 | 
			
		||||
		ethutil.Config.Log.Debugln("Could not load file:", path)
 | 
			
		||||
		jsrelogger.Debugln("Could not load file:", path)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -65,6 +68,8 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
 | 
			
		||||
 | 
			
		||||
	re.initStdFuncs()
 | 
			
		||||
 | 
			
		||||
	jsrelogger.Infoln("started")
 | 
			
		||||
 | 
			
		||||
	return re
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -99,6 +104,7 @@ func (self *JSRE) Stop() {
 | 
			
		||||
	close(self.blockChan)
 | 
			
		||||
	close(self.quitChan)
 | 
			
		||||
	close(self.changeChan)
 | 
			
		||||
	jsrelogger.Infoln("stopped")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *JSRE) mainLoop() {
 | 
			
		||||
@@ -138,6 +144,7 @@ func (self *JSRE) initStdFuncs() {
 | 
			
		||||
	eth.Set("require", self.require)
 | 
			
		||||
	eth.Set("stopMining", self.stopMining)
 | 
			
		||||
	eth.Set("startMining", self.startMining)
 | 
			
		||||
	eth.Set("execBlock", self.execBlock)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -207,3 +214,18 @@ func (self *JSRE) require(call otto.FunctionCall) otto.Value {
 | 
			
		||||
 | 
			
		||||
	return t
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *JSRE) execBlock(call otto.FunctionCall) otto.Value {
 | 
			
		||||
	hash, err := call.Argument(0).ToString()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return otto.UndefinedValue()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = utils.BlockDo(self.ethereum, ethutil.FromHex(hash))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
		return otto.FalseValue()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return otto.TrueValue()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								ethereum/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								ethereum/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"github.com/ethereum/go-ethereum/utils"
 | 
			
		||||
	"runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var logger = ethlog.NewLogger("CLI")
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
			
		||||
 | 
			
		||||
	utils.HandleInterrupt()
 | 
			
		||||
 | 
			
		||||
	// precedence: code-internal flag default < config file < environment variables < command line
 | 
			
		||||
	Init() // parsing command line
 | 
			
		||||
	utils.InitConfig(ConfigFile, Datadir, Identifier, "ETH")
 | 
			
		||||
 | 
			
		||||
	utils.InitDataDir(Datadir)
 | 
			
		||||
 | 
			
		||||
	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
 | 
			
		||||
 | 
			
		||||
	ethereum := utils.NewEthereum(UseUPnP, OutboundPort, MaxPeer)
 | 
			
		||||
 | 
			
		||||
	// create, import, export keys
 | 
			
		||||
	utils.KeyTasks(GenAddr, ImportKey, ExportKey, NonInteractive)
 | 
			
		||||
 | 
			
		||||
	if ShowGenesis {
 | 
			
		||||
		utils.ShowGenesis(ethereum)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if StartMining {
 | 
			
		||||
		utils.StartMining(ethereum)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// better reworked as cases
 | 
			
		||||
	if StartJsConsole {
 | 
			
		||||
		InitJsConsole(ethereum)
 | 
			
		||||
	} else if len(InputFile) > 0 {
 | 
			
		||||
		ExecJsFile(ethereum, InputFile)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if StartRpc {
 | 
			
		||||
		utils.StartRpc(ethereum, RpcPort)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	utils.StartEthereum(ethereum, UseSeed)
 | 
			
		||||
 | 
			
		||||
	// this blocks the thread
 | 
			
		||||
	ethereum.WaitForShutdown()
 | 
			
		||||
	ethlog.Flush()
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,15 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethpub"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"github.com/obscuren/otto"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Repl interface {
 | 
			
		||||
@@ -16,18 +21,48 @@ type JSRepl struct {
 | 
			
		||||
	re *JSRE
 | 
			
		||||
 | 
			
		||||
	prompt string
 | 
			
		||||
 | 
			
		||||
	history *os.File
 | 
			
		||||
 | 
			
		||||
	running bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
 | 
			
		||||
	return &JSRepl{re: NewJSRE(ethereum), prompt: "> "}
 | 
			
		||||
	hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &JSRepl{re: NewJSRE(ethereum), prompt: "> ", history: hist}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *JSRepl) Start() {
 | 
			
		||||
	if !self.running {
 | 
			
		||||
		self.running = true
 | 
			
		||||
		logger.Infoln("init JS Console")
 | 
			
		||||
		reader := bufio.NewReader(self.history)
 | 
			
		||||
		for {
 | 
			
		||||
			line, err := reader.ReadString('\n')
 | 
			
		||||
			if err != nil && err == io.EOF {
 | 
			
		||||
				break
 | 
			
		||||
			} else if err != nil {
 | 
			
		||||
				fmt.Println("error reading history", err)
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			addHistory(line[:len(line)-1])
 | 
			
		||||
		}
 | 
			
		||||
		self.read()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *JSRepl) Stop() {
 | 
			
		||||
	if self.running {
 | 
			
		||||
		self.running = false
 | 
			
		||||
		self.re.Stop()
 | 
			
		||||
		logger.Infoln("exit JS Console")
 | 
			
		||||
		self.history.Close()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *JSRepl) parseInput(code string) {
 | 
			
		||||
 
 | 
			
		||||
@@ -102,7 +102,9 @@ L:
 | 
			
		||||
					break L
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				addHistory(str[:len(str)-1]) //allow user to recall this line
 | 
			
		||||
				hist := str[:len(str)-1]
 | 
			
		||||
				addHistory(hist) //allow user to recall this line
 | 
			
		||||
				self.history.WriteString(str)
 | 
			
		||||
 | 
			
		||||
				self.parseInput(str)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										221
									
								
								utils/cmd.go
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								utils/cmd.go
									
									
									
									
									
								
							@@ -1,19 +1,186 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/ethereum/eth-go"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethlog"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethminer"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethpub"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethrpc"
 | 
			
		||||
	"github.com/ethereum/eth-go/ethutil"
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func DoRpc(ethereum *eth.Ethereum, RpcPort int) {
 | 
			
		||||
var logger = ethlog.NewLogger("CLI")
 | 
			
		||||
var interruptCallbacks = []func(os.Signal){}
 | 
			
		||||
 | 
			
		||||
// Register interrupt handlers callbacks
 | 
			
		||||
func RegisterInterrupt(cb func(os.Signal)) {
 | 
			
		||||
	interruptCallbacks = append(interruptCallbacks, cb)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// go routine that call interrupt handlers in order of registering
 | 
			
		||||
func HandleInterrupt() {
 | 
			
		||||
	c := make(chan os.Signal, 1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		signal.Notify(c, os.Interrupt)
 | 
			
		||||
		for sig := range c {
 | 
			
		||||
			logger.Errorf("Shutting down (%v) ... \n", sig)
 | 
			
		||||
			RunInterruptCallbacks(sig)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RunInterruptCallbacks(sig os.Signal) {
 | 
			
		||||
	for _, cb := range interruptCallbacks {
 | 
			
		||||
		cb(sig)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AbsolutePath(Datadir string, filename string) string {
 | 
			
		||||
	if path.IsAbs(filename) {
 | 
			
		||||
		return filename
 | 
			
		||||
	}
 | 
			
		||||
	return path.Join(Datadir, filename)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func openLogFile(Datadir string, filename string) *os.File {
 | 
			
		||||
	path := AbsolutePath(Datadir, filename)
 | 
			
		||||
	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(fmt.Sprintf("error opening log file '%s': %v", filename, err))
 | 
			
		||||
	}
 | 
			
		||||
	return file
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func confirm(message string) bool {
 | 
			
		||||
	fmt.Println(message, "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)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return r == "y"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func InitDataDir(Datadir string) {
 | 
			
		||||
	_, err := os.Stat(Datadir)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if os.IsNotExist(err) {
 | 
			
		||||
			fmt.Printf("Debug logging directory '%s' doesn't exist, creating it\n", Datadir)
 | 
			
		||||
			os.Mkdir(Datadir, 0777)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func InitLogging(Datadir string, LogFile string, LogLevel int, DebugFile string) {
 | 
			
		||||
	var writer io.Writer
 | 
			
		||||
	if LogFile == "" {
 | 
			
		||||
		writer = os.Stdout
 | 
			
		||||
	} else {
 | 
			
		||||
		writer = openLogFile(Datadir, LogFile)
 | 
			
		||||
	}
 | 
			
		||||
	ethlog.AddLogSystem(ethlog.NewStdLogSystem(writer, log.LstdFlags, ethlog.LogLevel(LogLevel)))
 | 
			
		||||
	if DebugFile != "" {
 | 
			
		||||
		writer = openLogFile(Datadir, DebugFile)
 | 
			
		||||
		ethlog.AddLogSystem(ethlog.NewStdLogSystem(writer, log.LstdFlags, ethlog.DebugLevel))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func InitConfig(ConfigFile string, Datadir string, Identifier string, EnvPrefix string) {
 | 
			
		||||
	InitDataDir(Datadir)
 | 
			
		||||
	ethutil.ReadConfig(ConfigFile, Datadir, Identifier, EnvPrefix)
 | 
			
		||||
	ethutil.Config.Set("rpcport", "700")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func exit(status int) {
 | 
			
		||||
	ethlog.Flush()
 | 
			
		||||
	os.Exit(status)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewEthereum(UseUPnP bool, OutboundPort string, MaxPeer int) *eth.Ethereum {
 | 
			
		||||
	ethereum, err := eth.New(eth.CapDefault, UseUPnP)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Fatalln("eth start err:", err)
 | 
			
		||||
	}
 | 
			
		||||
	ethereum.Port = OutboundPort
 | 
			
		||||
	ethereum.MaxPeers = MaxPeer
 | 
			
		||||
	return ethereum
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) {
 | 
			
		||||
	logger.Infof("Starting Ethereum v%s", ethutil.Config.Ver)
 | 
			
		||||
	ethereum.Start(UseSeed)
 | 
			
		||||
	RegisterInterrupt(func(sig os.Signal) {
 | 
			
		||||
		ethereum.Stop()
 | 
			
		||||
		ethlog.Flush()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ShowGenesis(ethereum *eth.Ethereum) {
 | 
			
		||||
	logger.Infoln(ethereum.BlockChain().Genesis())
 | 
			
		||||
	exit(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func KeyTasks(GenAddr bool, ImportKey string, ExportKey bool, NonInteractive bool) {
 | 
			
		||||
	switch {
 | 
			
		||||
	case GenAddr:
 | 
			
		||||
		if NonInteractive || confirm("This action overwrites your old private key.") {
 | 
			
		||||
			CreateKeyPair(true)
 | 
			
		||||
		}
 | 
			
		||||
		exit(0)
 | 
			
		||||
	case len(ImportKey) > 0:
 | 
			
		||||
		if NonInteractive || confirm("This action overwrites your old private key.") {
 | 
			
		||||
			// import should be from file
 | 
			
		||||
			mnemonic := strings.Split(ImportKey, " ")
 | 
			
		||||
			if len(mnemonic) == 24 {
 | 
			
		||||
				logger.Infoln("Got mnemonic key, importing.")
 | 
			
		||||
				key := ethutil.MnemonicDecode(mnemonic)
 | 
			
		||||
				ImportPrivateKey(key)
 | 
			
		||||
			} else if len(mnemonic) == 1 {
 | 
			
		||||
				logger.Infoln("Got hex key, importing.")
 | 
			
		||||
				ImportPrivateKey(ImportKey)
 | 
			
		||||
			} else {
 | 
			
		||||
				logger.Errorln("Did not recognise format, exiting.")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		exit(0)
 | 
			
		||||
	case ExportKey: // this should be exporting to a filename
 | 
			
		||||
		keyPair := ethutil.GetKeyRing().Get(0)
 | 
			
		||||
		fmt.Printf(`
 | 
			
		||||
Generating new address and keypair.
 | 
			
		||||
Please keep your keys somewhere save.
 | 
			
		||||
 | 
			
		||||
++++++++++++++++ KeyRing +++++++++++++++++++
 | 
			
		||||
addr: %x
 | 
			
		||||
prvk: %x
 | 
			
		||||
pubk: %x
 | 
			
		||||
++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
save these words so you can restore your account later: %s
 | 
			
		||||
`, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey)
 | 
			
		||||
 | 
			
		||||
		exit(0)
 | 
			
		||||
	default:
 | 
			
		||||
		// Creates a keypair if none exists
 | 
			
		||||
		CreateKeyPair(false)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StartRpc(ethereum *eth.Ethereum, RpcPort int) {
 | 
			
		||||
	var err error
 | 
			
		||||
	ethereum.RpcServer, err = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum), RpcPort)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ethutil.Config.Log.Infoln("Could not start RPC interface:", err)
 | 
			
		||||
		logger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err)
 | 
			
		||||
	} else {
 | 
			
		||||
		go ethereum.RpcServer.Start()
 | 
			
		||||
	}
 | 
			
		||||
@@ -21,54 +188,58 @@ func DoRpc(ethereum *eth.Ethereum, RpcPort int) {
 | 
			
		||||
 | 
			
		||||
var miner ethminer.Miner
 | 
			
		||||
 | 
			
		||||
func DoMining(ethereum *eth.Ethereum) {
 | 
			
		||||
	// Set Mining status
 | 
			
		||||
func StartMining(ethereum *eth.Ethereum) bool {
 | 
			
		||||
	if !ethereum.Mining {
 | 
			
		||||
		ethereum.Mining = true
 | 
			
		||||
 | 
			
		||||
		if ethutil.GetKeyRing().Len() == 0 {
 | 
			
		||||
		ethutil.Config.Log.Infoln("No address found, can't start mining")
 | 
			
		||||
		return
 | 
			
		||||
			logger.Errorln("No address found, can't start mining")
 | 
			
		||||
			ethereum.Mining = false
 | 
			
		||||
			return true //????
 | 
			
		||||
		}
 | 
			
		||||
		keyPair := ethutil.GetKeyRing().Get(0)
 | 
			
		||||
		addr := keyPair.Address()
 | 
			
		||||
 | 
			
		||||
		go func() {
 | 
			
		||||
			miner = ethminer.NewDefaultMiner(addr, ethereum)
 | 
			
		||||
 | 
			
		||||
			// Give it some time to connect with peers
 | 
			
		||||
			time.Sleep(3 * time.Second)
 | 
			
		||||
 | 
			
		||||
		for ethereum.IsUpToDate() == false {
 | 
			
		||||
			time.Sleep(5 * time.Second)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ethutil.Config.Log.Infoln("Miner started")
 | 
			
		||||
 | 
			
		||||
			logger.Infoln("Miner started")
 | 
			
		||||
			miner := ethminer.NewDefaultMiner(addr, ethereum)
 | 
			
		||||
			miner.Start()
 | 
			
		||||
		}()
 | 
			
		||||
		RegisterInterrupt(func(os.Signal) {
 | 
			
		||||
			StopMining(ethereum)
 | 
			
		||||
		})
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StopMining(ethereum *eth.Ethereum) bool {
 | 
			
		||||
	if ethereum.Mining {
 | 
			
		||||
		miner.Stop()
 | 
			
		||||
 | 
			
		||||
		ethutil.Config.Log.Infoln("Miner stopped")
 | 
			
		||||
 | 
			
		||||
		logger.Infoln("Miner stopped")
 | 
			
		||||
		ethereum.Mining = false
 | 
			
		||||
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StartMining(ethereum *eth.Ethereum) bool {
 | 
			
		||||
	if !ethereum.Mining {
 | 
			
		||||
		DoMining(ethereum)
 | 
			
		||||
 | 
			
		||||
		return true
 | 
			
		||||
// Replay block
 | 
			
		||||
func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
 | 
			
		||||
	block := ethereum.BlockChain().GetBlock(hash)
 | 
			
		||||
	if block == nil {
 | 
			
		||||
		return fmt.Errorf("unknown block %x", hash)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
	parent := ethereum.BlockChain().GetBlock(block.PrevHash)
 | 
			
		||||
 | 
			
		||||
	_, err := ethereum.StateManager().ApplyDiff(parent.State(), parent, block)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/obscuren/mutan"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// General compile function
 | 
			
		||||
func Compile(script string) ([]byte, error) {
 | 
			
		||||
	byteCode, errors := mutan.Compile(strings.NewReader(script), false)
 | 
			
		||||
	if len(errors) > 0 {
 | 
			
		||||
		var errs string
 | 
			
		||||
		for _, er := range errors {
 | 
			
		||||
			if er != nil {
 | 
			
		||||
				errs += er.Error()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return nil, fmt.Errorf("%v", errs)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return byteCode, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CompileScript(script string) ([]byte, []byte, error) {
 | 
			
		||||
	// Preprocess
 | 
			
		||||
	mainInput, initInput := mutan.PreParse(script)
 | 
			
		||||
	// Compile main script
 | 
			
		||||
	mainScript, err := Compile(mainInput)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Compile init script
 | 
			
		||||
	initScript, err := Compile(initInput)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mainScript, initScript, nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user