solc --abi Exchange.sol
abigen --abi="Exchange.sol:Exchange.abi" --pkg=exchange --out=Exchange.go
pragma solidity 0.4.11;
contract Exchange {
event LogFill(
address indexed maker,
address taker,
address indexed feeRecipient,
address makerToken,
address takerToken,
uint filledMakerTokenAmount,
uint filledTakerTokenAmount,
uint paidMakerFee,
uint paidTakerFee,
bytes32 indexed tokens, // keccak256(makerToken, takerToken), allows subscribing to a token pair
bytes32 orderHash
);
event LogCancel(
address indexed maker,
address indexed feeRecipient,
address makerToken,
address takerToken,
uint cancelledMakerTokenAmount,
uint cancelledTakerTokenAmount,
bytes32 indexed tokens,
bytes32 orderHash
);
event LogError(uint8 indexed errorId, bytes32 indexed orderHash);
}
package main
import (
"context"
"fmt"
"log"
"math/big"
"strconv"
"strings"
exchange "./contracts_0xprotocol" // for demo
"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/ethclient"
)
// LogFill ...
type LogFill struct {
Maker common.Address
Taker common.Address
FeeRecipient common.Address
MakerToken common.Address
TakerToken common.Address
FilledMakerTokenAmount *big.Int
FilledTakerTokenAmount *big.Int
PaidMakerFee *big.Int
PaidTakerFee *big.Int
Tokens [32]byte
OrderHash [32]byte
}
// LogCancel ...
type LogCancel struct {
Maker common.Address
FeeRecipient common.Address
MakerToken common.Address
TakerToken common.Address
CancelledMakerTokenAmount *big.Int
CancelledTakerTokenAmount *big.Int
Tokens [32]byte
OrderHash [32]byte
}
// LogError ...
type LogError struct {
ErrorID uint8
OrderHash [32]byte
}
func main() {
client, err := ethclient.Dial("https://mainnet.infura.io")
if err != nil {
log.Fatal(err)
}
// 0x Protocol Exchange smart contract address
contractAddress := common.HexToAddress("0x12459C951127e0c374FF9105DdA097662A027093")
query := ethereum.FilterQuery{
FromBlock: big.NewInt(6383482),
ToBlock: big.NewInt(6383488),
Addresses: []common.Address{
contractAddress,
},
}
logs, err := client.FilterLogs(context.Background(), query)
if err != nil {
log.Fatal(err)
}
contractAbi, err := abi.JSON(strings.NewReader(string(exchange.ExchangeABI)))
if err != nil {
log.Fatal(err)
}
// NOTE: keccak256("LogFill(address,address,address,address,address,uint256,uint256,uint256,uint256,bytes32,bytes32)")
logFillEvent := common.HexToHash("0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb3")
// NOTE: keccak256("LogCancel(address,address,address,address,uint256,uint256,bytes32,bytes32)")
logCancelEvent := common.HexToHash("67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b04587131")
// NOTE: keccak256("LogError(uint8,bytes32)")
logErrorEvent := common.HexToHash("36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e90")
for _, vLog := range logs {
fmt.Printf("Log Block Number: %d\n", vLog.BlockNumber)
fmt.Printf("Log Index: %d\n", vLog.Index)
switch vLog.Topics[0].Hex() {
case logFillEvent.Hex():
fmt.Printf("Log Name: LogFill\n")
var fillEvent LogFill
err := contractAbi.Unpack(&fillEvent, "LogFill", vLog.Data)
if err != nil {
log.Fatal(err)
}
fillEvent.Maker = common.HexToAddress(vLog.Topics[1].Hex())
fillEvent.FeeRecipient = common.HexToAddress(vLog.Topics[2].Hex())
fillEvent.Tokens = vLog.Topics[3]
fmt.Printf("Maker: %s\n", fillEvent.Maker.Hex())
fmt.Printf("Taker: %s\n", fillEvent.Taker.Hex())
fmt.Printf("Fee Recipient: %s\n", fillEvent.FeeRecipient.Hex())
fmt.Printf("Maker Token: %s\n", fillEvent.MakerToken.Hex())
fmt.Printf("Taker Token: %s\n", fillEvent.TakerToken.Hex())
fmt.Printf("Filled Maker Token Amount: %s\n", fillEvent.FilledMakerTokenAmount.String())
fmt.Printf("Filled Taker Token Amount: %s\n", fillEvent.FilledTakerTokenAmount.String())
fmt.Printf("Paid Maker Fee: %s\n", fillEvent.PaidMakerFee.String())
fmt.Printf("Paid Taker Fee: %s\n", fillEvent.PaidTakerFee.String())
fmt.Printf("Tokens: %s\n", hexutil.Encode(fillEvent.Tokens[:]))
fmt.Printf("Order Hash: %s\n", hexutil.Encode(fillEvent.OrderHash[:]))
case logCancelEvent.Hex():
fmt.Printf("Log Name: LogCancel\n")
var cancelEvent LogCancel
err := contractAbi.Unpack(&cancelEvent, "LogCancel", vLog.Data)
if err != nil {
log.Fatal(err)
}
cancelEvent.Maker = common.HexToAddress(vLog.Topics[1].Hex())
cancelEvent.FeeRecipient = common.HexToAddress(vLog.Topics[2].Hex())
cancelEvent.Tokens = vLog.Topics[3]
fmt.Printf("Maker: %s\n", cancelEvent.Maker.Hex())
fmt.Printf("Fee Recipient: %s\n", cancelEvent.FeeRecipient.Hex())
fmt.Printf("Maker Token: %s\n", cancelEvent.MakerToken.Hex())
fmt.Printf("Taker Token: %s\n", cancelEvent.TakerToken.Hex())
fmt.Printf("Cancelled Maker Token Amount: %s\n", cancelEvent.CancelledMakerTokenAmount.String())
fmt.Printf("Cancelled Taker Token Amount: %s\n", cancelEvent.CancelledTakerTokenAmount.String())
fmt.Printf("Tokens: %s\n", hexutil.Encode(cancelEvent.Tokens[:]))
fmt.Printf("Order Hash: %s\n", hexutil.Encode(cancelEvent.OrderHash[:]))
case logErrorEvent.Hex():
fmt.Printf("Log Name: LogError\n")
errorID, err := strconv.ParseInt(vLog.Topics[1].Hex(), 16, 64)
if err != nil {
log.Fatal(err)
}
errorEvent := &LogError{
ErrorID: uint8(errorID),
OrderHash: vLog.Topics[2],
}
fmt.Printf("Error ID: %d\n", errorEvent.ErrorID)
fmt.Printf("Order Hash: %s\n", hexutil.Encode(errorEvent.OrderHash[:]))
}
fmt.Printf("\n\n")
}
}