Last active
April 26, 2022 08:48
-
-
Save crazygit/55f539626be6557f9db7d1c010fcd694 to your computer and use it in GitHub Desktop.
read contract event with go ethereum
This file contains hidden or 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" | |
"github.com/ethereum/go-ethereum" | |
"github.com/ethereum/go-ethereum/accounts/abi" | |
"github.com/ethereum/go-ethereum/common" | |
"log" | |
"math/big" | |
"strings" | |
"github.com/ethereum/go-ethereum/ethclient" | |
) | |
const rawABI = ` | |
[ | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "from", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "amount", | |
"type": "uint256" | |
} | |
], | |
"name": "FallbackEvent", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "previousOwner", | |
"type": "address" | |
}, | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "newOwner", | |
"type": "address" | |
} | |
], | |
"name": "OwnershipTransferred", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "from", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "amount", | |
"type": "uint256" | |
} | |
], | |
"name": "ReceiveEvent", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "receiver", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "amount", | |
"type": "uint256" | |
} | |
], | |
"name": "WithDrawEvent", | |
"type": "event" | |
}, | |
{ | |
"stateMutability": "payable", | |
"type": "fallback" | |
}, | |
{ | |
"inputs": [], | |
"name": "destory", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "getBalance", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "owner", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "renounceOwnership", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "newOwner", | |
"type": "address" | |
} | |
], | |
"name": "transferOwnership", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address payable", | |
"name": "receiver", | |
"type": "address" | |
}, | |
{ | |
"internalType": "uint256", | |
"name": "amount", | |
"type": "uint256" | |
} | |
], | |
"name": "withDraw", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"stateMutability": "payable", | |
"type": "receive" | |
} | |
] | |
` | |
const ropstenHttpsEndpoint = "https://ropsten.infura.io/v3/77a8f7b1379d440b8c06e82f37d05657" | |
const ropstenFaucetContractAddress = "0xf1EEfEE62A8651c3772cd8D7ba9031b7029316f7" | |
const blockNumber = 12218203 | |
func main() { | |
contractAbi, err := abi.JSON(strings.NewReader(rawABI)) | |
if err != nil { | |
log.Fatal(err) | |
} | |
// get abi events info | |
for _, event := range contractAbi.Events { | |
fmt.Printf("Event Name: %s\n", event.Name) | |
fmt.Printf("Event ID: %s\n", event.ID) | |
fmt.Printf("Event RawName: %s\n", event.RawName) | |
fmt.Printf("Event Sig: %s\n", event.Sig) | |
for index, input := range event.Inputs { | |
fmt.Printf("input %d, Name: %s, Type:%s, indexed: %t\n", index, input.Name, input.Type, input.Indexed) | |
} | |
} | |
client, err := ethclient.Dial(ropstenHttpsEndpoint) | |
if err != nil { | |
log.Fatal(err) | |
} | |
contractAddress := common.HexToAddress(ropstenFaucetContractAddress) | |
blockLimit := big.NewInt(blockNumber) | |
query := ethereum.FilterQuery{ | |
FromBlock: blockLimit, | |
ToBlock: blockLimit, | |
Addresses: []common.Address{contractAddress}, | |
} | |
// query contract event in block 12218203 | |
logs, err := client.FilterLogs(context.Background(), query) | |
if err != nil { | |
log.Fatal(err) | |
} | |
// parse logs | |
for _, vLog := range logs { | |
fmt.Printf("Log Block Number: %d\n", vLog.BlockNumber) | |
fmt.Printf("TxHash: %s\n", vLog.TxHash) | |
fmt.Printf("Topics[0]: %s\n", vLog.Topics[0].Hex()) | |
// Topic[0] is the event signature hash value | |
// equals to | |
// logWithDrawEventSig := []byte("WithDrawEvent(address,uint256)") | |
// logWithDrawEventSigHash := crypto.Keccak256Hash(logWithDrawEventSig) | |
switch vLog.Topics[0] { | |
case contractAbi.Events["WithDrawEvent"].ID: | |
fmt.Printf("Log Name: WithDrawEvent\n") | |
// 解析所有Topic的信息 | |
for index := range vLog.Topics { | |
fmt.Printf("topic %d: %s\n", index, vLog.Topics[index].Hex()) | |
} | |
// ==================================== | |
// decode event log data | |
// ==================================== | |
// method 1: | |
data, errUnpack := contractAbi.Unpack("WithDrawEvent", vLog.Data) | |
if errUnpack != nil { | |
log.Fatal(errUnpack) | |
} | |
fmt.Printf("data: %s\n", data) | |
// method 2: decode to map | |
dataMap := make(map[string]interface{}) | |
err = contractAbi.UnpackIntoMap(dataMap, "WithDrawEvent", vLog.Data) | |
if err != nil { | |
log.Fatal(err) | |
} | |
fmt.Printf("dataMap: %v\n", dataMap) | |
// method 3: decode by event inputs | |
inputs, unpackValuesErr := contractAbi.Events["WithDrawEvent"].Inputs.UnpackValues(vLog.Data) | |
if unpackValuesErr != nil { | |
log.Fatal(unpackValuesErr) | |
} | |
fmt.Printf("inputs: %v\n", inputs) | |
// method 4: decode by event inputs into map | |
inputsMap := make(map[string]interface{}) | |
err := contractAbi.Events["WithDrawEvent"].Inputs.UnpackIntoMap(inputsMap, vLog.Data) | |
if err != nil { | |
log.Fatal(err) | |
} | |
fmt.Printf("inputsMap: %v\n", inputsMap) | |
} | |
fmt.Printf("\n\n") | |
} | |
} |
This file contains hidden or 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
module ReadContractEvent | |
go 1.18 | |
require github.com/ethereum/go-ethereum v1.10.17 | |
require ( | |
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect | |
github.com/btcsuite/btcd/btcec/v2 v2.1.2 // indirect | |
github.com/deckarep/golang-set v1.8.0 // indirect | |
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect | |
github.com/go-ole/go-ole v1.2.1 // indirect | |
github.com/go-stack/stack v1.8.0 // indirect | |
github.com/gorilla/websocket v1.4.2 // indirect | |
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect | |
github.com/tklauser/go-sysconf v0.3.5 // indirect | |
github.com/tklauser/numcpus v0.2.2 // indirect | |
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect | |
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 // indirect | |
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is how to parse contract log event info with the latest
go-ethereum
(v1.10.17).The contract is deploy by on ropsten faucet website and the query log event is under https://ropsten.etherscan.io/tx/0x488561fb7a18bdc4627f6be2bbf3b660520ace7a5dad1de5ef1b693c6eeaf168#eventlog
Here is the output