|
|
|
@ -28,36 +28,28 @@ type Gui struct { |
|
|
|
|
eth *eth.Ethereum |
|
|
|
|
|
|
|
|
|
// The public Ethereum library
|
|
|
|
|
lib *EthLib |
|
|
|
|
uiLib *UiLib |
|
|
|
|
|
|
|
|
|
txDb *ethdb.LDBDatabase |
|
|
|
|
|
|
|
|
|
addr []byte |
|
|
|
|
|
|
|
|
|
pub *ethpub.PEthereum |
|
|
|
|
logLevel ethlog.LogLevel |
|
|
|
|
open bool |
|
|
|
|
|
|
|
|
|
Session string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create GUI, but doesn't start it
|
|
|
|
|
func New(ethereum *eth.Ethereum, logLevel int) *Gui { |
|
|
|
|
lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} |
|
|
|
|
func New(ethereum *eth.Ethereum, session string, logLevel int) *Gui { |
|
|
|
|
|
|
|
|
|
db, err := ethdb.NewLDBDatabase("tx_database") |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// On first run we won't have any keys yet, so this would crash.
|
|
|
|
|
// Therefor we check if we are ready to actually start this process
|
|
|
|
|
var addr []byte |
|
|
|
|
if ethutil.GetKeyRing().Len() != 0 { |
|
|
|
|
addr = ethutil.GetKeyRing().Get(0).Address() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub := ethpub.NewPEthereum(ethereum) |
|
|
|
|
|
|
|
|
|
return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub, logLevel: ethlog.LogLevel(logLevel), open: false} |
|
|
|
|
return &Gui{eth: ethereum, txDb: db, pub: pub, logLevel: ethlog.LogLevel(logLevel), Session: session, open: false} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) Start(assetPath string) { |
|
|
|
@ -158,12 +150,11 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) { |
|
|
|
|
context.SetVar("lib", gui.lib) |
|
|
|
|
context.SetVar("lib", gui) |
|
|
|
|
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml")) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return gui.createWindow(component), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -175,15 +166,36 @@ func (gui *Gui) createWindow(comp qml.Object) *qml.Window { |
|
|
|
|
|
|
|
|
|
return gui.win |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) ImportAndSetPrivKey(secret string) bool { |
|
|
|
|
err := gui.eth.KeyManager().InitFromString(gui.Session, 0, secret) |
|
|
|
|
if err != nil { |
|
|
|
|
logger.Errorln("unable to import: ", err) |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
logger.Errorln("successfully imported: ", err) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) CreateAndSetPrivKey() (string, string, string, string) { |
|
|
|
|
err := gui.eth.KeyManager().Init(gui.Session, 0, true) |
|
|
|
|
if err != nil { |
|
|
|
|
logger.Errorln("unable to create key: ", err) |
|
|
|
|
return "", "", "", "" |
|
|
|
|
} |
|
|
|
|
return gui.eth.KeyManager().KeyPair().AsStrings() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) setInitialBlockChain() { |
|
|
|
|
sBlk := gui.eth.BlockChain().LastBlockHash |
|
|
|
|
blk := gui.eth.BlockChain().GetBlock(sBlk) |
|
|
|
|
for ; blk != nil; blk = gui.eth.BlockChain().GetBlock(sBlk) { |
|
|
|
|
sBlk = blk.PrevHash |
|
|
|
|
addr := gui.address() |
|
|
|
|
|
|
|
|
|
// Loop through all transactions to see if we missed any while being offline
|
|
|
|
|
for _, tx := range blk.Transactions() { |
|
|
|
|
if bytes.Compare(tx.Sender(), gui.addr) == 0 || bytes.Compare(tx.Recipient, gui.addr) == 0 { |
|
|
|
|
if bytes.Compare(tx.Sender(), addr) == 0 || bytes.Compare(tx.Recipient, addr) == 0 { |
|
|
|
|
if ok, _ := gui.txDb.Get(tx.Hash()); ok == nil { |
|
|
|
|
gui.txDb.Put(tx.Hash(), tx.RlpEncode()) |
|
|
|
|
} |
|
|
|
@ -199,25 +211,26 @@ type address struct { |
|
|
|
|
Name, Address string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var namereg = ethutil.FromHex("bb5f186604d057c1c5240ca2ae0f6430138ac010") |
|
|
|
|
var namereg = ethutil.Hex2Bytes("bb5f186604d057c1c5240ca2ae0f6430138ac010") |
|
|
|
|
|
|
|
|
|
func (gui *Gui) loadAddressBook() { |
|
|
|
|
gui.win.Root().Call("clearAddress") |
|
|
|
|
stateObject := gui.eth.StateManager().CurrentState().GetStateObject(namereg) |
|
|
|
|
if stateObject != nil { |
|
|
|
|
stateObject.State().EachStorage(func(name string, value *ethutil.Value) { |
|
|
|
|
gui.win.Root().Call("addAddress", struct{ Name, Address string }{name, ethutil.Hex(value.Bytes())}) |
|
|
|
|
gui.win.Root().Call("addAddress", struct{ Name, Address string }{name, ethutil.Bytes2Hex(value.Bytes())}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) readPreviousTransactions() { |
|
|
|
|
it := gui.txDb.Db().NewIterator(nil, nil) |
|
|
|
|
addr := gui.address() |
|
|
|
|
for it.Next() { |
|
|
|
|
tx := ethchain.NewTransactionFromBytes(it.Value()) |
|
|
|
|
|
|
|
|
|
var inout string |
|
|
|
|
if bytes.Compare(tx.Sender(), gui.addr) == 0 { |
|
|
|
|
if bytes.Compare(tx.Sender(), addr) == 0 { |
|
|
|
|
inout = "send" |
|
|
|
|
} else { |
|
|
|
|
inout = "recv" |
|
|
|
@ -269,29 +282,29 @@ func (gui *Gui) update() { |
|
|
|
|
state := gui.eth.StateManager().TransState() |
|
|
|
|
|
|
|
|
|
unconfirmedFunds := new(big.Int) |
|
|
|
|
gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.addr).Amount))) |
|
|
|
|
gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount))) |
|
|
|
|
|
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
|
case b := <-blockChan: |
|
|
|
|
block := b.Resource.(*ethchain.Block) |
|
|
|
|
gui.processBlock(block, false) |
|
|
|
|
if bytes.Compare(block.Coinbase, gui.addr) == 0 { |
|
|
|
|
gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.addr).Amount, nil) |
|
|
|
|
if bytes.Compare(block.Coinbase, gui.address()) == 0 { |
|
|
|
|
gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Amount, nil) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case txMsg := <-txChan: |
|
|
|
|
tx := txMsg.Resource.(*ethchain.Transaction) |
|
|
|
|
|
|
|
|
|
if txMsg.Event == "newTx:pre" { |
|
|
|
|
object := state.GetAccount(gui.addr) |
|
|
|
|
object := state.GetAccount(gui.address()) |
|
|
|
|
|
|
|
|
|
if bytes.Compare(tx.Sender(), gui.addr) == 0 { |
|
|
|
|
if bytes.Compare(tx.Sender(), gui.address()) == 0 { |
|
|
|
|
gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "send") |
|
|
|
|
gui.txDb.Put(tx.Hash(), tx.RlpEncode()) |
|
|
|
|
|
|
|
|
|
unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) |
|
|
|
|
} else if bytes.Compare(tx.Recipient, gui.addr) == 0 { |
|
|
|
|
} else if bytes.Compare(tx.Recipient, gui.address()) == 0 { |
|
|
|
|
gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "recv") |
|
|
|
|
gui.txDb.Put(tx.Hash(), tx.RlpEncode()) |
|
|
|
|
|
|
|
|
@ -300,10 +313,10 @@ func (gui *Gui) update() { |
|
|
|
|
|
|
|
|
|
gui.setWalletValue(object.Amount, unconfirmedFunds) |
|
|
|
|
} else { |
|
|
|
|
object := state.GetAccount(gui.addr) |
|
|
|
|
if bytes.Compare(tx.Sender(), gui.addr) == 0 { |
|
|
|
|
object := state.GetAccount(gui.address()) |
|
|
|
|
if bytes.Compare(tx.Sender(), gui.address()) == 0 { |
|
|
|
|
object.SubAmount(tx.Value) |
|
|
|
|
} else if bytes.Compare(tx.Recipient, gui.addr) == 0 { |
|
|
|
|
} else if bytes.Compare(tx.Recipient, gui.address()) == 0 { |
|
|
|
|
object.AddAmount(tx.Value) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -330,22 +343,25 @@ func (gui *Gui) setPeerInfo() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) privateKey() string { |
|
|
|
|
return ethutil.Bytes2Hex(gui.eth.KeyManager().PrivateKey()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) address() []byte { |
|
|
|
|
return gui.eth.KeyManager().Address() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) RegisterName(name string) { |
|
|
|
|
keyPair := ethutil.GetKeyRing().Get(0) |
|
|
|
|
name = fmt.Sprintf("\"%s\"\n1", name) |
|
|
|
|
gui.pub.Transact(ethutil.Hex(keyPair.PrivateKey), "namereg", "1000", "1000000", "150", name) |
|
|
|
|
gui.pub.Transact(gui.privateKey(), "namereg", "1000", "1000000", "150", name) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) Transact(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) { |
|
|
|
|
keyPair := ethutil.GetKeyRing().Get(0) |
|
|
|
|
|
|
|
|
|
return gui.pub.Transact(ethutil.Hex(keyPair.PrivateKey), recipient, value, gas, gasPrice, data) |
|
|
|
|
return gui.pub.Transact(gui.privateKey(), recipient, value, gas, gasPrice, data) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) Create(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) { |
|
|
|
|
keyPair := ethutil.GetKeyRing().Get(0) |
|
|
|
|
|
|
|
|
|
return gui.pub.Transact(ethutil.Hex(keyPair.PrivateKey), recipient, value, gas, gasPrice, data) |
|
|
|
|
return gui.pub.Transact(gui.privateKey(), recipient, value, gas, gasPrice, data) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (gui *Gui) ChangeClientId(id string) { |
|
|
|
|