| 
									
										
										
										
											2014-10-31 14:30:08 +01:00
										 |  |  | package xeth | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-01-29 23:58:43 +01:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2015-01-05 19:53:53 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-04 10:28:02 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2014-10-31 12:37:43 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2014-10-23 15:01:27 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							| 
									
										
										
										
											2014-12-14 18:09:33 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/p2p" | 
					
						
							| 
									
										
										
										
											2015-01-29 23:58:43 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							| 
									
										
										
										
											2014-10-31 14:43:14 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/state" | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | func toHex(b []byte) string { | 
					
						
							|  |  |  | 	return "0x" + ethutil.Bytes2Hex(b) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | func fromHex(s string) []byte { | 
					
						
							|  |  |  | 	if len(s) > 1 { | 
					
						
							|  |  |  | 		if s[0:2] == "0x" { | 
					
						
							|  |  |  | 			s = s[2:] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return ethutil.Hex2Bytes(s) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 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) { | 
					
						
							| 
									
										
										
										
											2015-01-29 20:39:26 +01:00
										 |  |  | 		return self.storage(ethutil.Hex2Bytes(str[2:])) | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2015-01-29 20:39:26 +01:00
										 |  |  | 		return self.storage(ethutil.RightPadBytes([]byte(str), 32)) | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Object) StorageValue(addr *ethutil.Value) *ethutil.Value { | 
					
						
							| 
									
										
										
										
											2015-01-29 20:39:26 +01:00
										 |  |  | 	return self.storage(addr.Bytes()) | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 20:39:26 +01:00
										 |  |  | func (self *Object) storage(addr []byte) *ethutil.Value { | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	return self.StateObject.GetStorage(ethutil.BigD(addr)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 20:39:26 +01:00
										 |  |  | func (self *Object) Storage() (storage map[string]string) { | 
					
						
							|  |  |  | 	storage = make(map[string]string) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	it := self.StateObject.Trie().Iterator() | 
					
						
							|  |  |  | 	for it.Next() { | 
					
						
							| 
									
										
										
										
											2015-01-29 23:58:43 +01:00
										 |  |  | 		var data []byte | 
					
						
							|  |  |  | 		rlp.Decode(bytes.NewReader(it.Value), &data) | 
					
						
							|  |  |  | 		storage[toHex(it.Key)] = toHex(data) | 
					
						
							| 
									
										
										
										
											2015-01-29 20:39:26 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | // Block interface exposed to QML | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | type Block struct { | 
					
						
							| 
									
										
										
										
											2014-09-08 00:49:47 +02:00
										 |  |  | 	//Transactions string `json:"transactions"` | 
					
						
							| 
									
										
										
										
											2014-11-18 16:58:22 +01:00
										 |  |  | 	ref          *types.Block | 
					
						
							| 
									
										
										
										
											2014-09-08 00:49:47 +02:00
										 |  |  | 	Size         string        `json:"size"` | 
					
						
							|  |  |  | 	Number       int           `json:"number"` | 
					
						
							|  |  |  | 	Hash         string        `json:"hash"` | 
					
						
							|  |  |  | 	Transactions *ethutil.List `json:"transactions"` | 
					
						
							| 
									
										
										
										
											2014-10-31 10:50:16 +01:00
										 |  |  | 	Uncles       *ethutil.List `json:"uncles"` | 
					
						
							| 
									
										
										
										
											2014-09-08 00:49:47 +02:00
										 |  |  | 	Time         int64         `json:"time"` | 
					
						
							|  |  |  | 	Coinbase     string        `json:"coinbase"` | 
					
						
							|  |  |  | 	Name         string        `json:"name"` | 
					
						
							|  |  |  | 	GasLimit     string        `json:"gasLimit"` | 
					
						
							|  |  |  | 	GasUsed      string        `json:"gasUsed"` | 
					
						
							| 
									
										
										
										
											2014-09-25 16:57:49 +02:00
										 |  |  | 	PrevHash     string        `json:"prevHash"` | 
					
						
							| 
									
										
										
										
											2014-11-10 01:17:31 +01:00
										 |  |  | 	Bloom        string        `json:"bloom"` | 
					
						
							|  |  |  | 	Raw          string        `json:"raw"` | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Creates a new QML Block from a chain block | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func NewBlock(block *types.Block) *Block { | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	if block == nil { | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 		return &Block{} | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	ptxs := make([]*Transaction, len(block.Transactions())) | 
					
						
							| 
									
										
										
										
											2014-10-31 10:50:16 +01:00
										 |  |  | 	for i, tx := range block.Transactions() { | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 		ptxs[i] = NewTx(tx) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-31 10:50:16 +01:00
										 |  |  | 	txlist := ethutil.NewList(ptxs) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	puncles := make([]*Block, len(block.Uncles())) | 
					
						
							| 
									
										
										
										
											2014-12-23 13:48:44 +01:00
										 |  |  | 	for i, uncle := range block.Uncles() { | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 		puncles[i] = NewBlock(types.NewBlockWithHeader(uncle)) | 
					
						
							| 
									
										
										
										
											2014-10-31 10:50:16 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ulist := ethutil.NewList(puncles) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	return &Block{ | 
					
						
							| 
									
										
										
										
											2014-09-25 16:57:49 +02:00
										 |  |  | 		ref: block, Size: block.Size().String(), | 
					
						
							| 
									
										
										
										
											2014-12-23 13:48:44 +01:00
										 |  |  | 		Number: int(block.NumberU64()), GasUsed: block.GasUsed().String(), | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 		GasLimit: block.GasLimit().String(), Hash: toHex(block.Hash()), | 
					
						
							| 
									
										
										
										
											2014-10-31 10:50:16 +01:00
										 |  |  | 		Transactions: txlist, Uncles: ulist, | 
					
						
							| 
									
										
										
										
											2014-12-23 13:48:44 +01:00
										 |  |  | 		Time:     block.Time(), | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 		Coinbase: toHex(block.Coinbase()), | 
					
						
							|  |  |  | 		PrevHash: toHex(block.ParentHash()), | 
					
						
							|  |  |  | 		Bloom:    toHex(block.Bloom()), | 
					
						
							| 
									
										
										
										
											2014-11-10 01:17:31 +01:00
										 |  |  | 		Raw:      block.String(), | 
					
						
							| 
									
										
										
										
											2014-09-25 16:57:49 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func (self *Block) ToString() string { | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	if self.ref != nil { | 
					
						
							|  |  |  | 		return self.ref.String() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func (self *Block) GetTransaction(hash string) *Transaction { | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 	tx := self.ref.Transaction(fromHex(hash)) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	if tx == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	return NewTx(tx) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | type Transaction struct { | 
					
						
							| 
									
										
										
										
											2014-11-18 16:58:22 +01:00
										 |  |  | 	ref *types.Transaction | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func NewTx(tx *types.Transaction) *Transaction { | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 	hash := toHex(tx.Hash()) | 
					
						
							|  |  |  | 	receiver := toHex(tx.To()) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	if receiver == "0000000000000000000000000000000000000000" { | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 		receiver = toHex(core.AddressFromMessage(tx)) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 	sender := toHex(tx.From()) | 
					
						
							| 
									
										
										
										
											2014-12-18 15:33:22 +01:00
										 |  |  | 	createsContract := core.MessageCreatesContract(tx) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var data string | 
					
						
							| 
									
										
										
										
											2014-12-18 15:33:22 +01:00
										 |  |  | 	if createsContract { | 
					
						
							| 
									
										
										
										
											2014-12-18 15:18:13 +01:00
										 |  |  | 		data = strings.Join(core.Disassemble(tx.Data()), "\n") | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 		data = toHex(tx.Data()) | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	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())} | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func (self *Transaction) ToString() string { | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	return self.ref.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | type Key struct { | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	Address    string `json:"address"` | 
					
						
							|  |  |  | 	PrivateKey string `json:"privateKey"` | 
					
						
							|  |  |  | 	PublicKey  string `json:"publicKey"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func NewKey(key *crypto.KeyPair) *Key { | 
					
						
							|  |  |  | 	return &Key{toHex(key.Address()), toHex(key.PrivateKey), toHex(key.PublicKey)} | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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, | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 		toHex(creationAddress), | 
					
						
							|  |  |  | 		toHex(hash), | 
					
						
							|  |  |  | 		toHex(address), | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Peer interface exposed to QML | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | type Peer struct { | 
					
						
							| 
									
										
										
										
											2015-01-05 19:53:53 +01:00
										 |  |  | 	ref     *p2p.Peer | 
					
						
							|  |  |  | 	Ip      string `json:"ip"` | 
					
						
							|  |  |  | 	Version string `json:"version"` | 
					
						
							|  |  |  | 	Caps    string `json:"caps"` | 
					
						
							| 
									
										
										
										
											2014-12-14 18:09:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func NewPeer(peer *p2p.Peer) *Peer { | 
					
						
							| 
									
										
										
										
											2015-01-05 19:53:53 +01:00
										 |  |  | 	var caps []string | 
					
						
							|  |  |  | 	for _, cap := range peer.Caps() { | 
					
						
							|  |  |  | 		caps = append(caps, fmt.Sprintf("%s/%d", cap.Name, cap.Version)) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-14 18:09:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | 	return &Peer{ | 
					
						
							| 
									
										
										
										
											2015-01-05 19:53:53 +01:00
										 |  |  | 		ref:     peer, | 
					
						
							| 
									
										
										
										
											2015-01-06 13:18:09 +01:00
										 |  |  | 		Ip:      fmt.Sprintf("%v", peer.RemoteAddr()), | 
					
						
							| 
									
										
										
										
											2015-02-05 03:16:16 +01:00
										 |  |  | 		Version: fmt.Sprintf("%v", peer.ID()), | 
					
						
							| 
									
										
										
										
											2015-01-05 19:53:53 +01:00
										 |  |  | 		Caps:    fmt.Sprintf("%v", caps), | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | type Receipt struct { | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	CreatedContract bool   `json:"createdContract"` | 
					
						
							|  |  |  | 	Address         string `json:"address"` | 
					
						
							|  |  |  | 	Hash            string `json:"hash"` | 
					
						
							|  |  |  | 	Sender          string `json:"sender"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-28 18:35:49 +01:00
										 |  |  | func NewReciept(contractCreation bool, creationAddress, hash, address []byte) *Receipt { | 
					
						
							|  |  |  | 	return &Receipt{ | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 		contractCreation, | 
					
						
							| 
									
										
										
										
											2015-01-10 00:51:56 +01:00
										 |  |  | 		toHex(creationAddress), | 
					
						
							|  |  |  | 		toHex(hash), | 
					
						
							|  |  |  | 		toHex(address), | 
					
						
							| 
									
										
										
										
											2014-08-15 13:05:13 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } |