forked from cerc-io/plugeth
Leverage the new watch & address:changed functionality
This commit is contained in:
parent
d0438ac10a
commit
e16fd323e8
@ -47,6 +47,10 @@ window.eth = {
|
|||||||
postData({call: "getKey"}, cb);
|
postData({call: "getKey"}, cb);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: function(address) {
|
||||||
|
postData({call: "watch", args: [address]});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
on: function(event, cb) {
|
on: function(event, cb) {
|
||||||
if(eth._onCallbacks[event] === undefined) {
|
if(eth._onCallbacks[event] === undefined) {
|
||||||
|
@ -74,14 +74,24 @@ ApplicationWindow {
|
|||||||
var keys = eth.getKey()
|
var keys = eth.getKey()
|
||||||
postData(data._seed, keys)
|
postData(data._seed, keys)
|
||||||
break
|
break
|
||||||
|
case "watch":
|
||||||
|
if(data.args.length > 0) {
|
||||||
|
eth.watch(data.args[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function postData(seed, data) {
|
function postData(seed, data) {
|
||||||
webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
|
webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed}))
|
||||||
}
|
}
|
||||||
|
function postEvent(event, data) {
|
||||||
|
webview.experimental.postMessage(JSON.stringify({data: data, _event: event}))
|
||||||
|
}
|
||||||
|
|
||||||
function onNewBlockCb(block) {
|
function onNewBlockCb(block) {
|
||||||
webview.experimental.postMessage(JSON.stringify({data: block, _event: "block:new"}))
|
postEvent("block:new", block)
|
||||||
|
}
|
||||||
|
function onObjectChangeCb(stateObject) {
|
||||||
|
postEvent("object:change", stateObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,15 @@ function tests() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
eth.watch(jefcoinAddr);
|
||||||
|
|
||||||
eth.getKey(function(key) {
|
eth.getKey(function(key) {
|
||||||
eth.getStorage(jefcoinAddr, key, function(storage) {
|
eth.getStorage(jefcoinAddr, key, function(storage) {
|
||||||
document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
|
document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
|
||||||
});
|
});
|
||||||
|
|
||||||
eth.on("block:new", function() {
|
eth.on("object:change", function(stateObject) {
|
||||||
|
debug(stateObject);
|
||||||
eth.getStorage(jefcoinAddr, key, function(storage) {
|
eth.getStorage(jefcoinAddr, key, function(storage) {
|
||||||
document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
|
document.querySelector("#currentAmount").innerHTML = "Amount: " + storage;
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,6 @@ package ethui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go"
|
"github.com/ethereum/eth-go"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
@ -13,45 +12,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Block interface exposed to QML
|
|
||||||
type Block struct {
|
|
||||||
Number int
|
|
||||||
Hash string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Tx struct {
|
|
||||||
Value, Hash, Address string
|
|
||||||
Contract bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Key struct {
|
|
||||||
Address string
|
|
||||||
}
|
|
||||||
|
|
||||||
type KeyRing struct {
|
|
||||||
Keys []interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKeyRing(keys []interface{}) *KeyRing {
|
|
||||||
return &KeyRing{Keys: keys}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTxFromTransaction(tx *ethchain.Transaction) *Tx {
|
|
||||||
hash := hex.EncodeToString(tx.Hash())
|
|
||||||
sender := hex.EncodeToString(tx.Recipient)
|
|
||||||
isContract := len(tx.Data) > 0
|
|
||||||
|
|
||||||
return &Tx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender, Contract: isContract}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a new QML Block from a chain block
|
|
||||||
func NewBlockFromBlock(block *ethchain.Block) *Block {
|
|
||||||
info := block.BlockInfo()
|
|
||||||
hash := hex.EncodeToString(block.Hash())
|
|
||||||
|
|
||||||
return &Block{Number: int(info.Number), Hash: hash}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Gui struct {
|
type Gui struct {
|
||||||
// The main application window
|
// The main application window
|
||||||
win *qml.Window
|
win *qml.Window
|
||||||
@ -96,9 +56,9 @@ func (ui *Gui) Start(assetPath string) {
|
|||||||
|
|
||||||
// Register ethereum functions
|
// Register ethereum functions
|
||||||
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
|
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
|
||||||
Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" },
|
Init: func(p *QBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
|
||||||
}, {
|
}, {
|
||||||
Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
|
Init: func(p *QTx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
|
||||||
}})
|
}})
|
||||||
|
|
||||||
ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.1"))
|
ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.1"))
|
||||||
@ -169,13 +129,13 @@ func (ui *Gui) readPreviousTransactions() {
|
|||||||
for it.Next() {
|
for it.Next() {
|
||||||
tx := ethchain.NewTransactionFromBytes(it.Value())
|
tx := ethchain.NewTransactionFromBytes(it.Value())
|
||||||
|
|
||||||
ui.win.Root().Call("addTx", NewTxFromTransaction(tx))
|
ui.win.Root().Call("addTx", NewQTx(tx))
|
||||||
}
|
}
|
||||||
it.Release()
|
it.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *Gui) ProcessBlock(block *ethchain.Block) {
|
func (ui *Gui) ProcessBlock(block *ethchain.Block) {
|
||||||
ui.win.Root().Call("addBlock", NewBlockFromBlock(block))
|
ui.win.Root().Call("addBlock", NewQBlock(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple go routine function that updates the list of peers in the GUI
|
// Simple go routine function that updates the list of peers in the GUI
|
||||||
@ -193,13 +153,13 @@ func (ui *Gui) update() {
|
|||||||
|
|
||||||
if txMsg.Type == ethchain.TxPre {
|
if txMsg.Type == ethchain.TxPre {
|
||||||
if bytes.Compare(tx.Sender(), ui.addr) == 0 {
|
if bytes.Compare(tx.Sender(), ui.addr) == 0 {
|
||||||
ui.win.Root().Call("addTx", NewTxFromTransaction(tx))
|
ui.win.Root().Call("addTx", NewQTx(tx))
|
||||||
ui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
ui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
||||||
|
|
||||||
ui.eth.StateManager().GetAddrState(ui.addr).Nonce += 1
|
ui.eth.StateManager().GetAddrState(ui.addr).Nonce += 1
|
||||||
unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
|
unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
|
||||||
} else if bytes.Compare(tx.Recipient, ui.addr) == 0 {
|
} else if bytes.Compare(tx.Recipient, ui.addr) == 0 {
|
||||||
ui.win.Root().Call("addTx", NewTxFromTransaction(tx))
|
ui.win.Root().Call("addTx", NewQTx(tx))
|
||||||
ui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
ui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
||||||
|
|
||||||
unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
|
unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
|
||||||
|
@ -67,6 +67,10 @@ func (lib *EthLib) GetStateObject(address string) *Contract {
|
|||||||
return NewContract(stateObject)
|
return NewContract(stateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lib *EthLib) Watch(addr string) {
|
||||||
|
lib.stateManager.Watch(ethutil.FromHex(addr))
|
||||||
|
}
|
||||||
|
|
||||||
func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
|
func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
|
||||||
var hash []byte
|
var hash []byte
|
||||||
var contractCreation bool
|
var contractCreation bool
|
||||||
@ -117,7 +121,7 @@ func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, dataStr st
|
|||||||
return ethutil.Hex(tx.Hash()), nil
|
return ethutil.Hex(tx.Hash()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lib *EthLib) GetBlock(hexHash string) *Block {
|
func (lib *EthLib) GetBlock(hexHash string) *QBlock {
|
||||||
hash, err := hex.DecodeString(hexHash)
|
hash, err := hex.DecodeString(hexHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@ -125,5 +129,5 @@ func (lib *EthLib) GetBlock(hexHash string) *Block {
|
|||||||
|
|
||||||
block := lib.blockChain.GetBlock(hash)
|
block := lib.blockChain.GetBlock(hash)
|
||||||
|
|
||||||
return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
|
return &QBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
|
||||||
}
|
}
|
||||||
|
56
ethereal/ui/types.go
Normal file
56
ethereal/ui/types.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package ethui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Block interface exposed to QML
|
||||||
|
type QBlock struct {
|
||||||
|
Number int
|
||||||
|
Hash string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a new QML Block from a chain block
|
||||||
|
func NewQBlock(block *ethchain.Block) *QBlock {
|
||||||
|
info := block.BlockInfo()
|
||||||
|
hash := hex.EncodeToString(block.Hash())
|
||||||
|
|
||||||
|
return &QBlock{Number: int(info.Number), Hash: hash}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QTx struct {
|
||||||
|
Value, Hash, Address string
|
||||||
|
Contract bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQTx(tx *ethchain.Transaction) *QTx {
|
||||||
|
hash := hex.EncodeToString(tx.Hash())
|
||||||
|
sender := hex.EncodeToString(tx.Recipient)
|
||||||
|
isContract := len(tx.Data) > 0
|
||||||
|
|
||||||
|
return &QTx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender, Contract: isContract}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QKey struct {
|
||||||
|
Address string
|
||||||
|
}
|
||||||
|
|
||||||
|
type QKeyRing struct {
|
||||||
|
Keys []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQKeyRing(keys []interface{}) *QKeyRing {
|
||||||
|
return &QKeyRing{Keys: keys}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QStateObject struct {
|
||||||
|
Address string
|
||||||
|
Amount string
|
||||||
|
Nonce int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQStateObject(stateObject *ethchain.StateObject) *QStateObject {
|
||||||
|
return &QStateObject{ethutil.Hex(stateObject.Address()), stateObject.Amount.String(), int(stateObject.Nonce)}
|
||||||
|
}
|
@ -69,8 +69,10 @@ func (ui *UiLib) OpenHtml(path string) {
|
|||||||
}
|
}
|
||||||
win.Set("url", path)
|
win.Set("url", path)
|
||||||
|
|
||||||
|
webView := win.ObjectByName("webView")
|
||||||
go func() {
|
go func() {
|
||||||
blockChan := make(chan ethutil.React, 1)
|
blockChan := make(chan ethutil.React, 1)
|
||||||
|
addrChan := make(chan ethutil.React, 1)
|
||||||
quitChan := make(chan bool)
|
quitChan := make(chan bool)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -82,8 +84,12 @@ func (ui *UiLib) OpenHtml(path string) {
|
|||||||
break out
|
break out
|
||||||
case block := <-blockChan:
|
case block := <-blockChan:
|
||||||
if block, ok := block.Resource.(*ethchain.Block); ok {
|
if block, ok := block.Resource.(*ethchain.Block); ok {
|
||||||
b := &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
|
b := &QBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
|
||||||
win.ObjectByName("webView").Call("onNewBlockCb", b)
|
webView.Call("onNewBlockCb", b)
|
||||||
|
}
|
||||||
|
case stateObject := <-addrChan:
|
||||||
|
if stateObject, ok := stateObject.Resource.(*ethchain.StateObject); ok {
|
||||||
|
webView.Call("onObjectChangeCb", NewQStateObject(stateObject))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,6 +99,7 @@ func (ui *UiLib) OpenHtml(path string) {
|
|||||||
close(quitChan)
|
close(quitChan)
|
||||||
}()
|
}()
|
||||||
ui.eth.Reactor().Subscribe("newBlock", blockChan)
|
ui.eth.Reactor().Subscribe("newBlock", blockChan)
|
||||||
|
ui.eth.Reactor().Subscribe("addressChanged", addrChan)
|
||||||
|
|
||||||
win.Show()
|
win.Show()
|
||||||
win.Wait()
|
win.Wait()
|
||||||
@ -169,7 +176,7 @@ func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string)
|
|||||||
callerClosure := ethchain.NewClosure(account, c, c.Script(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr), ethutil.Big(valueStr))
|
callerClosure := ethchain.NewClosure(account, c, c.Script(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr), ethutil.Big(valueStr))
|
||||||
|
|
||||||
block := ui.eth.BlockChain().CurrentBlock
|
block := ui.eth.BlockChain().CurrentBlock
|
||||||
vm := ethchain.NewVm(state, ethchain.RuntimeVars{
|
vm := ethchain.NewVm(state, ui.eth.StateManager(), ethchain.RuntimeVars{
|
||||||
Origin: account.Address(),
|
Origin: account.Address(),
|
||||||
BlockNumber: block.BlockInfo().Number,
|
BlockNumber: block.BlockInfo().Number,
|
||||||
PrevHash: block.PrevHash,
|
PrevHash: block.PrevHash,
|
||||||
|
@ -53,20 +53,22 @@ func main() {
|
|||||||
var logSys *log.Logger
|
var logSys *log.Logger
|
||||||
flags := log.LstdFlags
|
flags := log.LstdFlags
|
||||||
|
|
||||||
|
ethutil.ReadConfig(DataDir)
|
||||||
|
logger := ethutil.Config.Log
|
||||||
|
|
||||||
if LogFile != "" {
|
if LogFile != "" {
|
||||||
logfile, err := os.OpenFile(LogFile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
logfile, err := os.OpenFile(LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("error opening log file '%s': %v", LogFile, err))
|
panic(fmt.Sprintf("error opening log file '%s': %v", LogFile, err))
|
||||||
}
|
}
|
||||||
defer logfile.Close()
|
defer logfile.Close()
|
||||||
log.SetOutput(logfile)
|
log.SetOutput(logfile)
|
||||||
logSys = log.New(logfile, "", flags)
|
logSys = log.New(logfile, "", flags)
|
||||||
} else {
|
|
||||||
logSys = log.New(os.Stdout, "", flags)
|
|
||||||
}
|
|
||||||
ethutil.ReadConfig(DataDir)
|
|
||||||
logger := ethutil.Config.Log
|
|
||||||
logger.AddLogSystem(logSys)
|
logger.AddLogSystem(logSys)
|
||||||
|
}
|
||||||
|
/*else {
|
||||||
|
logSys = log.New(os.Stdout, "", flags)
|
||||||
|
}*/
|
||||||
|
|
||||||
ethchain.InitFees()
|
ethchain.InitFees()
|
||||||
ethutil.Config.Seed = UseSeed
|
ethutil.Config.Seed = UseSeed
|
||||||
@ -101,9 +103,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
case len(ImportKey) == 0:
|
|
||||||
utils.CreateKeyPair(false)
|
|
||||||
fallthrough
|
|
||||||
case ExportKey:
|
case ExportKey:
|
||||||
key := ethutil.Config.Db.GetKeys()[0]
|
key := ethutil.Config.Db.GetKeys()[0]
|
||||||
logSys.Println(fmt.Sprintf("prvk: %x\n", key.PrivateKey))
|
logSys.Println(fmt.Sprintf("prvk: %x\n", key.PrivateKey))
|
||||||
@ -111,6 +110,9 @@ func main() {
|
|||||||
case ShowGenesis:
|
case ShowGenesis:
|
||||||
logSys.Println(ethereum.BlockChain().Genesis())
|
logSys.Println(ethereum.BlockChain().Genesis())
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
default:
|
||||||
|
// Creates a keypair if non exists
|
||||||
|
utils.CreateKeyPair(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// client
|
// client
|
||||||
|
Loading…
Reference in New Issue
Block a user