Created
January 3, 2017 11:45
-
-
Save bas-vk/299f4a686b66a22cf87302c561ee5866 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"math/big" | |
"strings" | |
"time" | |
"encoding/json" | |
set "github.com/deckarep/golang-set" | |
"github.com/ethereum/go-ethereum" | |
"github.com/ethereum/go-ethereum/accounts/abi" | |
"github.com/ethereum/go-ethereum/common" | |
"github.com/ethereum/go-ethereum/common/hexutil" | |
"github.com/ethereum/go-ethereum/core/vm" | |
"github.com/ethereum/go-ethereum/ethclient" | |
) | |
var ( | |
ENSTEmporaryHashRegistryABI = `[{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"releaseDeed","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"unhashedName","type":"string"}],"name":"invalidateName","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"hash","type":"bytes32"},{"name":"owner","type":"address"},{"name":"value","type":"uint256"},{"name":"salt","type":"bytes32"}],"name":"shaBid","outputs":[{"name":"sealedBid","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"entries","outputs":[{"name":"status","type":"uint8"},{"name":"deed","type":"address"},{"name":"registrationDate","type":"uint256"},{"name":"value","type":"uint256"},{"name":"highestBid","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"ens","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"transferRegistrars","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"sealedBids","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"},{"name":"newOwner","type":"address"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"finalizeAuction","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"},{"name":"_owner","type":"address"},{"name":"_value","type":"uint256"},{"name":"_salt","type":"bytes32"}],"name":"unsealBid","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"registryCreated","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"sealedBid","type":"bytes32"}],"name":"newBid","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"seal","type":"bytes32"}],"name":"cancelBid","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_hashes","type":"bytes32[]"}],"name":"startAuctions","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"startAuction","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"rootNode","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"inputs":[{"name":"_ens","type":"address"},{"name":"_rootNode","type":"bytes32"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"hash","type":"bytes32"},{"indexed":false,"name":"auctionExpiryDate","type":"uint256"}],"name":"AuctionStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"hash","type":"bytes32"},{"indexed":false,"name":"deposit","type":"uint256"}],"name":"NewBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"hash","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"status","type":"uint8"}],"name":"BidRevealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"hash","type":"bytes32"},{"indexed":true,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"now","type":"uint256"}],"name":"HashRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"hash","type":"bytes32"},{"indexed":false,"name":"value","type":"uint256"}],"name":"HashReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"hash","type":"bytes32"},{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"now","type":"uint256"}],"name":"HashInvalidated","type":"event"}]` | |
ENSContractAddress = common.HexToAddress("c68de5b43c3d980b0c110a77a5f78d3c4c4d63b4") | |
rpcTimeout = 60 * time.Second | |
) | |
// Helper type that makes logs from the AuctionStarted event comparable. | |
// event AuctionStarted(bytes32 indexed hash, uint auctionExpiryDate); | |
type AuctionStartedLog struct { | |
Address common.Address | |
Topics [2]common.Hash | |
Data [32]byte | |
BlockNumber uint64 | |
TxHash common.Hash | |
TxIndex uint | |
BlockHash common.Hash | |
Index uint | |
Removed bool | |
} | |
func (l AuctionStartedLog) MarshalJSON() ([]byte, error) { | |
fields := make(map[string]interface{}) | |
fields["address"] = l.Address | |
fields["topics"] = l.Topics | |
fields["data"] = hexutil.Encode(l.Data[:]) | |
fields["txIndex"] = l.TxIndex | |
fields["txHash"] = l.TxHash | |
fields["index"] = l.Index | |
fields["removed"] = l.Removed | |
if (l.BlockHash != common.Hash{}) { | |
fields["blockHash"] = l.BlockHash | |
fields["blockNumber"] = l.BlockNumber | |
} | |
return json.Marshal(fields) | |
} | |
func convert(vmlogs []vm.Log) []interface{} { | |
logs := make([]interface{}, len(vmlogs)) | |
for i, log := range vmlogs { | |
if len(log.Topics) != 2 { | |
panic("Invalid number of topics") | |
} | |
l := AuctionStartedLog{ | |
Address: log.Address, | |
BlockNumber: log.BlockNumber, | |
TxHash: log.TxHash, | |
TxIndex: log.TxIndex, | |
BlockHash: log.BlockHash, | |
Index: log.Index, | |
Removed: log.Removed, | |
} | |
l.Topics[0], l.Topics[1] = log.Topics[0], log.Topics[1] | |
copy(l.Data[:], log.Data) | |
logs[i] = l | |
} | |
return logs | |
} | |
func fetchLogs(client *ethclient.Client, fromBlock, toBlock *big.Int) []interface{} { | |
ensABI, err := abi.JSON(strings.NewReader(ENSTEmporaryHashRegistryABI)) | |
if err != nil { | |
panic(err) | |
} | |
eventTopicId := ensABI.Events["AuctionStarted"].Id() | |
q := ethereum.FilterQuery{ | |
FromBlock: fromBlock, | |
ToBlock: toBlock, | |
Addresses: []common.Address{ENSContractAddress}, | |
Topics: [][]common.Hash{[]common.Hash{eventTopicId}}, | |
} | |
ctx, _ := context.WithTimeout(context.Background(), rpcTimeout) | |
vmlogs, err := client.FilterLogs(ctx, q) | |
if err != nil { | |
panic(err) | |
} | |
return convert(vmlogs) | |
} | |
func main() { | |
client, err := ethclient.Dial("http://localhost:8545") | |
if err != nil { | |
panic(err) | |
} | |
fromBlock, toBlock := big.NewInt(25461), big.NewInt(275836) | |
// geth --testnet --rpc | |
gethLogs := set.NewSetFromSlice(fetchLogs(client, fromBlock, toBlock)) | |
//parity --testnet --port 31313 --jsonrpc-port 8546 | |
client, err = ethclient.Dial("http://localhost:8546") | |
if err != nil { | |
panic(err) | |
} | |
parityLogs := set.NewSetFromSlice(fetchLogs(client, fromBlock, toBlock)) | |
inBoth := gethLogs.Intersect(parityLogs) | |
gethUnique := gethLogs.Difference(inBoth) | |
parityUnique := parityLogs.Difference(inBoth) | |
fmt.Printf(" geth logs: %d\n", gethLogs.Cardinality()) | |
fmt.Printf(" parity logs: %d\n", parityLogs.Cardinality()) | |
fmt.Printf(" unique geth logs: %d\n", gethUnique.Cardinality()) | |
fmt.Printf("unique parity logs: %d\n", parityUnique.Cardinality()) | |
fmt.Println("Unique Geth logs:") | |
it := gethUnique.Iterator() | |
for elem := range it.C { | |
serialized, _ := json.Marshal(elem) | |
fmt.Printf("%s\n", serialized) | |
} | |
fmt.Println() | |
fmt.Println("Unique Parity logs:") | |
it = parityUnique.Iterator() | |
for elem := range it.C { | |
serialized, _ := json.Marshal(elem) | |
fmt.Printf("%s\n", serialized) | |
} | |
fmt.Println() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment