Merge branch 'jsonrpc' into qt5.4

This commit is contained in:
obscuren 2015-01-28 18:36:41 +01:00
commit 1c51e12c18
17 changed files with 299 additions and 348 deletions

@ -44,7 +44,7 @@ type AppContainer interface {
}
type ExtApplication struct {
*xeth.JSXEth
*xeth.XEth
eth core.EthManager
events event.Subscription
@ -58,7 +58,7 @@ type ExtApplication struct {
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
return &ExtApplication{
JSXEth: xeth.NewJSXEth(lib.eth),
XEth: xeth.New(lib.eth),
eth: lib.eth,
watcherQuitChan: make(chan bool),
filters: make(map[string]*core.Filter),

@ -75,7 +75,7 @@ type Gui struct {
logLevel logger.LogLevel
open bool
xeth *xeth.JSXEth
xeth *xeth.XEth
Session string
clientIdentity *p2p.SimpleClientIdentity
@ -93,7 +93,7 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden
panic(err)
}
xeth := xeth.NewJSXEth(ethereum)
xeth := xeth.New(ethereum)
gui := &Gui{eth: ethereum,
txDb: db,
xeth: xeth,
@ -120,9 +120,9 @@ func (gui *Gui) Start(assetPath string) {
// Register ethereum functions
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
Init: func(p *xeth.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
Init: func(p *xeth.Block, obj qml.Object) { p.Number = 0; p.Hash = "" },
}, {
Init: func(p *xeth.JSTransaction, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
Init: func(p *xeth.Transaction, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
}, {
Init: func(p *xeth.KeyVal, obj qml.Object) { p.Key = ""; p.Value = "" },
}})
@ -276,7 +276,7 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
}
var (
ptx = xeth.NewJSTx(tx)
ptx = xeth.NewTx(tx)
send = ethutil.Bytes2Hex(tx.From())
rec = ethutil.Bytes2Hex(tx.To())
)
@ -303,7 +303,7 @@ func (gui *Gui) readPreviousTransactions() {
func (gui *Gui) processBlock(block *types.Block, initial bool) {
name := ethutil.Bytes2Hex(block.Coinbase())
b := xeth.NewJSBlock(block)
b := xeth.NewBlock(block)
b.Name = name
gui.getObjectByName("chainView").Call("addBlock", b, initial)

@ -140,7 +140,7 @@ func (app *HtmlApplication) Window() *qml.Window {
}
func (app *HtmlApplication) NewBlock(block *types.Block) {
b := &xeth.JSBlock{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())}
b := &xeth.Block{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())}
app.webView.Call("onNewBlockCb", b)
}

@ -70,7 +70,7 @@ func (app *QmlApplication) NewWatcher(quitChan chan bool) {
// Events
func (app *QmlApplication) NewBlock(block *types.Block) {
pblock := &xeth.JSBlock{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())}
pblock := &xeth.Block{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())}
app.win.Call("onNewBlockCb", pblock)
}

@ -42,7 +42,7 @@ type memAddr struct {
// UI Library that has some basic functionality exposed
type UiLib struct {
*xeth.JSXEth
*xeth.XEth
engine *qml.Engine
eth *eth.Ethereum
connected bool
@ -61,7 +61,7 @@ type UiLib struct {
}
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
lib := &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)}
lib := &UiLib{XEth: xeth.New(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)}
lib.miner = miner.New(eth.KeyManager().Address(), eth)
lib.filterManager = filter.NewFilterManager(eth.EventMux())
go lib.filterManager.Start()
@ -178,7 +178,7 @@ func (self *UiLib) StartDebugger() {
func (self *UiLib) Transact(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Transact(
return self.XEth.Transact(
object["from"],
object["to"],
object["value"],
@ -200,7 +200,7 @@ func (self *UiLib) Compile(code string) (string, error) {
func (self *UiLib) Call(params map[string]interface{}) (string, error) {
object := mapToTxParams(params)
return self.JSXEth.Execute(
return self.XEth.Execute(
object["to"],
object["value"],
object["gas"],
@ -260,7 +260,7 @@ func (self *UiLib) NewFilter(object map[string]interface{}, view *qml.Common) (i
/* TODO remove me
filter := qt.NewFilterFromMap(object, self.eth)
filter.MessageCallback = func(messages state.Messages) {
view.Call("messages", xeth.ToJSMessages(messages), id)
view.Call("messages", xeth.ToMessages(messages), id)
}
id = self.filterManager.InstallFilter(filter)
return id
@ -284,7 +284,7 @@ func (self *UiLib) Messages(id int) *ethutil.List {
/* TODO remove me
filter := self.filterManager.GetFilter(id)
if filter != nil {
messages := xeth.ToJSMessages(filter.Find())
messages := xeth.ToMessages(filter.Find())
return messages
}

@ -194,7 +194,7 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre
func StartRpc(ethereum *eth.Ethereum, RpcPort int) {
var err error
ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.NewJSXEth(ethereum), RpcPort)
ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcPort)
if err != nil {
clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err)
} else {

@ -24,7 +24,7 @@ var jsrelogger = logger.NewLogger("JSRE")
type JSRE struct {
ethereum *eth.Ethereum
Vm *otto.Otto
pipe *xeth.JSXEth
pipe *xeth.XEth
events event.Subscription
@ -49,7 +49,7 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
re := &JSRE{
ethereum,
otto.New(),
xeth.NewJSXEth(ethereum),
xeth.New(ethereum),
nil,
make(map[string][]otto.Value),
}

@ -12,14 +12,14 @@ import (
)
type JSStateObject struct {
*xeth.JSObject
*xeth.Object
eth *JSEthereum
}
func (self *JSStateObject) EachStorage(call otto.FunctionCall) otto.Value {
cb := call.Argument(0)
it := self.JSObject.Trie().Iterator()
it := self.Object.Trie().Iterator()
for it.Next() {
cb.Call(self.eth.toVal(self), self.eth.toVal(ethutil.Bytes2Hex(it.Key)), self.eth.toVal(ethutil.Bytes2Hex(it.Value)))
}
@ -30,12 +30,12 @@ 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 {
*xeth.JSBlock
*xeth.Block
eth *JSEthereum
}
func (self *JSBlock) GetTransaction(hash string) otto.Value {
return self.eth.toVal(self.JSBlock.GetTransaction(hash))
return self.eth.toVal(self.Block.GetTransaction(hash))
}
type JSLog struct {
@ -55,27 +55,27 @@ func NewJSLog(log state.Log) JSLog {
}
type JSEthereum struct {
*xeth.JSXEth
*xeth.XEth
vm *otto.Otto
ethereum *eth.Ethereum
}
func (self *JSEthereum) Block(v interface{}) otto.Value {
if number, ok := v.(int64); ok {
return self.toVal(&JSBlock{self.JSXEth.BlockByNumber(int32(number)), self})
return self.toVal(&JSBlock{self.XEth.BlockByNumber(int32(number)), self})
} else if hash, ok := v.(string); ok {
return self.toVal(&JSBlock{self.JSXEth.BlockByHash(hash), self})
return self.toVal(&JSBlock{self.XEth.BlockByHash(hash), self})
}
return otto.UndefinedValue()
}
func (self *JSEthereum) GetStateObject(addr string) otto.Value {
return self.toVal(&JSStateObject{xeth.NewJSObject(self.JSXEth.State().SafeGet(addr)), self})
return self.toVal(&JSStateObject{self.XEth.State().SafeGet(addr), self})
}
func (self *JSEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) otto.Value {
r, err := self.JSXEth.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
r, err := self.XEth.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
if err != nil {
fmt.Println(err)

@ -29,7 +29,7 @@ import (
var rpchttplogger = logger.NewLogger("RPC-HTTP")
var JSON rpc.JsonWrapper
func NewRpcHttpServer(pipe *xeth.JSXEth, port int) (*RpcHttpServer, error) {
func NewRpcHttpServer(pipe *xeth.XEth, port int) (*RpcHttpServer, error) {
sport := fmt.Sprintf(":%d", port)
l, err := net.Listen("tcp", sport)
if err != nil {
@ -47,7 +47,7 @@ func NewRpcHttpServer(pipe *xeth.JSXEth, port int) (*RpcHttpServer, error) {
type RpcHttpServer struct {
quit chan bool
listener net.Listener
pipe *xeth.JSXEth
pipe *xeth.XEth
port int
}

@ -19,8 +19,8 @@
For each request type, define the following:
1. RpcRequest "To" method [message.go], which does basic validation and conversion to "Args" type via json.Decoder()
2. json.Decoder() calls "UnmarshalJSON" defined on each "Args" struct
3. EthereumApi method, taking the "Args" type and replying with an interface to be marshalled to JSON
2. json.Decoder() calls "UnmarshalON" defined on each "Args" struct
3. EthereumApi method, taking the "Args" type and replying with an interface to be marshalled to ON
*/
package rpc
@ -38,12 +38,12 @@ type RpcServer interface {
Stop()
}
func NewEthereumApi(xeth *xeth.JSXEth) *EthereumApi {
func NewEthereumApi(xeth *xeth.XEth) *EthereumApi {
return &EthereumApi{xeth: xeth}
}
type EthereumApi struct {
xeth *xeth.JSXEth
xeth *xeth.XEth
}
func (p *EthereumApi) GetBlock(args *GetBlockArgs, reply *interface{}) error {
@ -162,7 +162,7 @@ func (p *EthereumApi) GetCodeAt(args *GetCodeAtArgs, reply *interface{}) error {
}
func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
// Spec at https://github.com/ethereum/wiki/wiki/Generic-ON-RPC
rpclogger.DebugDetailf("%T %s", req.Params, req.Params)
switch req.Method {
case "eth_coinbase":

@ -75,7 +75,7 @@ func (self *WebSocketServer) Start() {
wslogger.Infof("Starting RPC-WS server on port %d", self.port)
go self.handlerLoop()
api := rpc.NewEthereumApi(xeth.NewJSXEth(self.eth))
api := rpc.NewEthereumApi(xeth.New(self.eth))
h := self.apiHandler(api)
http.Handle("/ws", h)

@ -1,37 +0,0 @@
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)}
case "MergeMining":
addr = []byte{4}
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
}
*/

@ -1,211 +0,0 @@
package xeth
import (
"bytes"
"encoding/json"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
)
// to resolve the import cycle
type Backend interface {
BlockProcessor() *core.BlockProcessor
ChainManager() *core.ChainManager
Coinbase() []byte
KeyManager() *crypto.KeyManager
IsMining() bool
IsListening() bool
PeerCount() int
Db() ethutil.Database
TxPool() *core.TxPool
}
type JSXEth struct {
eth Backend
blockProcessor *core.BlockProcessor
chainManager *core.ChainManager
world *State
}
func NewJSXEth(eth Backend) *JSXEth {
xeth := &JSXEth{
eth: eth,
blockProcessor: eth.BlockProcessor(),
chainManager: eth.ChainManager(),
}
xeth.world = NewState(xeth)
return xeth
}
func (self *JSXEth) State() *State { return self.world }
func (self *JSXEth) BlockByHash(strHash string) *JSBlock {
hash := fromHex(strHash)
block := self.chainManager.GetBlock(hash)
return NewJSBlock(block)
}
func (self *JSXEth) BlockByNumber(num int32) *JSBlock {
if num == -1 {
return NewJSBlock(self.chainManager.CurrentBlock())
}
return NewJSBlock(self.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) Accounts() []string {
return []string{toHex(self.eth.KeyManager().Address())}
}
/*
func (self *JSXEth) StateObject(addr string) *JSObject {
object := &Object{self.State().safeGet(fromHex(addr))}
return NewJSObject(object)
}
*/
func (self *JSXEth) PeerCount() int {
return self.eth.PeerCount()
}
func (self *JSXEth) IsMining() bool {
return self.eth.IsMining()
}
func (self *JSXEth) IsListening() bool {
return self.eth.IsListening()
}
func (self *JSXEth) Coinbase() string {
return toHex(self.eth.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.State().SafeGet(addr).StorageString(storageAddr)
return toHex(storage.Bytes())
}
func (self *JSXEth) BalanceAt(addr string) string {
return self.State().SafeGet(addr).Balance().String()
}
func (self *JSXEth) TxCountAt(address string) int {
return int(self.State().SafeGet(address).Nonce)
}
func (self *JSXEth) CodeAt(address string) string {
return toHex(self.State().SafeGet(address).Code)
}
func (self *JSXEth) IsContract(address string) bool {
return len(self.State().SafeGet(address).Code) > 0
}
func (self *JSXEth) SecretToAddress(key string) string {
pair, err := crypto.NewKeyPairFromSec(fromHex(key))
if err != nil {
return ""
}
return toHex(pair.Address())
}
func (self *JSXEth) Execute(addr, value, gas, price, data string) (string, error) {
return "", nil
}
type KeyVal struct {
Key string `json:"key"`
Value string `json:"value"`
}
func (self *JSXEth) EachStorage(addr string) string {
var values []KeyVal
object := self.State().SafeGet(addr)
it := object.Trie().Iterator()
for it.Next() {
values = append(values, KeyVal{toHex(it.Key), toHex(it.Value)})
}
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" + toHex(padded)
}
func (self *JSXEth) FromAscii(str string) string {
if ethutil.IsHex(str) {
str = str[2:]
}
return string(bytes.Trim(fromHex(str), "\x00"))
}
func (self *JSXEth) FromNumber(str string) string {
if ethutil.IsHex(str) {
str = str[2:]
}
return ethutil.BigD(fromHex(str)).String()
}
func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
return "", nil
}
func ToJSMessages(messages state.Messages) *ethutil.List {
var msgs []JSMessage
for _, m := range messages {
msgs = append(msgs, NewJSMessage(m))
}
return ethutil.NewList(msgs)
}
func (self *JSXEth) PushTx(encodedTx string) (string, error) {
tx := types.NewTransactionFromBytes(fromHex(encodedTx))
err := self.eth.TxPool().Add(tx)
if err != nil {
return "", err
}
if tx.To() == nil {
addr := core.AddressFromMessage(tx)
return toHex(addr), nil
}
return toHex(tx.Hash()), nil
}

@ -1,26 +0,0 @@
package xeth
import (
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
)
type Object struct {
*state.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))
}

@ -25,8 +25,32 @@ func fromHex(s string) []byte {
return nil
}
type Object struct {
*state.StateObject
}
func NewObject(state *state.StateObject) *Object {
return &Object{state}
}
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))
}
// Block interface exposed to QML
type JSBlock struct {
type Block struct {
//Transactions string `json:"transactions"`
ref *types.Block
Size string `json:"size"`
@ -45,24 +69,24 @@ type JSBlock struct {
}
// Creates a new QML Block from a chain block
func NewJSBlock(block *types.Block) *JSBlock {
func NewBlock(block *types.Block) *Block {
if block == nil {
return &JSBlock{}
return &Block{}
}
ptxs := make([]*JSTransaction, len(block.Transactions()))
ptxs := make([]*Transaction, len(block.Transactions()))
for i, tx := range block.Transactions() {
ptxs[i] = NewJSTx(tx)
ptxs[i] = NewTx(tx)
}
txlist := ethutil.NewList(ptxs)
puncles := make([]*JSBlock, len(block.Uncles()))
puncles := make([]*Block, len(block.Uncles()))
for i, uncle := range block.Uncles() {
puncles[i] = NewJSBlock(types.NewBlockWithHeader(uncle))
puncles[i] = NewBlock(types.NewBlockWithHeader(uncle))
}
ulist := ethutil.NewList(puncles)
return &JSBlock{
return &Block{
ref: block, Size: block.Size().String(),
Number: int(block.NumberU64()), GasUsed: block.GasUsed().String(),
GasLimit: block.GasLimit().String(), Hash: toHex(block.Hash()),
@ -75,7 +99,7 @@ func NewJSBlock(block *types.Block) *JSBlock {
}
}
func (self *JSBlock) ToString() string {
func (self *Block) ToString() string {
if self.ref != nil {
return self.ref.String()
}
@ -83,16 +107,16 @@ func (self *JSBlock) ToString() string {
return ""
}
func (self *JSBlock) GetTransaction(hash string) *JSTransaction {
func (self *Block) GetTransaction(hash string) *Transaction {
tx := self.ref.Transaction(fromHex(hash))
if tx == nil {
return nil
}
return NewJSTx(tx)
return NewTx(tx)
}
type JSTransaction struct {
type Transaction struct {
ref *types.Transaction
Value string `json:"value"`
@ -108,7 +132,7 @@ type JSTransaction struct {
Confirmations int `json:"confirmations"`
}
func NewJSTx(tx *types.Transaction) *JSTransaction {
func NewTx(tx *types.Transaction) *Transaction {
hash := toHex(tx.Hash())
receiver := toHex(tx.To())
if receiver == "0000000000000000000000000000000000000000" {
@ -124,29 +148,21 @@ func NewJSTx(tx *types.Transaction) *JSTransaction {
data = toHex(tx.Data())
}
return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value()), Address: receiver, Contract: createsContract, Gas: tx.Gas().String(), GasPrice: tx.GasPrice().String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: toHex(tx.Data())}
return &Transaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value()), Address: receiver, Contract: createsContract, Gas: tx.Gas().String(), GasPrice: tx.GasPrice().String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: toHex(tx.Data())}
}
func (self *JSTransaction) ToString() string {
func (self *Transaction) ToString() string {
return self.ref.String()
}
type JSKey struct {
type Key struct {
Address string `json:"address"`
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
}
func NewJSKey(key *crypto.KeyPair) *JSKey {
return &JSKey{toHex(key.Address()), toHex(key.PrivateKey), toHex(key.PublicKey)}
}
type JSObject struct {
*Object
}
func NewJSObject(object *Object) *JSObject {
return &JSObject{object}
func NewKey(key *crypto.KeyPair) *Key {
return &Key{toHex(key.Address()), toHex(key.PrivateKey), toHex(key.PublicKey)}
}
type PReceipt struct {
@ -167,20 +183,20 @@ func NewPReciept(contractCreation bool, creationAddress, hash, address []byte) *
// Peer interface exposed to QML
type JSPeer struct {
type Peer struct {
ref *p2p.Peer
Ip string `json:"ip"`
Version string `json:"version"`
Caps string `json:"caps"`
}
func NewJSPeer(peer *p2p.Peer) *JSPeer {
func NewPeer(peer *p2p.Peer) *Peer {
var caps []string
for _, cap := range peer.Caps() {
caps = append(caps, fmt.Sprintf("%s/%d", cap.Name, cap.Version))
}
return &JSPeer{
return &Peer{
ref: peer,
Ip: fmt.Sprintf("%v", peer.RemoteAddr()),
Version: fmt.Sprintf("%v", peer.Identity()),
@ -188,15 +204,15 @@ func NewJSPeer(peer *p2p.Peer) *JSPeer {
}
}
type JSReceipt struct {
type Receipt 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{
func NewReciept(contractCreation bool, creationAddress, hash, address []byte) *Receipt {
return &Receipt{
contractCreation,
toHex(creationAddress),
toHex(hash),
@ -204,7 +220,7 @@ func NewJSReciept(contractCreation bool, creationAddress, hash, address []byte)
}
}
type JSMessage struct {
type Message struct {
To string `json:"to"`
From string `json:"from"`
Input string `json:"input"`
@ -218,8 +234,8 @@ type JSMessage struct {
Value string `json:"value"`
}
func NewJSMessage(message *state.Message) JSMessage {
return JSMessage{
func NewMessage(message *state.Message) Message {
return Message{
To: toHex(message.To),
From: toHex(message.From),
Input: toHex(message.Input),

@ -3,10 +3,10 @@ package xeth
import "github.com/ethereum/go-ethereum/state"
type State struct {
xeth *JSXEth
xeth *XEth
}
func NewState(xeth *JSXEth) *State {
func NewState(xeth *XEth) *State {
return &State{xeth}
}

@ -4,6 +4,215 @@ package xeth
* eXtended ETHereum
*/
import "github.com/ethereum/go-ethereum/logger"
import (
"bytes"
"encoding/json"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
)
var pipelogger = logger.NewLogger("XETH")
// to resolve the import cycle
type Backend interface {
BlockProcessor() *core.BlockProcessor
ChainManager() *core.ChainManager
Coinbase() []byte
KeyManager() *crypto.KeyManager
IsMining() bool
IsListening() bool
PeerCount() int
Db() ethutil.Database
TxPool() *core.TxPool
}
type XEth struct {
eth Backend
blockProcessor *core.BlockProcessor
chainManager *core.ChainManager
world *State
}
func New(eth Backend) *XEth {
xeth := &XEth{
eth: eth,
blockProcessor: eth.BlockProcessor(),
chainManager: eth.ChainManager(),
}
xeth.world = NewState(xeth)
return xeth
}
func (self *XEth) State() *State { return self.world }
func (self *XEth) BlockByHash(strHash string) *Block {
hash := fromHex(strHash)
block := self.chainManager.GetBlock(hash)
return NewBlock(block)
}
func (self *XEth) BlockByNumber(num int32) *Block {
if num == -1 {
return NewBlock(self.chainManager.CurrentBlock())
}
return NewBlock(self.chainManager.GetBlockByNumber(uint64(num)))
}
func (self *XEth) Block(v interface{}) *Block {
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 *XEth) Accounts() []string {
return []string{toHex(self.eth.KeyManager().Address())}
}
/*
func (self *XEth) StateObject(addr string) *Object {
object := &Object{self.State().safeGet(fromHex(addr))}
return NewObject(object)
}
*/
func (self *XEth) PeerCount() int {
return self.eth.PeerCount()
}
func (self *XEth) IsMining() bool {
return self.eth.IsMining()
}
func (self *XEth) IsListening() bool {
return self.eth.IsListening()
}
func (self *XEth) Coinbase() string {
return toHex(self.eth.KeyManager().Address())
}
func (self *XEth) NumberToHuman(balance string) string {
b := ethutil.Big(balance)
return ethutil.CurrencyToString(b)
}
func (self *XEth) StorageAt(addr, storageAddr string) string {
storage := self.State().SafeGet(addr).StorageString(storageAddr)
return toHex(storage.Bytes())
}
func (self *XEth) BalanceAt(addr string) string {
return self.State().SafeGet(addr).Balance().String()
}
func (self *XEth) TxCountAt(address string) int {
return int(self.State().SafeGet(address).Nonce)
}
func (self *XEth) CodeAt(address string) string {
return toHex(self.State().SafeGet(address).Code)
}
func (self *XEth) IsContract(address string) bool {
return len(self.State().SafeGet(address).Code) > 0
}
func (self *XEth) SecretToAddress(key string) string {
pair, err := crypto.NewKeyPairFromSec(fromHex(key))
if err != nil {
return ""
}
return toHex(pair.Address())
}
func (self *XEth) Execute(addr, value, gas, price, data string) (string, error) {
return "", nil
}
type KeyVal struct {
Key string `json:"key"`
Value string `json:"value"`
}
func (self *XEth) EachStorage(addr string) string {
var values []KeyVal
object := self.State().SafeGet(addr)
it := object.Trie().Iterator()
for it.Next() {
values = append(values, KeyVal{toHex(it.Key), toHex(it.Value)})
}
valuesJson, err := json.Marshal(values)
if err != nil {
return ""
}
return string(valuesJson)
}
func (self *XEth) ToAscii(str string) string {
padded := ethutil.RightPadBytes([]byte(str), 32)
return "0x" + toHex(padded)
}
func (self *XEth) FromAscii(str string) string {
if ethutil.IsHex(str) {
str = str[2:]
}
return string(bytes.Trim(fromHex(str), "\x00"))
}
func (self *XEth) FromNumber(str string) string {
if ethutil.IsHex(str) {
str = str[2:]
}
return ethutil.BigD(fromHex(str)).String()
}
func (self *XEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
return "", nil
}
func ToMessages(messages state.Messages) *ethutil.List {
var msgs []Message
for _, m := range messages {
msgs = append(msgs, NewMessage(m))
}
return ethutil.NewList(msgs)
}
func (self *XEth) PushTx(encodedTx string) (string, error) {
tx := types.NewTransactionFromBytes(fromHex(encodedTx))
err := self.eth.TxPool().Add(tx)
if err != nil {
return "", err
}
if tx.To() == nil {
addr := core.AddressFromMessage(tx)
return toHex(addr), nil
}
return toHex(tx.Hash()), nil
}