From 0ed1a8b50a9b9726cd57a2731d0405f6949c6188 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 31 Oct 2014 14:30:08 +0100 Subject: ethpipe => xeth (eXtended ETHereum) --- cmd/mist/bindings.go | 4 +- cmd/mist/ext_app.go | 6 +- cmd/mist/gui.go | 22 ++-- cmd/mist/html_container.go | 4 +- cmd/mist/qml_container.go | 4 +- cmd/mist/ui_lib.go | 16 +-- cmd/utils/cmd.go | 4 +- cmd/utils/websockets.go | 4 +- ethpipe/config.go | 33 ----- ethpipe/js_pipe.go | 264 --------------------------------------- ethpipe/js_types.go | 229 --------------------------------- ethpipe/object.go | 26 ---- ethpipe/pipe.go | 171 ------------------------- ethpipe/vm_env.go | 40 ------ ethpipe/world.go | 64 ---------- javascript/javascript_runtime.go | 6 +- javascript/types.go | 22 ++-- rpc/packages.go | 4 +- rpc/server.go | 6 +- xeth/config.go | 33 +++++ xeth/hexface.go | 264 +++++++++++++++++++++++++++++++++++++++ xeth/js_types.go | 229 +++++++++++++++++++++++++++++++++ xeth/object.go | 26 ++++ xeth/pipe.go | 175 ++++++++++++++++++++++++++ xeth/vm_env.go | 40 ++++++ xeth/world.go | 64 ++++++++++ 26 files changed, 882 insertions(+), 878 deletions(-) delete mode 100644 ethpipe/config.go delete mode 100644 ethpipe/js_pipe.go delete mode 100644 ethpipe/js_types.go delete mode 100644 ethpipe/object.go delete mode 100644 ethpipe/pipe.go delete mode 100644 ethpipe/vm_env.go delete mode 100644 ethpipe/world.go create mode 100644 xeth/config.go create mode 100644 xeth/hexface.go create mode 100644 xeth/js_types.go create mode 100644 xeth/object.go create mode 100644 xeth/pipe.go create mode 100644 xeth/vm_env.go create mode 100644 xeth/world.go diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go index f5a0dfcff..196fd38a1 100644 --- a/cmd/mist/bindings.go +++ b/cmd/mist/bindings.go @@ -24,9 +24,9 @@ import ( "github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/xeth" ) type plugin struct { @@ -46,7 +46,7 @@ func (gui *Gui) LogPrint(level logger.LogLevel, msg string) { } */ } -func (gui *Gui) Transact(recipient, value, gas, gasPrice, d string) (*ethpipe.JSReceipt, error) { +func (gui *Gui) Transact(recipient, value, gas, gasPrice, d string) (*xeth.JSReceipt, error) { var data string if len(recipient) == 0 { code, err := ethutil.Compile(d, false) diff --git a/cmd/mist/ext_app.go b/cmd/mist/ext_app.go index 8af9778bc..4a3ab1d2c 100644 --- a/cmd/mist/ext_app.go +++ b/cmd/mist/ext_app.go @@ -21,11 +21,11 @@ import ( "encoding/json" "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethstate" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/ui/qt" + "github.com/ethereum/go-ethereum/xeth" "gopkg.in/qml.v1" ) @@ -43,7 +43,7 @@ type AppContainer interface { } type ExtApplication struct { - *ethpipe.JSPipe + *xeth.JSXEth eth chain.EthManager events event.Subscription @@ -57,7 +57,7 @@ type ExtApplication struct { func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication { return &ExtApplication{ - JSPipe: ethpipe.NewJSPipe(lib.eth), + JSXEth: xeth.NewJSXEth(lib.eth), eth: lib.eth, watcherQuitChan: make(chan bool), filters: make(map[string]*chain.Filter), diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 4ae92a340..2dfdd104f 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -34,10 +34,10 @@ import ( "github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethminer" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethwire" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/xeth" "gopkg.in/qml.v1" ) @@ -84,7 +84,7 @@ type Gui struct { logLevel logger.LogLevel open bool - pipe *ethpipe.JSPipe + pipe *xeth.JSXEth Session string clientIdentity *ethwire.SimpleClientIdentity @@ -103,7 +103,7 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden panic(err) } - pipe := ethpipe.NewJSPipe(ethereum) + pipe := xeth.NewJSXEth(ethereum) gui := &Gui{eth: ethereum, txDb: db, pipe: pipe, logLevel: logger.LogLevel(logLevel), Session: session, open: false, clientIdentity: clientIdentity, config: config, plugins: make(map[string]plugin)} data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "plugins.json")) json.Unmarshal([]byte(data), &gui.plugins) @@ -117,11 +117,11 @@ func (gui *Gui) Start(assetPath string) { // Register ethereum functions qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ - Init: func(p *ethpipe.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" }, + Init: func(p *xeth.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" }, }, { - Init: func(p *ethpipe.JSTransaction, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, + Init: func(p *xeth.JSTransaction, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, }, { - Init: func(p *ethpipe.KeyVal, obj qml.Object) { p.Key = ""; p.Value = "" }, + Init: func(p *xeth.KeyVal, obj qml.Object) { p.Key = ""; p.Value = "" }, }}) // Create a new QML engine gui.engine = qml.NewEngine() @@ -287,7 +287,7 @@ func (gui *Gui) loadAddressBook() { } func (gui *Gui) insertTransaction(window string, tx *chain.Transaction) { - pipe := ethpipe.New(gui.eth) + pipe := xeth.New(gui.eth) nameReg := pipe.World().Config().Get("NameReg") addr := gui.address() @@ -299,7 +299,7 @@ func (gui *Gui) insertTransaction(window string, tx *chain.Transaction) { } var ( - ptx = ethpipe.NewJSTx(tx, pipe.World().State()) + ptx = xeth.NewJSTx(tx, pipe.World().State()) send = nameReg.Storage(tx.Sender()) rec = nameReg.Storage(tx.Recipient) s, r string @@ -346,7 +346,7 @@ func (gui *Gui) readPreviousTransactions() { func (gui *Gui) processBlock(block *chain.Block, initial bool) { name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase).Str(), "\x00") - b := ethpipe.NewJSBlock(block) + b := xeth.NewJSBlock(block) b.Name = name gui.getObjectByName("chainView").Call("addBlock", b, initial) @@ -451,12 +451,12 @@ func (gui *Gui) update() { if bytes.Compare(tx.Sender(), gui.address()) == 0 { object.SubAmount(tx.Value) - //gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "send") + //gui.getObjectByName("transactionView").Call("addTx", xeth.NewJSTx(tx), "send") gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { object.AddAmount(tx.Value) - //gui.getObjectByName("transactionView").Call("addTx", ethpipe.NewJSTx(tx), "recv") + //gui.getObjectByName("transactionView").Call("addTx", xeth.NewJSTx(tx), "recv") gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } diff --git a/cmd/mist/html_container.go b/cmd/mist/html_container.go index 755d5ea6e..082d65f67 100644 --- a/cmd/mist/html_container.go +++ b/cmd/mist/html_container.go @@ -28,10 +28,10 @@ import ( "path/filepath" "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethstate" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/javascript" + "github.com/ethereum/go-ethereum/xeth" "github.com/howeyc/fsnotify" "gopkg.in/qml.v1" ) @@ -139,7 +139,7 @@ func (app *HtmlApplication) Window() *qml.Window { } func (app *HtmlApplication) NewBlock(block *chain.Block) { - b := ðpipe.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} + b := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} app.webView.Call("onNewBlockCb", b) } diff --git a/cmd/mist/qml_container.go b/cmd/mist/qml_container.go index 13a50d988..4f6ca0b7f 100644 --- a/cmd/mist/qml_container.go +++ b/cmd/mist/qml_container.go @@ -22,9 +22,9 @@ import ( "runtime" "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethstate" "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/xeth" "gopkg.in/qml.v1" ) @@ -66,7 +66,7 @@ func (app *QmlApplication) NewWatcher(quitChan chan bool) { // Events func (app *QmlApplication) NewBlock(block *chain.Block) { - pblock := ðpipe.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} + pblock := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} app.win.Call("onNewBlockCb", pblock) } diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index 6fffa845f..9d2554cf4 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -27,11 +27,11 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethstate" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/ui/qt" + "github.com/ethereum/go-ethereum/xeth" "gopkg.in/qml.v1" ) @@ -42,7 +42,7 @@ type memAddr struct { // UI Library that has some basic functionality exposed type UiLib struct { - *ethpipe.JSPipe + *xeth.JSXEth engine *qml.Engine eth *eth.Ethereum connected bool @@ -58,7 +58,7 @@ type UiLib struct { } func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { - return &UiLib{JSPipe: ethpipe.NewJSPipe(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*ethpipe.JSFilter)} + return &UiLib{JSXEth: xeth.NewJSXEth(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)} } func (self *UiLib) Notef(args []interface{}) { @@ -214,7 +214,7 @@ func (self *UiLib) StartDebugger() { func (self *UiLib) NewFilter(object map[string]interface{}) (id int) { filter := qt.NewFilterFromMap(object, self.eth) filter.MessageCallback = func(messages ethstate.Messages) { - self.win.Root().Call("invokeFilterCallback", ethpipe.ToJSMessages(messages), id) + self.win.Root().Call("invokeFilterCallback", xeth.ToJSMessages(messages), id) } id = self.eth.InstallFilter(filter) return id @@ -232,7 +232,7 @@ func (self *UiLib) NewFilterString(typ string) (id int) { func (self *UiLib) Messages(id int) *ethutil.List { filter := self.eth.GetFilter(id) if filter != nil { - messages := ethpipe.ToJSMessages(filter.Find()) + messages := xeth.ToJSMessages(filter.Find()) return messages } @@ -295,10 +295,10 @@ func mapToTxParams(object map[string]interface{}) map[string]string { return conv } -func (self *UiLib) Transact(params map[string]interface{}) (*ethpipe.JSReceipt, error) { +func (self *UiLib) Transact(params map[string]interface{}) (*xeth.JSReceipt, error) { object := mapToTxParams(params) - return self.JSPipe.Transact( + return self.JSXEth.Transact( object["from"], object["to"], object["value"], @@ -320,7 +320,7 @@ func (self *UiLib) Compile(code string) (string, error) { func (self *UiLib) Call(params map[string]interface{}) (string, error) { object := mapToTxParams(params) - return self.JSPipe.Execute( + return self.JSXEth.Execute( object["to"], object["value"], object["gas"], diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 7ee41d042..d9914a6f4 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -17,11 +17,11 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethminer" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethwire" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/xeth" ) var clilogger = logger.NewLogger("CLI") @@ -244,7 +244,7 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre func StartRpc(ethereum *eth.Ethereum, RpcPort int) { var err error - ethereum.RpcServer, err = rpc.NewJsonRpcServer(ethpipe.NewJSPipe(ethereum), RpcPort) + ethereum.RpcServer, err = rpc.NewJsonRpcServer(xeth.NewJSXEth(ethereum), RpcPort) if err != nil { clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err) } else { diff --git a/cmd/utils/websockets.go b/cmd/utils/websockets.go index 7bda805ac..d3ba50e78 100644 --- a/cmd/utils/websockets.go +++ b/cmd/utils/websockets.go @@ -2,9 +2,9 @@ package utils import ( "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/websocket" + "github.com/ethereum/go-ethereum/xeth" ) func args(v ...interface{}) []interface{} { @@ -21,7 +21,7 @@ func NewWebSocketServer(eth *eth.Ethereum) *WebSocketServer { } func (self *WebSocketServer) Serv() { - pipe := ethpipe.NewJSPipe(self.ethereum) + pipe := xeth.NewJSXEth(self.ethereum) wsServ := websocket.NewServer("/eth", ":40404") wsServ.MessageFunc(func(c *websocket.Client, msg *websocket.Message) { diff --git a/ethpipe/config.go b/ethpipe/config.go deleted file mode 100644 index bea5005b6..000000000 --- a/ethpipe/config.go +++ /dev/null @@ -1,33 +0,0 @@ -package ethpipe - -import "github.com/ethereum/go-ethereum/ethutil" - -var cnfCtr = ethutil.Hex2Bytes("661005d2720d855f1d9976f88bb10c1a3398c77f") - -type Config struct { - pipe *Pipe -} - -func (self *Config) Get(name string) *Object { - configCtrl := self.pipe.World().safeGet(cnfCtr) - var addr []byte - - switch name { - case "NameReg": - addr = []byte{0} - case "DnsReg": - objectAddr := configCtrl.GetStorage(ethutil.BigD([]byte{0})) - domainAddr := (&Object{self.pipe.World().safeGet(objectAddr.Bytes())}).StorageString("DnsReg").Bytes() - return &Object{self.pipe.World().safeGet(domainAddr)} - default: - addr = ethutil.RightPadBytes([]byte(name), 32) - } - - objectAddr := configCtrl.GetStorage(ethutil.BigD(addr)) - - return &Object{self.pipe.World().safeGet(objectAddr.Bytes())} -} - -func (self *Config) Exist() bool { - return self.pipe.World().Get(cnfCtr) != nil -} diff --git a/ethpipe/js_pipe.go b/ethpipe/js_pipe.go deleted file mode 100644 index eb365f007..000000000 --- a/ethpipe/js_pipe.go +++ /dev/null @@ -1,264 +0,0 @@ -package ethpipe - -import ( - "bytes" - "encoding/json" - "sync/atomic" - - "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethstate" - "github.com/ethereum/go-ethereum/ethutil" -) - -type JSPipe struct { - *Pipe -} - -func NewJSPipe(eth chain.EthManager) *JSPipe { - return &JSPipe{New(eth)} -} - -func (self *JSPipe) BlockByHash(strHash string) *JSBlock { - hash := ethutil.Hex2Bytes(strHash) - block := self.obj.ChainManager().GetBlock(hash) - - return NewJSBlock(block) -} - -func (self *JSPipe) BlockByNumber(num int32) *JSBlock { - if num == -1 { - return NewJSBlock(self.obj.ChainManager().CurrentBlock) - } - - return NewJSBlock(self.obj.ChainManager().GetBlockByNumber(uint64(num))) -} - -func (self *JSPipe) Block(v interface{}) *JSBlock { - if n, ok := v.(int32); ok { - return self.BlockByNumber(n) - } else if str, ok := v.(string); ok { - return self.BlockByHash(str) - } else if f, ok := v.(float64); ok { // Don't ask ... - return self.BlockByNumber(int32(f)) - } - - return nil -} - -func (self *JSPipe) Key() *JSKey { - return NewJSKey(self.obj.KeyManager().KeyPair()) -} - -func (self *JSPipe) StateObject(addr string) *JSObject { - object := &Object{self.World().safeGet(ethutil.Hex2Bytes(addr))} - - return NewJSObject(object) -} - -func (self *JSPipe) PeerCount() int { - return self.obj.PeerCount() -} - -func (self *JSPipe) Peers() []JSPeer { - var peers []JSPeer - for peer := self.obj.Peers().Front(); peer != nil; peer = peer.Next() { - p := peer.Value.(chain.Peer) - // we only want connected peers - if atomic.LoadInt32(p.Connected()) != 0 { - peers = append(peers, *NewJSPeer(p)) - } - } - - return peers -} - -func (self *JSPipe) IsMining() bool { - return self.obj.IsMining() -} - -func (self *JSPipe) IsListening() bool { - return self.obj.IsListening() -} - -func (self *JSPipe) CoinBase() string { - return ethutil.Bytes2Hex(self.obj.KeyManager().Address()) -} - -func (self *JSPipe) NumberToHuman(balance string) string { - b := ethutil.Big(balance) - - return ethutil.CurrencyToString(b) -} - -func (self *JSPipe) StorageAt(addr, storageAddr string) string { - storage := self.World().SafeGet(ethutil.Hex2Bytes(addr)).Storage(ethutil.Hex2Bytes(storageAddr)) - - return ethutil.Bytes2Hex(storage.Bytes()) -} - -func (self *JSPipe) BalanceAt(addr string) string { - return self.World().SafeGet(ethutil.Hex2Bytes(addr)).Balance().String() -} - -func (self *JSPipe) TxCountAt(address string) int { - return int(self.World().SafeGet(ethutil.Hex2Bytes(address)).Nonce) -} - -func (self *JSPipe) CodeAt(address string) string { - return ethutil.Bytes2Hex(self.World().SafeGet(ethutil.Hex2Bytes(address)).Code) -} - -func (self *JSPipe) IsContract(address string) bool { - return len(self.World().SafeGet(ethutil.Hex2Bytes(address)).Code) > 0 -} - -func (self *JSPipe) SecretToAddress(key string) string { - pair, err := crypto.NewKeyPairFromSec(ethutil.Hex2Bytes(key)) - if err != nil { - return "" - } - - return ethutil.Bytes2Hex(pair.Address()) -} - -func (self *JSPipe) Execute(addr, value, gas, price, data string) (string, error) { - ret, err := self.ExecuteObject(&Object{ - self.World().safeGet(ethutil.Hex2Bytes(addr))}, - ethutil.Hex2Bytes(data), - ethutil.NewValue(value), - ethutil.NewValue(gas), - ethutil.NewValue(price), - ) - - return ethutil.Bytes2Hex(ret), err -} - -type KeyVal struct { - Key string `json:"key"` - Value string `json:"value"` -} - -func (self *JSPipe) EachStorage(addr string) string { - var values []KeyVal - object := self.World().SafeGet(ethutil.Hex2Bytes(addr)) - object.EachStorage(func(name string, value *ethutil.Value) { - value.Decode() - values = append(values, KeyVal{ethutil.Bytes2Hex([]byte(name)), ethutil.Bytes2Hex(value.Bytes())}) - }) - - valuesJson, err := json.Marshal(values) - if err != nil { - return "" - } - - return string(valuesJson) -} - -func (self *JSPipe) ToAscii(str string) string { - padded := ethutil.RightPadBytes([]byte(str), 32) - - return "0x" + ethutil.Bytes2Hex(padded) -} - -func (self *JSPipe) FromAscii(str string) string { - if ethutil.IsHex(str) { - str = str[2:] - } - - return string(bytes.Trim(ethutil.Hex2Bytes(str), "\x00")) -} - -func (self *JSPipe) FromNumber(str string) string { - if ethutil.IsHex(str) { - str = str[2:] - } - - return ethutil.BigD(ethutil.Hex2Bytes(str)).String() -} - -func (self *JSPipe) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (*JSReceipt, error) { - var hash []byte - var contractCreation bool - if len(toStr) == 0 { - contractCreation = true - } else { - // Check if an address is stored by this address - addr := self.World().Config().Get("NameReg").StorageString(toStr).Bytes() - if len(addr) > 0 { - hash = addr - } else { - hash = ethutil.Hex2Bytes(toStr) - } - } - - var keyPair *crypto.KeyPair - var err error - if ethutil.IsHex(key) { - keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key[2:]))) - } else { - keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key))) - } - - if err != nil { - return nil, err - } - - var ( - value = ethutil.Big(valueStr) - gas = ethutil.Big(gasStr) - gasPrice = ethutil.Big(gasPriceStr) - data []byte - tx *chain.Transaction - ) - - if ethutil.IsHex(codeStr) { - data = ethutil.Hex2Bytes(codeStr[2:]) - } else { - data = ethutil.Hex2Bytes(codeStr) - } - - if contractCreation { - tx = chain.NewContractCreationTx(value, gas, gasPrice, data) - } else { - tx = chain.NewTransactionMessage(hash, value, gas, gasPrice, data) - } - - acc := self.obj.StateManager().TransState().GetOrNewStateObject(keyPair.Address()) - tx.Nonce = acc.Nonce - acc.Nonce += 1 - self.obj.StateManager().TransState().UpdateStateObject(acc) - - tx.Sign(keyPair.PrivateKey) - self.obj.TxPool().QueueTransaction(tx) - - if contractCreation { - pipelogger.Infof("Contract addr %x", tx.CreationAddress(self.World().State())) - } - - return NewJSReciept(contractCreation, tx.CreationAddress(self.World().State()), tx.Hash(), keyPair.Address()), nil -} - -func (self *JSPipe) PushTx(txStr string) (*JSReceipt, error) { - tx := chain.NewTransactionFromBytes(ethutil.Hex2Bytes(txStr)) - self.obj.TxPool().QueueTransaction(tx) - return NewJSReciept(tx.CreatesContract(), tx.CreationAddress(self.World().State()), tx.Hash(), tx.Sender()), nil -} - -func (self *JSPipe) CompileMutan(code string) string { - data, err := self.Pipe.CompileMutan(code) - if err != nil { - return err.Error() - } - - return ethutil.Bytes2Hex(data) -} - -func ToJSMessages(messages ethstate.Messages) *ethutil.List { - var msgs []JSMessage - for _, m := range messages { - msgs = append(msgs, NewJSMessage(m)) - } - - return ethutil.NewList(msgs) -} diff --git a/ethpipe/js_types.go b/ethpipe/js_types.go deleted file mode 100644 index 3daf015ca..000000000 --- a/ethpipe/js_types.go +++ /dev/null @@ -1,229 +0,0 @@ -package ethpipe - -import ( - "fmt" - "strconv" - "strings" - - "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethstate" - "github.com/ethereum/go-ethereum/ethutil" -) - -// Block interface exposed to QML -type JSBlock struct { - //Transactions string `json:"transactions"` - ref *chain.Block - Size string `json:"size"` - Number int `json:"number"` - Hash string `json:"hash"` - Transactions *ethutil.List `json:"transactions"` - Uncles *ethutil.List `json:"uncles"` - Time int64 `json:"time"` - Coinbase string `json:"coinbase"` - Name string `json:"name"` - GasLimit string `json:"gasLimit"` - GasUsed string `json:"gasUsed"` - PrevHash string `json:"prevHash"` -} - -// Creates a new QML Block from a chain block -func NewJSBlock(block *chain.Block) *JSBlock { - if block == nil { - return &JSBlock{} - } - - ptxs := make([]*JSTransaction, len(block.Transactions())) - for i, tx := range block.Transactions() { - ptxs[i] = NewJSTx(tx, block.State()) - } - txlist := ethutil.NewList(ptxs) - - puncles := make([]*JSBlock, len(block.Uncles)) - for i, uncle := range block.Uncles { - puncles[i] = NewJSBlock(uncle) - } - ulist := ethutil.NewList(puncles) - - return &JSBlock{ - ref: block, Size: block.Size().String(), - Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(), - GasLimit: block.GasLimit.String(), Hash: ethutil.Bytes2Hex(block.Hash()), - Transactions: txlist, Uncles: ulist, - Time: block.Time, - Coinbase: ethutil.Bytes2Hex(block.Coinbase), - PrevHash: ethutil.Bytes2Hex(block.PrevHash), - } -} - -func (self *JSBlock) ToString() string { - if self.ref != nil { - return self.ref.String() - } - - return "" -} - -func (self *JSBlock) GetTransaction(hash string) *JSTransaction { - tx := self.ref.GetTransaction(ethutil.Hex2Bytes(hash)) - if tx == nil { - return nil - } - - return NewJSTx(tx, self.ref.State()) -} - -type JSTransaction struct { - ref *chain.Transaction - - Value string `json:"value"` - Gas string `json:"gas"` - GasPrice string `json:"gasPrice"` - Hash string `json:"hash"` - Address string `json:"address"` - Sender string `json:"sender"` - RawData string `json:"rawData"` - Data string `json:"data"` - Contract bool `json:"isContract"` - CreatesContract bool `json:"createsContract"` - Confirmations int `json:"confirmations"` -} - -func NewJSTx(tx *chain.Transaction, state *ethstate.State) *JSTransaction { - hash := ethutil.Bytes2Hex(tx.Hash()) - receiver := ethutil.Bytes2Hex(tx.Recipient) - if receiver == "0000000000000000000000000000000000000000" { - receiver = ethutil.Bytes2Hex(tx.CreationAddress(state)) - } - sender := ethutil.Bytes2Hex(tx.Sender()) - createsContract := tx.CreatesContract() - - var data string - if tx.CreatesContract() { - data = strings.Join(chain.Disassemble(tx.Data), "\n") - } else { - data = ethutil.Bytes2Hex(tx.Data) - } - - return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: receiver, Contract: tx.CreatesContract(), Gas: tx.Gas.String(), GasPrice: tx.GasPrice.String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data)} -} - -func (self *JSTransaction) ToString() string { - return self.ref.String() -} - -type JSKey struct { - Address string `json:"address"` - PrivateKey string `json:"privateKey"` - PublicKey string `json:"publicKey"` -} - -func NewJSKey(key *crypto.KeyPair) *JSKey { - return &JSKey{ethutil.Bytes2Hex(key.Address()), ethutil.Bytes2Hex(key.PrivateKey), ethutil.Bytes2Hex(key.PublicKey)} -} - -type JSObject struct { - *Object -} - -func NewJSObject(object *Object) *JSObject { - return &JSObject{object} -} - -type PReceipt struct { - CreatedContract bool `json:"createdContract"` - Address string `json:"address"` - Hash string `json:"hash"` - Sender string `json:"sender"` -} - -func NewPReciept(contractCreation bool, creationAddress, hash, address []byte) *PReceipt { - return &PReceipt{ - contractCreation, - ethutil.Bytes2Hex(creationAddress), - ethutil.Bytes2Hex(hash), - ethutil.Bytes2Hex(address), - } -} - -// Peer interface exposed to QML - -type JSPeer struct { - ref *chain.Peer - Inbound bool `json:"isInbound"` - LastSend int64 `json:"lastSend"` - LastPong int64 `json:"lastPong"` - Ip string `json:"ip"` - Port int `json:"port"` - Version string `json:"version"` - LastResponse string `json:"lastResponse"` - Latency string `json:"latency"` - Caps string `json:"caps"` -} - -func NewJSPeer(peer chain.Peer) *JSPeer { - if peer == nil { - return nil - } - - var ip []string - for _, i := range peer.Host() { - ip = append(ip, strconv.Itoa(int(i))) - } - ipAddress := strings.Join(ip, ".") - - var caps []string - capsIt := peer.Caps().NewIterator() - for capsIt.Next() { - caps = append(caps, capsIt.Value().Str()) - } - - return &JSPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port()), Latency: peer.PingTime(), Caps: fmt.Sprintf("%v", caps)} -} - -type JSReceipt struct { - CreatedContract bool `json:"createdContract"` - Address string `json:"address"` - Hash string `json:"hash"` - Sender string `json:"sender"` -} - -func NewJSReciept(contractCreation bool, creationAddress, hash, address []byte) *JSReceipt { - return &JSReceipt{ - contractCreation, - ethutil.Bytes2Hex(creationAddress), - ethutil.Bytes2Hex(hash), - ethutil.Bytes2Hex(address), - } -} - -type JSMessage struct { - To string `json:"to"` - From string `json:"from"` - Input string `json:"input"` - Output string `json:"output"` - Path int32 `json:"path"` - Origin string `json:"origin"` - Timestamp int32 `json:"timestamp"` - Coinbase string `json:"coinbase"` - Block string `json:"block"` - Number int32 `json:"number"` - Value string `json:"value"` -} - -func NewJSMessage(message *ethstate.Message) JSMessage { - return JSMessage{ - To: ethutil.Bytes2Hex(message.To), - From: ethutil.Bytes2Hex(message.From), - Input: ethutil.Bytes2Hex(message.Input), - Output: ethutil.Bytes2Hex(message.Output), - Path: int32(message.Path), - Origin: ethutil.Bytes2Hex(message.Origin), - Timestamp: int32(message.Timestamp), - Coinbase: ethutil.Bytes2Hex(message.Origin), - Block: ethutil.Bytes2Hex(message.Block), - Number: int32(message.Number.Int64()), - Value: message.Value.String(), - } -} diff --git a/ethpipe/object.go b/ethpipe/object.go deleted file mode 100644 index 356ed788c..000000000 --- a/ethpipe/object.go +++ /dev/null @@ -1,26 +0,0 @@ -package ethpipe - -import ( - "github.com/ethereum/go-ethereum/ethstate" - "github.com/ethereum/go-ethereum/ethutil" -) - -type Object struct { - *ethstate.StateObject -} - -func (self *Object) StorageString(str string) *ethutil.Value { - if ethutil.IsHex(str) { - return self.Storage(ethutil.Hex2Bytes(str[2:])) - } else { - return self.Storage(ethutil.RightPadBytes([]byte(str), 32)) - } -} - -func (self *Object) StorageValue(addr *ethutil.Value) *ethutil.Value { - return self.Storage(addr.Bytes()) -} - -func (self *Object) Storage(addr []byte) *ethutil.Value { - return self.StateObject.GetStorage(ethutil.BigD(addr)) -} diff --git a/ethpipe/pipe.go b/ethpipe/pipe.go deleted file mode 100644 index f6fee3923..000000000 --- a/ethpipe/pipe.go +++ /dev/null @@ -1,171 +0,0 @@ -package ethpipe - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethstate" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/vm" -) - -var pipelogger = logger.NewLogger("PIPE") - -type VmVars struct { - State *ethstate.State -} - -type Pipe struct { - obj chain.EthManager - stateManager *chain.StateManager - blockChain *chain.ChainManager - world *World - - Vm VmVars -} - -func New(obj chain.EthManager) *Pipe { - pipe := &Pipe{ - obj: obj, - stateManager: obj.StateManager(), - blockChain: obj.ChainManager(), - } - pipe.world = NewWorld(pipe) - - return pipe -} - -func (self *Pipe) Balance(addr []byte) *ethutil.Value { - return ethutil.NewValue(self.World().safeGet(addr).Balance) -} - -func (self *Pipe) Nonce(addr []byte) uint64 { - return self.World().safeGet(addr).Nonce -} - -func (self *Pipe) Execute(addr []byte, data []byte, value, gas, price *ethutil.Value) ([]byte, error) { - return self.ExecuteObject(&Object{self.World().safeGet(addr)}, data, value, gas, price) -} - -func (self *Pipe) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) { - var ( - initiator = ethstate.NewStateObject(self.obj.KeyManager().KeyPair().Address()) - block = self.blockChain.CurrentBlock - ) - - self.Vm.State = self.World().State().Copy() - - evm := vm.New(NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address()), vm.Type(ethutil.Config.VmType)) - - msg := vm.NewExecution(evm, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt()) - ret, err := msg.Exec(object.Address(), initiator) - - fmt.Println("returned from call", ret, err) - - return ret, err -} - -func (self *Pipe) Block(hash []byte) *chain.Block { - return self.blockChain.GetBlock(hash) -} - -func (self *Pipe) Storage(addr, storageAddr []byte) *ethutil.Value { - return self.World().safeGet(addr).GetStorage(ethutil.BigD(storageAddr)) -} - -func (self *Pipe) ToAddress(priv []byte) []byte { - pair, err := crypto.NewKeyPairFromSec(priv) - if err != nil { - return nil - } - - return pair.Address() -} - -func (self *Pipe) Exists(addr []byte) bool { - return self.World().Get(addr) != nil -} - -func (self *Pipe) TransactString(key *crypto.KeyPair, rec string, value, gas, price *ethutil.Value, data []byte) ([]byte, error) { - // Check if an address is stored by this address - var hash []byte - addr := self.World().Config().Get("NameReg").StorageString(rec).Bytes() - if len(addr) > 0 { - hash = addr - } else if ethutil.IsHex(rec) { - hash = ethutil.Hex2Bytes(rec[2:]) - } else { - hash = ethutil.Hex2Bytes(rec) - } - - return self.Transact(key, hash, value, gas, price, data) -} - -func (self *Pipe) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *ethutil.Value, data []byte) ([]byte, error) { - var hash []byte - var contractCreation bool - if rec == nil { - contractCreation = true - } - - var tx *chain.Transaction - // Compile and assemble the given data - if contractCreation { - script, err := ethutil.Compile(string(data), false) - if err != nil { - return nil, err - } - - tx = chain.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), script) - } else { - data := ethutil.StringToByteFunc(string(data), func(s string) (ret []byte) { - slice := strings.Split(s, "\n") - for _, dataItem := range slice { - d := ethutil.FormatData(dataItem) - ret = append(ret, d...) - } - return - }) - - tx = chain.NewTransactionMessage(hash, value.BigInt(), gas.BigInt(), price.BigInt(), data) - } - - acc := self.stateManager.TransState().GetOrNewStateObject(key.Address()) - tx.Nonce = acc.Nonce - acc.Nonce += 1 - self.stateManager.TransState().UpdateStateObject(acc) - - tx.Sign(key.PrivateKey) - self.obj.TxPool().QueueTransaction(tx) - - if contractCreation { - addr := tx.CreationAddress(self.World().State()) - pipelogger.Infof("Contract addr %x\n", addr) - - return addr, nil - } - - return tx.Hash(), nil -} - -func (self *Pipe) PushTx(tx *chain.Transaction) ([]byte, error) { - self.obj.TxPool().QueueTransaction(tx) - if tx.Recipient == nil { - addr := tx.CreationAddress(self.World().State()) - pipelogger.Infof("Contract addr %x\n", addr) - return addr, nil - } - return tx.Hash(), nil -} - -func (self *Pipe) CompileMutan(code string) ([]byte, error) { - data, err := ethutil.Compile(code, false) - if err != nil { - return nil, err - } - - return data, nil -} diff --git a/ethpipe/vm_env.go b/ethpipe/vm_env.go deleted file mode 100644 index baab67b28..000000000 --- a/ethpipe/vm_env.go +++ /dev/null @@ -1,40 +0,0 @@ -package ethpipe - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/chain" - "github.com/ethereum/go-ethereum/ethstate" - "github.com/ethereum/go-ethereum/vm" -) - -type VMEnv struct { - state *ethstate.State - block *chain.Block - value *big.Int - sender []byte -} - -func NewEnv(state *ethstate.State, block *chain.Block, value *big.Int, sender []byte) *VMEnv { - return &VMEnv{ - state: state, - block: block, - value: value, - sender: sender, - } -} - -func (self *VMEnv) Origin() []byte { return self.sender } -func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number } -func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash } -func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase } -func (self *VMEnv) Time() int64 { return self.block.Time } -func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty } -func (self *VMEnv) BlockHash() []byte { return self.block.Hash() } -func (self *VMEnv) Value() *big.Int { return self.value } -func (self *VMEnv) State() *ethstate.State { return self.state } -func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit } -func (self *VMEnv) AddLog(ethstate.Log) {} -func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { - return vm.Transfer(from, to, amount) -} diff --git a/ethpipe/world.go b/ethpipe/world.go deleted file mode 100644 index e34bd31aa..000000000 --- a/ethpipe/world.go +++ /dev/null @@ -1,64 +0,0 @@ -package ethpipe - -import ( - "container/list" - - "github.com/ethereum/go-ethereum/ethstate" -) - -type World struct { - pipe *Pipe - cfg *Config -} - -func NewWorld(pipe *Pipe) *World { - world := &World{pipe, nil} - world.cfg = &Config{pipe} - - return world -} - -func (self *Pipe) World() *World { - return self.world -} - -func (self *World) State() *ethstate.State { - return self.pipe.stateManager.CurrentState() -} - -func (self *World) Get(addr []byte) *Object { - return &Object{self.State().GetStateObject(addr)} -} - -func (self *World) SafeGet(addr []byte) *Object { - return &Object{self.safeGet(addr)} -} - -func (self *World) safeGet(addr []byte) *ethstate.StateObject { - object := self.State().GetStateObject(addr) - if object == nil { - object = ethstate.NewStateObject(addr) - } - - return object -} - -func (self *World) Coinbase() *ethstate.StateObject { - return nil -} - -func (self *World) IsMining() bool { - return self.pipe.obj.IsMining() -} - -func (self *World) IsListening() bool { - return self.pipe.obj.IsListening() -} - -func (self *World) Peers() *list.List { - return self.pipe.obj.Peers() -} - -func (self *World) Config() *Config { - return self.cfg -} diff --git a/javascript/javascript_runtime.go b/javascript/javascript_runtime.go index deb6fe305..5885e5c6e 100644 --- a/javascript/javascript_runtime.go +++ b/javascript/javascript_runtime.go @@ -10,11 +10,11 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/chain" "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethstate" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/xeth" "github.com/obscuren/otto" ) @@ -23,7 +23,7 @@ var jsrelogger = logger.NewLogger("JSRE") type JSRE struct { ethereum *eth.Ethereum Vm *otto.Otto - pipe *ethpipe.JSPipe + pipe *xeth.JSXEth events event.Subscription @@ -48,7 +48,7 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE { re := &JSRE{ ethereum, otto.New(), - ethpipe.NewJSPipe(ethereum), + xeth.NewJSXEth(ethereum), nil, make(map[string][]otto.Value), } diff --git a/javascript/types.go b/javascript/types.go index b02ee9dc2..a98c48905 100644 --- a/javascript/types.go +++ b/javascript/types.go @@ -4,15 +4,15 @@ import ( "fmt" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethstate" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ui" + "github.com/ethereum/go-ethereum/xeth" "github.com/obscuren/otto" ) type JSStateObject struct { - *ethpipe.JSObject + *xeth.JSObject eth *JSEthereum } @@ -30,7 +30,7 @@ func (self *JSStateObject) EachStorage(call otto.FunctionCall) otto.Value { // The JSEthereum object attempts to wrap the PEthereum object and returns // meaningful javascript objects type JSBlock struct { - *ethpipe.JSBlock + *xeth.JSBlock eth *JSEthereum } @@ -67,33 +67,33 @@ func NewJSMessage(message *ethstate.Message) JSMessage { } type JSEthereum struct { - *ethpipe.JSPipe + *xeth.JSXEth vm *otto.Otto ethereum *eth.Ethereum } func (self *JSEthereum) GetBlock(hash string) otto.Value { - return self.toVal(&JSBlock{self.JSPipe.BlockByHash(hash), self}) + return self.toVal(&JSBlock{self.JSXEth.BlockByHash(hash), self}) } func (self *JSEthereum) GetPeers() otto.Value { - return self.toVal(self.JSPipe.Peers()) + return self.toVal(self.JSXEth.Peers()) } func (self *JSEthereum) GetKey() otto.Value { - return self.toVal(self.JSPipe.Key()) + return self.toVal(self.JSXEth.Key()) } func (self *JSEthereum) GetStateObject(addr string) otto.Value { - return self.toVal(&JSStateObject{ethpipe.NewJSObject(self.JSPipe.World().SafeGet(ethutil.Hex2Bytes(addr))), self}) + return self.toVal(&JSStateObject{xeth.NewJSObject(self.JSXEth.World().SafeGet(ethutil.Hex2Bytes(addr))), self}) } func (self *JSEthereum) Peers() otto.Value { - return self.toVal(self.JSPipe.Peers()) + return self.toVal(self.JSXEth.Peers()) } func (self *JSEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) otto.Value { - r, err := self.JSPipe.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr) + r, err := self.JSXEth.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr) if err != nil { fmt.Println(err) @@ -104,7 +104,7 @@ func (self *JSEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, } func (self *JSEthereum) Create(key, valueStr, gasStr, gasPriceStr, scriptStr string) otto.Value { - r, err := self.JSPipe.Transact(key, "", valueStr, gasStr, gasPriceStr, scriptStr) + r, err := self.JSXEth.Transact(key, "", valueStr, gasStr, gasPriceStr, scriptStr) if err != nil { fmt.Println(err) diff --git a/rpc/packages.go b/rpc/packages.go index 31500867c..5535e6e79 100644 --- a/rpc/packages.go +++ b/rpc/packages.go @@ -6,12 +6,12 @@ import ( "math/big" "strings" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/xeth" ) type EthereumApi struct { - pipe *ethpipe.JSPipe + pipe *xeth.JSXEth } type JsonArgs interface { diff --git a/rpc/server.go b/rpc/server.go index 20f75ce67..983dc6c33 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -6,8 +6,8 @@ import ( "net/rpc" "net/rpc/jsonrpc" - "github.com/ethereum/go-ethereum/ethpipe" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/xeth" ) var jsonlogger = logger.NewLogger("JSON") @@ -15,7 +15,7 @@ var jsonlogger = logger.NewLogger("JSON") type JsonRpcServer struct { quit chan bool listener net.Listener - pipe *ethpipe.JSPipe + pipe *xeth.JSXEth } func (s *JsonRpcServer) exitHandler() { @@ -52,7 +52,7 @@ func (s *JsonRpcServer) Start() { } } -func NewJsonRpcServer(pipe *ethpipe.JSPipe, port int) (*JsonRpcServer, error) { +func NewJsonRpcServer(pipe *xeth.JSXEth, port int) (*JsonRpcServer, error) { sport := fmt.Sprintf(":%d", port) l, err := net.Listen("tcp", sport) if err != nil { diff --git a/xeth/config.go b/xeth/config.go new file mode 100644 index 000000000..34aa9e32d --- /dev/null +++ b/xeth/config.go @@ -0,0 +1,33 @@ +package xeth + +import "github.com/ethereum/go-ethereum/ethutil" + +var cnfCtr = ethutil.Hex2Bytes("661005d2720d855f1d9976f88bb10c1a3398c77f") + +type Config struct { + pipe *XEth +} + +func (self *Config) Get(name string) *Object { + configCtrl := self.pipe.World().safeGet(cnfCtr) + var addr []byte + + switch name { + case "NameReg": + addr = []byte{0} + case "DnsReg": + objectAddr := configCtrl.GetStorage(ethutil.BigD([]byte{0})) + domainAddr := (&Object{self.pipe.World().safeGet(objectAddr.Bytes())}).StorageString("DnsReg").Bytes() + return &Object{self.pipe.World().safeGet(domainAddr)} + default: + addr = ethutil.RightPadBytes([]byte(name), 32) + } + + objectAddr := configCtrl.GetStorage(ethutil.BigD(addr)) + + return &Object{self.pipe.World().safeGet(objectAddr.Bytes())} +} + +func (self *Config) Exist() bool { + return self.pipe.World().Get(cnfCtr) != nil +} diff --git a/xeth/hexface.go b/xeth/hexface.go new file mode 100644 index 000000000..829f530f4 --- /dev/null +++ b/xeth/hexface.go @@ -0,0 +1,264 @@ +package xeth + +import ( + "bytes" + "encoding/json" + "sync/atomic" + + "github.com/ethereum/go-ethereum/chain" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethstate" + "github.com/ethereum/go-ethereum/ethutil" +) + +type JSXEth struct { + *XEth +} + +func NewJSXEth(eth chain.EthManager) *JSXEth { + return &JSXEth{New(eth)} +} + +func (self *JSXEth) BlockByHash(strHash string) *JSBlock { + hash := ethutil.Hex2Bytes(strHash) + block := self.obj.ChainManager().GetBlock(hash) + + return NewJSBlock(block) +} + +func (self *JSXEth) BlockByNumber(num int32) *JSBlock { + if num == -1 { + return NewJSBlock(self.obj.ChainManager().CurrentBlock) + } + + return NewJSBlock(self.obj.ChainManager().GetBlockByNumber(uint64(num))) +} + +func (self *JSXEth) Block(v interface{}) *JSBlock { + if n, ok := v.(int32); ok { + return self.BlockByNumber(n) + } else if str, ok := v.(string); ok { + return self.BlockByHash(str) + } else if f, ok := v.(float64); ok { // Don't ask ... + return self.BlockByNumber(int32(f)) + } + + return nil +} + +func (self *JSXEth) Key() *JSKey { + return NewJSKey(self.obj.KeyManager().KeyPair()) +} + +func (self *JSXEth) StateObject(addr string) *JSObject { + object := &Object{self.World().safeGet(ethutil.Hex2Bytes(addr))} + + return NewJSObject(object) +} + +func (self *JSXEth) PeerCount() int { + return self.obj.PeerCount() +} + +func (self *JSXEth) Peers() []JSPeer { + var peers []JSPeer + for peer := self.obj.Peers().Front(); peer != nil; peer = peer.Next() { + p := peer.Value.(chain.Peer) + // we only want connected peers + if atomic.LoadInt32(p.Connected()) != 0 { + peers = append(peers, *NewJSPeer(p)) + } + } + + return peers +} + +func (self *JSXEth) IsMining() bool { + return self.obj.IsMining() +} + +func (self *JSXEth) IsListening() bool { + return self.obj.IsListening() +} + +func (self *JSXEth) CoinBase() string { + return ethutil.Bytes2Hex(self.obj.KeyManager().Address()) +} + +func (self *JSXEth) NumberToHuman(balance string) string { + b := ethutil.Big(balance) + + return ethutil.CurrencyToString(b) +} + +func (self *JSXEth) StorageAt(addr, storageAddr string) string { + storage := self.World().SafeGet(ethutil.Hex2Bytes(addr)).Storage(ethutil.Hex2Bytes(storageAddr)) + + return ethutil.Bytes2Hex(storage.Bytes()) +} + +func (self *JSXEth) BalanceAt(addr string) string { + return self.World().SafeGet(ethutil.Hex2Bytes(addr)).Balance().String() +} + +func (self *JSXEth) TxCountAt(address string) int { + return int(self.World().SafeGet(ethutil.Hex2Bytes(address)).Nonce) +} + +func (self *JSXEth) CodeAt(address string) string { + return ethutil.Bytes2Hex(self.World().SafeGet(ethutil.Hex2Bytes(address)).Code) +} + +func (self *JSXEth) IsContract(address string) bool { + return len(self.World().SafeGet(ethutil.Hex2Bytes(address)).Code) > 0 +} + +func (self *JSXEth) SecretToAddress(key string) string { + pair, err := crypto.NewKeyPairFromSec(ethutil.Hex2Bytes(key)) + if err != nil { + return "" + } + + return ethutil.Bytes2Hex(pair.Address()) +} + +func (self *JSXEth) Execute(addr, value, gas, price, data string) (string, error) { + ret, err := self.ExecuteObject(&Object{ + self.World().safeGet(ethutil.Hex2Bytes(addr))}, + ethutil.Hex2Bytes(data), + ethutil.NewValue(value), + ethutil.NewValue(gas), + ethutil.NewValue(price), + ) + + return ethutil.Bytes2Hex(ret), err +} + +type KeyVal struct { + Key string `json:"key"` + Value string `json:"value"` +} + +func (self *JSXEth) EachStorage(addr string) string { + var values []KeyVal + object := self.World().SafeGet(ethutil.Hex2Bytes(addr)) + object.EachStorage(func(name string, value *ethutil.Value) { + value.Decode() + values = append(values, KeyVal{ethutil.Bytes2Hex([]byte(name)), ethutil.Bytes2Hex(value.Bytes())}) + }) + + valuesJson, err := json.Marshal(values) + if err != nil { + return "" + } + + return string(valuesJson) +} + +func (self *JSXEth) ToAscii(str string) string { + padded := ethutil.RightPadBytes([]byte(str), 32) + + return "0x" + ethutil.Bytes2Hex(padded) +} + +func (self *JSXEth) FromAscii(str string) string { + if ethutil.IsHex(str) { + str = str[2:] + } + + return string(bytes.Trim(ethutil.Hex2Bytes(str), "\x00")) +} + +func (self *JSXEth) FromNumber(str string) string { + if ethutil.IsHex(str) { + str = str[2:] + } + + return ethutil.BigD(ethutil.Hex2Bytes(str)).String() +} + +func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (*JSReceipt, error) { + var hash []byte + var contractCreation bool + if len(toStr) == 0 { + contractCreation = true + } else { + // Check if an address is stored by this address + addr := self.World().Config().Get("NameReg").StorageString(toStr).Bytes() + if len(addr) > 0 { + hash = addr + } else { + hash = ethutil.Hex2Bytes(toStr) + } + } + + var keyPair *crypto.KeyPair + var err error + if ethutil.IsHex(key) { + keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key[2:]))) + } else { + keyPair, err = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key))) + } + + if err != nil { + return nil, err + } + + var ( + value = ethutil.Big(valueStr) + gas = ethutil.Big(gasStr) + gasPrice = ethutil.Big(gasPriceStr) + data []byte + tx *chain.Transaction + ) + + if ethutil.IsHex(codeStr) { + data = ethutil.Hex2Bytes(codeStr[2:]) + } else { + data = ethutil.Hex2Bytes(codeStr) + } + + if contractCreation { + tx = chain.NewContractCreationTx(value, gas, gasPrice, data) + } else { + tx = chain.NewTransactionMessage(hash, value, gas, gasPrice, data) + } + + acc := self.obj.StateManager().TransState().GetOrNewStateObject(keyPair.Address()) + tx.Nonce = acc.Nonce + acc.Nonce += 1 + self.obj.StateManager().TransState().UpdateStateObject(acc) + + tx.Sign(keyPair.PrivateKey) + self.obj.TxPool().QueueTransaction(tx) + + if contractCreation { + pipelogger.Infof("Contract addr %x", tx.CreationAddress(self.World().State())) + } + + return NewJSReciept(contractCreation, tx.CreationAddress(self.World().State()), tx.Hash(), keyPair.Address()), nil +} + +func (self *JSXEth) PushTx(txStr string) (*JSReceipt, error) { + tx := chain.NewTransactionFromBytes(ethutil.Hex2Bytes(txStr)) + self.obj.TxPool().QueueTransaction(tx) + return NewJSReciept(tx.CreatesContract(), tx.CreationAddress(self.World().State()), tx.Hash(), tx.Sender()), nil +} + +func (self *JSXEth) CompileMutan(code string) string { + data, err := self.XEth.CompileMutan(code) + if err != nil { + return err.Error() + } + + return ethutil.Bytes2Hex(data) +} + +func ToJSMessages(messages ethstate.Messages) *ethutil.List { + var msgs []JSMessage + for _, m := range messages { + msgs = append(msgs, NewJSMessage(m)) + } + + return ethutil.NewList(msgs) +} diff --git a/xeth/js_types.go b/xeth/js_types.go new file mode 100644 index 000000000..058bfe0dd --- /dev/null +++ b/xeth/js_types.go @@ -0,0 +1,229 @@ +package xeth + +import ( + "fmt" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/chain" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethstate" + "github.com/ethereum/go-ethereum/ethutil" +) + +// Block interface exposed to QML +type JSBlock struct { + //Transactions string `json:"transactions"` + ref *chain.Block + Size string `json:"size"` + Number int `json:"number"` + Hash string `json:"hash"` + Transactions *ethutil.List `json:"transactions"` + Uncles *ethutil.List `json:"uncles"` + Time int64 `json:"time"` + Coinbase string `json:"coinbase"` + Name string `json:"name"` + GasLimit string `json:"gasLimit"` + GasUsed string `json:"gasUsed"` + PrevHash string `json:"prevHash"` +} + +// Creates a new QML Block from a chain block +func NewJSBlock(block *chain.Block) *JSBlock { + if block == nil { + return &JSBlock{} + } + + ptxs := make([]*JSTransaction, len(block.Transactions())) + for i, tx := range block.Transactions() { + ptxs[i] = NewJSTx(tx, block.State()) + } + txlist := ethutil.NewList(ptxs) + + puncles := make([]*JSBlock, len(block.Uncles)) + for i, uncle := range block.Uncles { + puncles[i] = NewJSBlock(uncle) + } + ulist := ethutil.NewList(puncles) + + return &JSBlock{ + ref: block, Size: block.Size().String(), + Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(), + GasLimit: block.GasLimit.String(), Hash: ethutil.Bytes2Hex(block.Hash()), + Transactions: txlist, Uncles: ulist, + Time: block.Time, + Coinbase: ethutil.Bytes2Hex(block.Coinbase), + PrevHash: ethutil.Bytes2Hex(block.PrevHash), + } +} + +func (self *JSBlock) ToString() string { + if self.ref != nil { + return self.ref.String() + } + + return "" +} + +func (self *JSBlock) GetTransaction(hash string) *JSTransaction { + tx := self.ref.GetTransaction(ethutil.Hex2Bytes(hash)) + if tx == nil { + return nil + } + + return NewJSTx(tx, self.ref.State()) +} + +type JSTransaction struct { + ref *chain.Transaction + + Value string `json:"value"` + Gas string `json:"gas"` + GasPrice string `json:"gasPrice"` + Hash string `json:"hash"` + Address string `json:"address"` + Sender string `json:"sender"` + RawData string `json:"rawData"` + Data string `json:"data"` + Contract bool `json:"isContract"` + CreatesContract bool `json:"createsContract"` + Confirmations int `json:"confirmations"` +} + +func NewJSTx(tx *chain.Transaction, state *ethstate.State) *JSTransaction { + hash := ethutil.Bytes2Hex(tx.Hash()) + receiver := ethutil.Bytes2Hex(tx.Recipient) + if receiver == "0000000000000000000000000000000000000000" { + receiver = ethutil.Bytes2Hex(tx.CreationAddress(state)) + } + sender := ethutil.Bytes2Hex(tx.Sender()) + createsContract := tx.CreatesContract() + + var data string + if tx.CreatesContract() { + data = strings.Join(chain.Disassemble(tx.Data), "\n") + } else { + data = ethutil.Bytes2Hex(tx.Data) + } + + return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: receiver, Contract: tx.CreatesContract(), Gas: tx.Gas.String(), GasPrice: tx.GasPrice.String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data)} +} + +func (self *JSTransaction) ToString() string { + return self.ref.String() +} + +type JSKey struct { + Address string `json:"address"` + PrivateKey string `json:"privateKey"` + PublicKey string `json:"publicKey"` +} + +func NewJSKey(key *crypto.KeyPair) *JSKey { + return &JSKey{ethutil.Bytes2Hex(key.Address()), ethutil.Bytes2Hex(key.PrivateKey), ethutil.Bytes2Hex(key.PublicKey)} +} + +type JSObject struct { + *Object +} + +func NewJSObject(object *Object) *JSObject { + return &JSObject{object} +} + +type PReceipt struct { + CreatedContract bool `json:"createdContract"` + Address string `json:"address"` + Hash string `json:"hash"` + Sender string `json:"sender"` +} + +func NewPReciept(contractCreation bool, creationAddress, hash, address []byte) *PReceipt { + return &PReceipt{ + contractCreation, + ethutil.Bytes2Hex(creationAddress), + ethutil.Bytes2Hex(hash), + ethutil.Bytes2Hex(address), + } +} + +// Peer interface exposed to QML + +type JSPeer struct { + ref *chain.Peer + Inbound bool `json:"isInbound"` + LastSend int64 `json:"lastSend"` + LastPong int64 `json:"lastPong"` + Ip string `json:"ip"` + Port int `json:"port"` + Version string `json:"version"` + LastResponse string `json:"lastResponse"` + Latency string `json:"latency"` + Caps string `json:"caps"` +} + +func NewJSPeer(peer chain.Peer) *JSPeer { + if peer == nil { + return nil + } + + var ip []string + for _, i := range peer.Host() { + ip = append(ip, strconv.Itoa(int(i))) + } + ipAddress := strings.Join(ip, ".") + + var caps []string + capsIt := peer.Caps().NewIterator() + for capsIt.Next() { + caps = append(caps, capsIt.Value().Str()) + } + + return &JSPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port()), Latency: peer.PingTime(), Caps: fmt.Sprintf("%v", caps)} +} + +type JSReceipt struct { + CreatedContract bool `json:"createdContract"` + Address string `json:"address"` + Hash string `json:"hash"` + Sender string `json:"sender"` +} + +func NewJSReciept(contractCreation bool, creationAddress, hash, address []byte) *JSReceipt { + return &JSReceipt{ + contractCreation, + ethutil.Bytes2Hex(creationAddress), + ethutil.Bytes2Hex(hash), + ethutil.Bytes2Hex(address), + } +} + +type JSMessage struct { + To string `json:"to"` + From string `json:"from"` + Input string `json:"input"` + Output string `json:"output"` + Path int32 `json:"path"` + Origin string `json:"origin"` + Timestamp int32 `json:"timestamp"` + Coinbase string `json:"coinbase"` + Block string `json:"block"` + Number int32 `json:"number"` + Value string `json:"value"` +} + +func NewJSMessage(message *ethstate.Message) JSMessage { + return JSMessage{ + To: ethutil.Bytes2Hex(message.To), + From: ethutil.Bytes2Hex(message.From), + Input: ethutil.Bytes2Hex(message.Input), + Output: ethutil.Bytes2Hex(message.Output), + Path: int32(message.Path), + Origin: ethutil.Bytes2Hex(message.Origin), + Timestamp: int32(message.Timestamp), + Coinbase: ethutil.Bytes2Hex(message.Origin), + Block: ethutil.Bytes2Hex(message.Block), + Number: int32(message.Number.Int64()), + Value: message.Value.String(), + } +} diff --git a/xeth/object.go b/xeth/object.go new file mode 100644 index 000000000..fe4e84a4a --- /dev/null +++ b/xeth/object.go @@ -0,0 +1,26 @@ +package xeth + +import ( + "github.com/ethereum/go-ethereum/ethstate" + "github.com/ethereum/go-ethereum/ethutil" +) + +type Object struct { + *ethstate.StateObject +} + +func (self *Object) StorageString(str string) *ethutil.Value { + if ethutil.IsHex(str) { + return self.Storage(ethutil.Hex2Bytes(str[2:])) + } else { + return self.Storage(ethutil.RightPadBytes([]byte(str), 32)) + } +} + +func (self *Object) StorageValue(addr *ethutil.Value) *ethutil.Value { + return self.Storage(addr.Bytes()) +} + +func (self *Object) Storage(addr []byte) *ethutil.Value { + return self.StateObject.GetStorage(ethutil.BigD(addr)) +} diff --git a/xeth/pipe.go b/xeth/pipe.go new file mode 100644 index 000000000..f2759d660 --- /dev/null +++ b/xeth/pipe.go @@ -0,0 +1,175 @@ +package xeth + +/* + * eXtended ETHereum + */ + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/chain" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethstate" + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/vm" +) + +var pipelogger = logger.NewLogger("XETH") + +type VmVars struct { + State *ethstate.State +} + +type XEth struct { + obj chain.EthManager + stateManager *chain.StateManager + blockChain *chain.ChainManager + world *World + + Vm VmVars +} + +func New(obj chain.EthManager) *XEth { + pipe := &XEth{ + obj: obj, + stateManager: obj.StateManager(), + blockChain: obj.ChainManager(), + } + pipe.world = NewWorld(pipe) + + return pipe +} + +func (self *XEth) Balance(addr []byte) *ethutil.Value { + return ethutil.NewValue(self.World().safeGet(addr).Balance) +} + +func (self *XEth) Nonce(addr []byte) uint64 { + return self.World().safeGet(addr).Nonce +} + +func (self *XEth) Execute(addr []byte, data []byte, value, gas, price *ethutil.Value) ([]byte, error) { + return self.ExecuteObject(&Object{self.World().safeGet(addr)}, data, value, gas, price) +} + +func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) { + var ( + initiator = ethstate.NewStateObject(self.obj.KeyManager().KeyPair().Address()) + block = self.blockChain.CurrentBlock + ) + + self.Vm.State = self.World().State().Copy() + + evm := vm.New(NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address()), vm.Type(ethutil.Config.VmType)) + + msg := vm.NewExecution(evm, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt()) + ret, err := msg.Exec(object.Address(), initiator) + + fmt.Println("returned from call", ret, err) + + return ret, err +} + +func (self *XEth) Block(hash []byte) *chain.Block { + return self.blockChain.GetBlock(hash) +} + +func (self *XEth) Storage(addr, storageAddr []byte) *ethutil.Value { + return self.World().safeGet(addr).GetStorage(ethutil.BigD(storageAddr)) +} + +func (self *XEth) ToAddress(priv []byte) []byte { + pair, err := crypto.NewKeyPairFromSec(priv) + if err != nil { + return nil + } + + return pair.Address() +} + +func (self *XEth) Exists(addr []byte) bool { + return self.World().Get(addr) != nil +} + +func (self *XEth) TransactString(key *crypto.KeyPair, rec string, value, gas, price *ethutil.Value, data []byte) ([]byte, error) { + // Check if an address is stored by this address + var hash []byte + addr := self.World().Config().Get("NameReg").StorageString(rec).Bytes() + if len(addr) > 0 { + hash = addr + } else if ethutil.IsHex(rec) { + hash = ethutil.Hex2Bytes(rec[2:]) + } else { + hash = ethutil.Hex2Bytes(rec) + } + + return self.Transact(key, hash, value, gas, price, data) +} + +func (self *XEth) Transact(key *crypto.KeyPair, rec []byte, value, gas, price *ethutil.Value, data []byte) ([]byte, error) { + var hash []byte + var contractCreation bool + if rec == nil { + contractCreation = true + } + + var tx *chain.Transaction + // Compile and assemble the given data + if contractCreation { + script, err := ethutil.Compile(string(data), false) + if err != nil { + return nil, err + } + + tx = chain.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), script) + } else { + data := ethutil.StringToByteFunc(string(data), func(s string) (ret []byte) { + slice := strings.Split(s, "\n") + for _, dataItem := range slice { + d := ethutil.FormatData(dataItem) + ret = append(ret, d...) + } + return + }) + + tx = chain.NewTransactionMessage(hash, value.BigInt(), gas.BigInt(), price.BigInt(), data) + } + + acc := self.stateManager.TransState().GetOrNewStateObject(key.Address()) + tx.Nonce = acc.Nonce + acc.Nonce += 1 + self.stateManager.TransState().UpdateStateObject(acc) + + tx.Sign(key.PrivateKey) + self.obj.TxPool().QueueTransaction(tx) + + if contractCreation { + addr := tx.CreationAddress(self.World().State()) + pipelogger.Infof("Contract addr %x\n", addr) + + return addr, nil + } + + return tx.Hash(), nil +} + +func (self *XEth) PushTx(tx *chain.Transaction) ([]byte, error) { + self.obj.TxPool().QueueTransaction(tx) + if tx.Recipient == nil { + addr := tx.CreationAddress(self.World().State()) + pipelogger.Infof("Contract addr %x\n", addr) + return addr, nil + } + return tx.Hash(), nil +} + +func (self *XEth) CompileMutan(code string) ([]byte, error) { + data, err := ethutil.Compile(code, false) + if err != nil { + return nil, err + } + + return data, nil +} diff --git a/xeth/vm_env.go b/xeth/vm_env.go new file mode 100644 index 000000000..952101f68 --- /dev/null +++ b/xeth/vm_env.go @@ -0,0 +1,40 @@ +package xeth + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/chain" + "github.com/ethereum/go-ethereum/ethstate" + "github.com/ethereum/go-ethereum/vm" +) + +type VMEnv struct { + state *ethstate.State + block *chain.Block + value *big.Int + sender []byte +} + +func NewEnv(state *ethstate.State, block *chain.Block, value *big.Int, sender []byte) *VMEnv { + return &VMEnv{ + state: state, + block: block, + value: value, + sender: sender, + } +} + +func (self *VMEnv) Origin() []byte { return self.sender } +func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number } +func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash } +func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase } +func (self *VMEnv) Time() int64 { return self.block.Time } +func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty } +func (self *VMEnv) BlockHash() []byte { return self.block.Hash() } +func (self *VMEnv) Value() *big.Int { return self.value } +func (self *VMEnv) State() *ethstate.State { return self.state } +func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit } +func (self *VMEnv) AddLog(ethstate.Log) {} +func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { + return vm.Transfer(from, to, amount) +} diff --git a/xeth/world.go b/xeth/world.go new file mode 100644 index 000000000..daeb59e1c --- /dev/null +++ b/xeth/world.go @@ -0,0 +1,64 @@ +package xeth + +import ( + "container/list" + + "github.com/ethereum/go-ethereum/ethstate" +) + +type World struct { + pipe *XEth + cfg *Config +} + +func NewWorld(pipe *XEth) *World { + world := &World{pipe, nil} + world.cfg = &Config{pipe} + + return world +} + +func (self *XEth) World() *World { + return self.world +} + +func (self *World) State() *ethstate.State { + return self.pipe.stateManager.CurrentState() +} + +func (self *World) Get(addr []byte) *Object { + return &Object{self.State().GetStateObject(addr)} +} + +func (self *World) SafeGet(addr []byte) *Object { + return &Object{self.safeGet(addr)} +} + +func (self *World) safeGet(addr []byte) *ethstate.StateObject { + object := self.State().GetStateObject(addr) + if object == nil { + object = ethstate.NewStateObject(addr) + } + + return object +} + +func (self *World) Coinbase() *ethstate.StateObject { + return nil +} + +func (self *World) IsMining() bool { + return self.pipe.obj.IsMining() +} + +func (self *World) IsListening() bool { + return self.pipe.obj.IsListening() +} + +func (self *World) Peers() *list.List { + return self.pipe.obj.Peers() +} + +func (self *World) Config() *Config { + return self.cfg +} -- cgit v1.2.3