1

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

7
  • what do you mean by tried to slice it as an array and what is the error you are getting during compilation?
    – Nulik
    Commented Sep 8, 2018 at 19:40
  • As in tried to slice it as a byte array so fmt.Println( string(vLog[:]) ) but it is of type types.Log
    – Gizzard
    Commented Sep 9, 2018 at 1:26
  • I don't understand you at all, but by the subject of your question I guess you are looking for something like this: topics,err:=json.Marshal(vlog.Topics) or data,err:=json.Marshal(vlog.Data) . Its more readable
    – Nulik
    Commented Sep 9, 2018 at 17:02
  • Not sure why you dont understand. The format is in bytes id like to convert it to a more readable/friendly format... i.e either string, int or hex
    – Gizzard
    Commented Sep 10, 2018 at 13:51
  • to encode bytes in hex use hex.EncodeToString(byte_slice) , import module encoding/hex
    – Nulik
    Commented Sep 10, 2018 at 19:40

1 Answer 1

1

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

2
  • vLog.Data can be anything , only the contract knows what is contained in it. Here you are assuming it is a 32 byte long key and value contained in a struct
    – Nulik
    Commented Sep 16, 2018 at 15:09
  • 1
    There's no assumption because key and value are 32 bytes long as per the event log definition in OP's smart contract in the question
    – Miguel
    Commented Sep 16, 2018 at 16:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.