mirror of https://github.com/ethereum/go-ethereum
commit
3777ead25e
@ -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) |
||||
} |
||||
} |
@ -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() |
||||
} |
@ -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() |
||||
} |
@ -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() |
||||
} |
@ -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 |
||||
} |
@ -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() |
||||
} |
@ -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,74 +1,245 @@ |
||||
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 err error |
||||
ethereum.RpcServer, err = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum), RpcPort) |
||||
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 { |
||||
ethutil.Config.Log.Infoln("Could not start RPC interface:", err) |
||||
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 { |
||||
go ethereum.RpcServer.Start() |
||||
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)) |
||||
} |
||||
} |
||||
|
||||
var miner ethminer.Miner |
||||
func InitConfig(ConfigFile string, Datadir string, Identifier string, EnvPrefix string) { |
||||
InitDataDir(Datadir) |
||||
ethutil.ReadConfig(ConfigFile, Datadir, Identifier, EnvPrefix) |
||||
ethutil.Config.Set("rpcport", "700") |
||||
} |
||||
|
||||
func DoMining(ethereum *eth.Ethereum) { |
||||
// Set Mining status
|
||||
ethereum.Mining = true |
||||
func exit(status int) { |
||||
ethlog.Flush() |
||||
os.Exit(status) |
||||
} |
||||
|
||||
if ethutil.GetKeyRing().Len() == 0 { |
||||
ethutil.Config.Log.Infoln("No address found, can't start mining") |
||||
return |
||||
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) |
||||
} |
||||
keyPair := ethutil.GetKeyRing().Get(0) |
||||
addr := keyPair.Address() |
||||
ethereum.Port = OutboundPort |
||||
ethereum.MaxPeers = MaxPeer |
||||
return ethereum |
||||
} |
||||
|
||||
go func() { |
||||
miner = ethminer.NewDefaultMiner(addr, 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() |
||||
}) |
||||
} |
||||
|
||||
// Give it some time to connect with peers
|
||||
time.Sleep(3 * time.Second) |
||||
func ShowGenesis(ethereum *eth.Ethereum) { |
||||
logger.Infoln(ethereum.BlockChain().Genesis()) |
||||
exit(0) |
||||
} |
||||
|
||||
for ethereum.IsUpToDate() == false { |
||||
time.Sleep(5 * time.Second) |
||||
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 { |
||||
logger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err) |
||||
} else { |
||||
go ethereum.RpcServer.Start() |
||||
} |
||||
} |
||||
|
||||
ethutil.Config.Log.Infoln("Miner started") |
||||
var miner ethminer.Miner |
||||
|
||||
miner := ethminer.NewDefaultMiner(addr, ethereum) |
||||
miner.Start() |
||||
}() |
||||
func StartMining(ethereum *eth.Ethereum) bool { |
||||
if !ethereum.Mining { |
||||
ethereum.Mining = true |
||||
|
||||
if ethutil.GetKeyRing().Len() == 0 { |
||||
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) |
||||
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) |
||||
// 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 true |
||||
parent := ethereum.BlockChain().GetBlock(block.PrevHash) |
||||
|
||||
_, err := ethereum.StateManager().ApplyDiff(parent.State(), parent, block) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
return false |
||||
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 |
||||
} |
Loading…
Reference in new issue