mirror of https://github.com/ethereum/go-ethereum
parent
7d95e8624a
commit
4bd6003b7f
@ -1,296 +0,0 @@ |
||||
package ethpub |
||||
|
||||
import ( |
||||
"bytes" |
||||
"encoding/json" |
||||
"math/big" |
||||
"strconv" |
||||
"strings" |
||||
"sync/atomic" |
||||
|
||||
"github.com/ethereum/eth-go/ethchain" |
||||
"github.com/ethereum/eth-go/ethcrypto" |
||||
"github.com/ethereum/eth-go/ethlog" |
||||
"github.com/ethereum/eth-go/ethpipe" |
||||
"github.com/ethereum/eth-go/ethstate" |
||||
"github.com/ethereum/eth-go/ethutil" |
||||
) |
||||
|
||||
var logger = ethlog.NewLogger("PUB") |
||||
|
||||
// TODO this has to move elsewhere
|
||||
var cnfCtr = ethutil.Hex2Bytes("661005d2720d855f1d9976f88bb10c1a3398c77f") |
||||
|
||||
type helper struct { |
||||
sm *ethchain.StateManager |
||||
} |
||||
|
||||
func EthereumConfig(stateManager *ethchain.StateManager) helper { |
||||
return helper{stateManager} |
||||
} |
||||
func (self helper) obj() *ethstate.StateObject { |
||||
return self.sm.CurrentState().GetStateObject(cnfCtr) |
||||
} |
||||
|
||||
func (self helper) NameReg() *ethstate.StateObject { |
||||
if self.obj() != nil { |
||||
addr := self.obj().GetStorage(big.NewInt(0)) |
||||
if len(addr.Bytes()) > 0 { |
||||
return self.sm.CurrentState().GetStateObject(addr.Bytes()) |
||||
} |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
// TODO Re-write / refactor
|
||||
type PEthereum struct { |
||||
manager ethchain.EthManager |
||||
stateManager *ethchain.StateManager |
||||
blockChain *ethchain.BlockChain |
||||
txPool *ethchain.TxPool |
||||
keyManager *ethcrypto.KeyManager |
||||
} |
||||
|
||||
func New(manager ethchain.EthManager) *PEthereum { |
||||
return &PEthereum{ |
||||
manager, |
||||
manager.StateManager(), |
||||
manager.BlockChain(), |
||||
manager.TxPool(), |
||||
manager.KeyManager(), |
||||
} |
||||
} |
||||
|
||||
func (self *PEthereum) LookupDomain(domain string) string { |
||||
pipe := ethpipe.New(self.manager) |
||||
world := pipe.World() |
||||
|
||||
if len(domain) > 32 { |
||||
domain = string(ethcrypto.Sha3Bin([]byte(domain))) |
||||
} |
||||
data := world.Config().Get("DnsReg").StorageString(domain).Bytes() |
||||
|
||||
// Left padded = A record, Right padded = CNAME
|
||||
if data[0] == 0 { |
||||
data = bytes.TrimLeft(data, "\x00") |
||||
var ipSlice []string |
||||
for _, d := range data { |
||||
ipSlice = append(ipSlice, strconv.Itoa(int(d))) |
||||
} |
||||
|
||||
return strings.Join(ipSlice, ".") |
||||
} else { |
||||
data = bytes.TrimRight(data, "\x00") |
||||
|
||||
return string(data) |
||||
} |
||||
} |
||||
|
||||
func (lib *PEthereum) GetBlock(hexHash string) *PBlock { |
||||
hash := ethutil.Hex2Bytes(hexHash) |
||||
block := lib.blockChain.GetBlock(hash) |
||||
|
||||
return NewPBlock(block) |
||||
} |
||||
|
||||
func (lib *PEthereum) GetKey() *PKey { |
||||
return NewPKey(lib.keyManager.KeyPair()) |
||||
} |
||||
|
||||
func (lib *PEthereum) GetStateObject(address string) *PStateObject { |
||||
stateObject := lib.stateManager.CurrentState().GetStateObject(ethutil.Hex2Bytes(address)) |
||||
if stateObject != nil { |
||||
return NewPStateObject(stateObject) |
||||
} |
||||
|
||||
// See GetStorage for explanation on "nil"
|
||||
return NewPStateObject(nil) |
||||
} |
||||
|
||||
func (lib *PEthereum) GetPeerCount() int { |
||||
return lib.manager.PeerCount() |
||||
} |
||||
|
||||
func (lib *PEthereum) GetPeers() []PPeer { |
||||
var peers []PPeer |
||||
for peer := lib.manager.Peers().Front(); peer != nil; peer = peer.Next() { |
||||
p := peer.Value.(ethchain.Peer) |
||||
// we only want connected peers
|
||||
if atomic.LoadInt32(p.Connected()) != 0 { |
||||
peers = append(peers, *NewPPeer(p)) |
||||
} |
||||
} |
||||
|
||||
return peers |
||||
} |
||||
|
||||
func (lib *PEthereum) GetIsMining() bool { |
||||
return lib.manager.IsMining() |
||||
} |
||||
|
||||
func (lib *PEthereum) GetIsListening() bool { |
||||
return lib.manager.IsListening() |
||||
} |
||||
|
||||
func (lib *PEthereum) GetCoinBase() string { |
||||
return ethutil.Bytes2Hex(lib.keyManager.Address()) |
||||
} |
||||
|
||||
func (lib *PEthereum) GetTransactionsFor(address string, asJson bool) interface{} { |
||||
sBlk := lib.manager.BlockChain().LastBlockHash |
||||
blk := lib.manager.BlockChain().GetBlock(sBlk) |
||||
addr := []byte(ethutil.Hex2Bytes(address)) |
||||
|
||||
var txs []*PTx |
||||
|
||||
for ; blk != nil; blk = lib.manager.BlockChain().GetBlock(sBlk) { |
||||
sBlk = blk.PrevHash |
||||
|
||||
// Loop through all transactions to see if we missed any while being offline
|
||||
for _, tx := range blk.Transactions() { |
||||
if bytes.Compare(tx.Sender(), addr) == 0 || bytes.Compare(tx.Recipient, addr) == 0 { |
||||
ptx := NewPTx(tx) |
||||
//TODO: somehow move this to NewPTx
|
||||
ptx.Confirmations = int(lib.manager.BlockChain().LastBlockNumber - blk.BlockInfo().Number) |
||||
txs = append(txs, ptx) |
||||
} |
||||
} |
||||
} |
||||
if asJson { |
||||
txJson, err := json.Marshal(txs) |
||||
if err != nil { |
||||
return nil |
||||
} |
||||
return string(txJson) |
||||
} |
||||
return txs |
||||
} |
||||
|
||||
func (lib *PEthereum) GetStorage(address, storageAddress string) string { |
||||
return lib.GetStateObject(address).GetStorage(storageAddress) |
||||
} |
||||
|
||||
func (lib *PEthereum) GetTxCountAt(address string) int { |
||||
return lib.GetStateObject(address).Nonce() |
||||
} |
||||
|
||||
func (lib *PEthereum) IsContract(address string) bool { |
||||
return lib.GetStateObject(address).IsContract() |
||||
} |
||||
|
||||
func (lib *PEthereum) SecretToAddress(key string) string { |
||||
pair, err := ethcrypto.NewKeyPairFromSec(ethutil.Hex2Bytes(key)) |
||||
if err != nil { |
||||
return "" |
||||
} |
||||
|
||||
return ethutil.Bytes2Hex(pair.Address()) |
||||
} |
||||
|
||||
func FindAddressInNameReg(stateManager *ethchain.StateManager, name string) []byte { |
||||
nameReg := EthereumConfig(stateManager).NameReg() |
||||
if nameReg != nil { |
||||
addr := ethutil.RightPadBytes([]byte(name), 32) |
||||
|
||||
reg := nameReg.GetStorage(ethutil.BigD(addr)) |
||||
|
||||
return reg.Bytes() |
||||
} |
||||
|
||||
return nil |
||||
} |
||||
|
||||
func FindNameInNameReg(stateManager *ethchain.StateManager, addr []byte) string { |
||||
nameReg := EthereumConfig(stateManager).NameReg() |
||||
if nameReg != nil { |
||||
addr = ethutil.LeftPadBytes(addr, 32) |
||||
|
||||
reg := nameReg.GetStorage(ethutil.BigD(addr)) |
||||
|
||||
return strings.TrimRight(reg.Str(), "\x00") |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (*PReceipt, error) { |
||||
return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr) |
||||
} |
||||
|
||||
func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, script string) (*PReceipt, error) { |
||||
return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, script) |
||||
} |
||||
|
||||
func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, scriptStr string) (*PReceipt, error) { |
||||
var hash []byte |
||||
var contractCreation bool |
||||
if len(recipient) == 0 { |
||||
contractCreation = true |
||||
} else { |
||||
// Check if an address is stored by this address
|
||||
addr := FindAddressInNameReg(lib.stateManager, recipient) |
||||
if len(addr) > 0 { |
||||
hash = addr |
||||
} else { |
||||
hash = ethutil.Hex2Bytes(recipient) |
||||
} |
||||
} |
||||
|
||||
var keyPair *ethcrypto.KeyPair |
||||
var err error |
||||
if ethutil.IsHex(key) { |
||||
keyPair, err = ethcrypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key[2:]))) |
||||
} else { |
||||
keyPair, err = ethcrypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(key))) |
||||
} |
||||
|
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
value := ethutil.Big(valueStr) |
||||
gas := ethutil.Big(gasStr) |
||||
gasPrice := ethutil.Big(gasPriceStr) |
||||
var tx *ethchain.Transaction |
||||
// Compile and assemble the given data
|
||||
if contractCreation { |
||||
var script []byte |
||||
var err error |
||||
if ethutil.IsHex(scriptStr) { |
||||
script = ethutil.Hex2Bytes(scriptStr[2:]) |
||||
} else { |
||||
script, err = ethutil.Compile(scriptStr, false) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
tx = ethchain.NewContractCreationTx(value, gas, gasPrice, script) |
||||
} else { |
||||
data := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) { |
||||
slice := strings.Split(s, "\n") |
||||
for _, dataItem := range slice { |
||||
d := ethutil.FormatData(dataItem) |
||||
ret = append(ret, d...) |
||||
} |
||||
return |
||||
}) |
||||
|
||||
tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, data) |
||||
} |
||||
|
||||
acc := lib.stateManager.TransState().GetOrNewStateObject(keyPair.Address()) |
||||
tx.Nonce = acc.Nonce |
||||
acc.Nonce += 1 |
||||
lib.stateManager.TransState().UpdateStateObject(acc) |
||||
|
||||
tx.Sign(keyPair.PrivateKey) |
||||
lib.txPool.QueueTransaction(tx) |
||||
|
||||
if contractCreation { |
||||
logger.Infof("Contract addr %x", tx.CreationAddress()) |
||||
} |
||||
|
||||
return NewPReciept(contractCreation, tx.CreationAddress(), tx.Hash(), keyPair.Address()), nil |
||||
} |
@ -1,273 +0,0 @@ |
||||
package ethpub |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"fmt" |
||||
"strings" |
||||
|
||||
"github.com/ethereum/eth-go/ethchain" |
||||
"github.com/ethereum/eth-go/ethcrypto" |
||||
"github.com/ethereum/eth-go/ethstate" |
||||
"github.com/ethereum/eth-go/ethtrie" |
||||
"github.com/ethereum/eth-go/ethutil" |
||||
) |
||||
|
||||
// Peer interface exposed to QML
|
||||
|
||||
type PPeer struct { |
||||
ref *ethchain.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"` |
||||
} |
||||
|
||||
func NewPPeer(peer ethchain.Peer) *PPeer { |
||||
if peer == nil { |
||||
return nil |
||||
} |
||||
|
||||
// TODO: There must be something build in to do this?
|
||||
var ip []string |
||||
for _, i := range peer.Host() { |
||||
ip = append(ip, fmt.Sprintf("%d", i)) |
||||
} |
||||
ipAddress := strings.Join(ip, ".") |
||||
|
||||
return &PPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port()), Latency: peer.PingTime()} |
||||
} |
||||
|
||||
// Block interface exposed to QML
|
||||
type PBlock struct { |
||||
ref *ethchain.Block |
||||
Number int `json:"number"` |
||||
Hash string `json:"hash"` |
||||
Transactions string `json:"transactions"` |
||||
Time int64 `json:"time"` |
||||
Coinbase string `json:"coinbase"` |
||||
Name string `json:"name"` |
||||
GasLimit string `json:"gasLimit"` |
||||
GasUsed string `json:"gasUsed"` |
||||
} |
||||
|
||||
// Creates a new QML Block from a chain block
|
||||
func NewPBlock(block *ethchain.Block) *PBlock { |
||||
if block == nil { |
||||
return nil |
||||
} |
||||
|
||||
var ptxs []PTx |
||||
for _, tx := range block.Transactions() { |
||||
ptxs = append(ptxs, *NewPTx(tx)) |
||||
} |
||||
|
||||
txJson, err := json.Marshal(ptxs) |
||||
if err != nil { |
||||
return nil |
||||
} |
||||
|
||||
return &PBlock{ref: block, Number: int(block.Number.Uint64()), GasUsed: block.GasUsed.String(), GasLimit: block.GasLimit.String(), Hash: ethutil.Bytes2Hex(block.Hash()), Transactions: string(txJson), Time: block.Time, Coinbase: ethutil.Bytes2Hex(block.Coinbase)} |
||||
} |
||||
|
||||
func (self *PBlock) ToString() string { |
||||
if self.ref != nil { |
||||
return self.ref.String() |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (self *PBlock) GetTransaction(hash string) *PTx { |
||||
tx := self.ref.GetTransaction(ethutil.Hex2Bytes(hash)) |
||||
if tx == nil { |
||||
return nil |
||||
} |
||||
|
||||
return NewPTx(tx) |
||||
} |
||||
|
||||
type PTx struct { |
||||
ref *ethchain.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 NewPTx(tx *ethchain.Transaction) *PTx { |
||||
hash := ethutil.Bytes2Hex(tx.Hash()) |
||||
receiver := ethutil.Bytes2Hex(tx.Recipient) |
||||
if receiver == "0000000000000000000000000000000000000000" { |
||||
receiver = ethutil.Bytes2Hex(tx.CreationAddress()) |
||||
} |
||||
sender := ethutil.Bytes2Hex(tx.Sender()) |
||||
createsContract := tx.CreatesContract() |
||||
|
||||
var data string |
||||
if tx.CreatesContract() { |
||||
data = strings.Join(ethchain.Disassemble(tx.Data), "\n") |
||||
} else { |
||||
data = ethutil.Bytes2Hex(tx.Data) |
||||
} |
||||
|
||||
return &PTx{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 *PTx) ToString() string { |
||||
return self.ref.String() |
||||
} |
||||
|
||||
type PKey struct { |
||||
Address string `json:"address"` |
||||
PrivateKey string `json:"privateKey"` |
||||
PublicKey string `json:"publicKey"` |
||||
} |
||||
|
||||
func NewPKey(key *ethcrypto.KeyPair) *PKey { |
||||
return &PKey{ethutil.Bytes2Hex(key.Address()), ethutil.Bytes2Hex(key.PrivateKey), ethutil.Bytes2Hex(key.PublicKey)} |
||||
} |
||||
|
||||
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), |
||||
} |
||||
} |
||||
|
||||
type PStateObject struct { |
||||
object *ethstate.StateObject |
||||
} |
||||
|
||||
func NewPStateObject(object *ethstate.StateObject) *PStateObject { |
||||
return &PStateObject{object: object} |
||||
} |
||||
|
||||
func (c *PStateObject) GetStorage(address string) string { |
||||
// Because somehow, even if you return nil to QML it
|
||||
// still has some magical object so we can't rely on
|
||||
// undefined or null at the QML side
|
||||
if c.object != nil { |
||||
val := c.object.GetStorage(ethutil.Big("0x" + address)) |
||||
|
||||
return val.BigInt().String() |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (c *PStateObject) Balance() string { |
||||
if c.object != nil { |
||||
return c.object.Balance.String() |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (c *PStateObject) Address() string { |
||||
if c.object != nil { |
||||
return ethutil.Bytes2Hex(c.object.Address()) |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (c *PStateObject) Nonce() int { |
||||
if c.object != nil { |
||||
return int(c.object.Nonce) |
||||
} |
||||
|
||||
return 0 |
||||
} |
||||
|
||||
func (c *PStateObject) Root() string { |
||||
if c.object != nil { |
||||
return ethutil.Bytes2Hex(ethutil.NewValue(c.object.State.Root()).Bytes()) |
||||
} |
||||
|
||||
return "<err>" |
||||
} |
||||
|
||||
func (c *PStateObject) IsContract() bool { |
||||
if c.object != nil { |
||||
return len(c.object.Code) > 0 |
||||
} |
||||
|
||||
return false |
||||
} |
||||
|
||||
func (self *PStateObject) EachStorage(cb ethtrie.EachCallback) { |
||||
self.object.EachStorage(cb) |
||||
} |
||||
|
||||
type KeyVal struct { |
||||
Key string `json:"key"` |
||||
Value string `json:"value"` |
||||
} |
||||
|
||||
func (c *PStateObject) StateKeyVal(asJson bool) interface{} { |
||||
var values []KeyVal |
||||
if c.object != nil { |
||||
c.object.EachStorage(func(name string, value *ethutil.Value) { |
||||
value.Decode() |
||||
values = append(values, KeyVal{ethutil.Bytes2Hex([]byte(name)), ethutil.Bytes2Hex(value.Bytes())}) |
||||
}) |
||||
} |
||||
|
||||
if asJson { |
||||
valuesJson, err := json.Marshal(values) |
||||
if err != nil { |
||||
return nil |
||||
} |
||||
|
||||
return string(valuesJson) |
||||
} |
||||
|
||||
return values |
||||
} |
||||
|
||||
func (c *PStateObject) Script() string { |
||||
if c.object != nil { |
||||
return strings.Join(ethchain.Disassemble(c.object.Code), " ") |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
func (c *PStateObject) HexScript() string { |
||||
if c.object != nil { |
||||
return ethutil.Bytes2Hex(c.object.Code) |
||||
} |
||||
|
||||
return "" |
||||
} |
||||
|
||||
type PStorageState struct { |
||||
StateAddress string |
||||
Address string |
||||
Value string |
||||
} |
||||
|
||||
func NewPStorageState(storageObject *ethstate.StorageState) *PStorageState { |
||||
return &PStorageState{ethutil.Bytes2Hex(storageObject.StateAddress), ethutil.Bytes2Hex(storageObject.Address), storageObject.Value.String()} |
||||
} |
Loading…
Reference in new issue