Load ERC20 events in eth.GetBlock

ethereum
Martin Boehm 2018-11-15 18:07:45 +01:00
parent 089346a4bb
commit fad7ea326c
2 changed files with 56 additions and 26 deletions

View File

@ -27,26 +27,26 @@ func NewEthereumParser() *EthereumParser {
}
type rpcHeader struct {
Hash ethcommon.Hash `json:"hash"`
Difficulty string `json:"difficulty"`
Number string `json:"number"`
Time string `json:"timestamp"`
Size string `json:"size"`
Nonce string `json:"nonce"`
Hash string `json:"hash"`
Difficulty string `json:"difficulty"`
Number string `json:"number"`
Time string `json:"timestamp"`
Size string `json:"size"`
Nonce string `json:"nonce"`
}
type rpcTransaction struct {
AccountNonce string `json:"nonce"`
GasPrice string `json:"gasPrice"`
GasLimit string `json:"gas"`
To string `json:"to" rlp:"nil"` // nil means contract creation
Value string `json:"value"`
Payload string `json:"input"`
Hash ethcommon.Hash `json:"hash" rlp:"-"`
BlockNumber string `json:"blockNumber"`
BlockHash *ethcommon.Hash `json:"blockHash,omitempty"`
From string `json:"from"`
TransactionIndex string `json:"transactionIndex"`
AccountNonce string `json:"nonce"`
GasPrice string `json:"gasPrice"`
GasLimit string `json:"gas"`
To string `json:"to"` // nil means contract creation
Value string `json:"value"`
Payload string `json:"input"`
Hash string `json:"hash"`
BlockNumber string `json:"blockNumber"`
BlockHash string `json:"blockHash,omitempty"`
From string `json:"from"`
TransactionIndex string `json:"transactionIndex"`
// Signature values - ignored
// V string `json:"v"`
// R string `json:"r"`
@ -59,6 +59,11 @@ type rpcLog struct {
Data string `json:"data"`
}
type rpcLogWithTxHash struct {
rpcLog
Hash string `json:"transactionHash"`
}
type rpcReceipt struct {
GasUsed string `json:"gasUsed"`
Status string `json:"status"`
@ -86,7 +91,7 @@ func ethNumber(n string) (int64, error) {
}
func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, receipt *rpcReceipt, blocktime int64, confirmations uint32, marshallHex bool) (*bchain.Tx, error) {
txid := tx.Hash.Hex()
txid := tx.Hash
var (
fa, ta []string
err error
@ -105,7 +110,7 @@ func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, receipt *rpcReceipt, bloc
if marshallHex {
// completeTransaction without BlockHash is marshalled and hex encoded to bchain.Tx.Hex
bh := tx.BlockHash
tx.BlockHash = nil
tx.BlockHash = ""
b, err := json.Marshal(ct)
if err != nil {
return nil, err
@ -235,7 +240,9 @@ func (p *EthereumParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) (
if pt.Tx.GasLimit, err = hexutil.DecodeUint64(r.Tx.GasLimit); err != nil {
return nil, errors.Annotatef(err, "GasLimit %v", r.Tx.GasLimit)
}
pt.Tx.Hash = r.Tx.Hash.Bytes()
if pt.Tx.Hash, err = hexDecode(r.Tx.Hash); err != nil {
return nil, errors.Annotatef(err, "Hash %v", r.Tx.Hash)
}
if pt.Tx.Payload, err = hexDecode(r.Tx.Payload); err != nil {
return nil, errors.Annotatef(err, "Payload %v", r.Tx.Payload)
}
@ -306,7 +313,7 @@ func (p *EthereumParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
BlockNumber: hexutil.EncodeUint64(uint64(pt.BlockNumber)),
From: hexutil.Encode(pt.Tx.From),
GasLimit: hexutil.EncodeUint64(pt.Tx.GasLimit),
Hash: ethcommon.BytesToHash(pt.Tx.Hash),
Hash: hexutil.Encode(pt.Tx.Hash),
Payload: hexutil.Encode(pt.Tx.Payload),
GasPrice: hexEncodeBig(pt.Tx.GasPrice),
// R: hexEncodeBig(pt.R),

View File

@ -374,7 +374,7 @@ func (b *EthereumRPC) ethHeaderToBlockHeader(h *rpcHeader) (*bchain.BlockHeader,
return nil, err
}
return &bchain.BlockHeader{
Hash: h.Hash.Hex(),
Hash: h.Hash,
Height: uint32(height),
Confirmations: int(c),
Time: time,
@ -427,6 +427,25 @@ func (b *EthereumRPC) getBlockRaw(hash string, height uint32, fullTxs bool) (jso
return raw, nil
}
func (b *EthereumRPC) getERC20EventsForBlock(blockNumber string) (map[string][]*rpcLog, error) {
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
defer cancel()
var logs []rpcLogWithTxHash
err := b.rpc.CallContext(ctx, &logs, "eth_getLogs", map[string]interface{}{
"fromBlock": blockNumber,
"toBlock": blockNumber,
"topics": []string{erc20EventTransferSignature},
})
if err != nil {
return nil, errors.Annotatef(err, "blockNumber %v", blockNumber)
}
r := make(map[string][]*rpcLog)
for _, l := range logs {
r[l.Hash] = append(r[l.Hash], &l.rpcLog)
}
return r, nil
}
// GetBlock returns block with given hash or height, hash has precedence if both passed
func (b *EthereumRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) {
raw, err := b.getBlockRaw(hash, height, true)
@ -445,12 +464,16 @@ func (b *EthereumRPC) GetBlock(hash string, height uint32) (*bchain.Block, error
if err != nil {
return nil, errors.Annotatef(err, "hash %v, height %v", hash, height)
}
// TODO - get ERC20 events
// get ERC20 events
logs, err := b.getERC20EventsForBlock(head.Number)
if err != nil {
return nil, err
}
btxs := make([]bchain.Tx, len(body.Transactions))
for i, tx := range body.Transactions {
btx, err := b.Parser.ethTxToTx(&tx, nil, bbh.Time, uint32(bbh.Confirmations), false)
btx, err := b.Parser.ethTxToTx(&tx, &rpcReceipt{Logs: logs[tx.Hash]}, bbh.Time, uint32(bbh.Confirmations), false)
if err != nil {
return nil, errors.Annotatef(err, "hash %v, height %v, txid %v", hash, height, tx.Hash.String())
return nil, errors.Annotatef(err, "hash %v, height %v, txid %v", hash, height, tx.Hash)
}
btxs[i] = *btx
}
@ -511,7 +534,7 @@ func (b *EthereumRPC) GetTransaction(txid string) (*bchain.Tx, error) {
}
} else {
// non mempool tx - we must read the block header to get the block time
raw, err := b.getBlockRaw(tx.BlockHash.Hex(), 0, false)
raw, err := b.getBlockRaw(tx.BlockHash, 0, false)
if err != nil {
return nil, err
}