[Ethereum] Golang How to slice Ethereum log events from smart contract to a more readable format

ethereum-wallet-dappgo-ethereumgolang

Im looking to use a channel to watch contract log events but the output returns a byte array like this

the go code i am using looks like this

        package main

        import (
            "context"
            "fmt"
            "log"

            "github.com/ethereum/go-ethereum"
            "github.com/ethereum/go-ethereum/common"
            "github.com/ethereum/go-ethereum/core/types"
            "github.com/ethereum/go-ethereum/ethclient"
        )


        func main() {
            client, err := ethclient.Dial("wss://rinkeby.infura.io/ws")
            if err != nil {
                log.Fatal(err)
            }

            contractAddress := common.HexToAddress("0x0337da4ac39966a3acff66b281472ba91762045b")
            query := ethereum.FilterQuery{
                Addresses: []common.Address{contractAddress},
            }

            logs := make(chan types.Log)
            sub, err := client.SubscribeFilterLogs(context.Background(), query, logs)
            if err != nil {
                log.Fatal(err)
            }

            for {
                select {
                case err := <-sub.Err():
                    log.Fatal(err)
                case vLog := <-logs:
                    fmt.Println(s)
                    fmt.Println(vLog) 
                }
            }
        }

and the smart contract is put together as follows

    pragma solidity ^0.4.24;

    contract Store {

        event ItemSet(bytes32 key, bytes32 value);

        string public version;

        mapping (bytes32 => bytes32) public items;

        constructor(string _version) public {
            version = _version;
        }

        function setItem(bytes32 key, bytes32 value) external {
            items[key] = value;
            emit ItemSet(key, value);
        }

    }

and the output from the go script is like this but id like it to be more readable and friendly.


{[3 55 218 74 195 153 102 163 172 255 102 178 129 71 43 169 23 98 4 91] [[231 158 115 218 65 119 16 174 153 170 32 136 87 85 128 166 4 21 211 89 172 250 217 205 211 56 45 89 200 2 129 212]] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 116 101 115 116 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 116 101 115 116] 2953868 [98 220 227 61 110 2 130 66 120 56 30 32 186 128 34 184 128 50 201 124 70 143 210 120 186 145 138 210 219 237 228 72] 7 [11 61 192 53 238 180 252 64 240 177 48 148 54 226 100 165 7 106 118 111 45 182 231 244 52 103 175 51 192 94 97 250] 6 false}

I tried to slice it as an array but i get the error Cannot slice types.Log which seems to be defined in here https://github.com/ethereum/go-ethereum/blob/master/core/types/log.go

Best Answer

You need to Unpack the log data

Example:

// `store` is the imported contract compiled into a Go package with abigen
contractAbi, err := abi.JSON(strings.NewReader(string(store.StoreABI)))
if err != nil {
    log.Fatal(err)
}

event := struct {
    Key   [32]byte
    Value [32]byte
}{}
err := contractAbi.Unpack(&event, "ItemSet", vLog.Data)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(event.Key[:]))   // foo
fmt.Println(string(event.Value[:])) // bar

Full example here

Related Topic