Skip to content

Instantly share code, notes, and snippets.

@crazygit
Last active April 26, 2022 08:48
Show Gist options
  • Save crazygit/55f539626be6557f9db7d1c010fcd694 to your computer and use it in GitHub Desktop.
Save crazygit/55f539626be6557f9db7d1c010fcd694 to your computer and use it in GitHub Desktop.

Revisions

  1. crazygit revised this gist Apr 26, 2022. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion go-ethereum-read-event.go
    Original file line number Diff line number Diff line change
    @@ -227,7 +227,10 @@ func main() {
    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)
    @@ -251,7 +254,7 @@ func main() {
    }
    fmt.Printf("inputs: %v\n", inputs)

    // method 3: decode by event inputs into map
    // 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 {
  2. crazygit revised this gist Apr 26, 2022. 1 changed file with 21 additions and 0 deletions.
    21 changes: 21 additions & 0 deletions go.mod
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    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
    )
  3. crazygit created this gist Apr 26, 2022.
    267 changes: 267 additions & 0 deletions go-ethereum-read-event.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,267 @@
    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 3: 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")
    }

    }