Search code examples
ipfsfilecoin

Compute CID of data in Go


I need to compute the CID of some data in Golang, right now I'm using this code, but the CID I receive is different than what I get when I upload the file to Filecoin or add it to a Lotus node.

This is my code:

"github.com/ipfs/go-cid"
ma "github.com/multiformats/go-multiaddr"
mh "github.com/multiformats/go-multihash"

func Cid(data []byte) {
    hash, err := mh.Sum(data, mh.SHA2_256, -1)
    if err != nil {
        panic(err)
    }

    c, err := cid.V1Builder{Codec: cid.DagProtobuf, MhType: mh.SHA2_256, MhLength: -1}.Sum(hash)

    fmt.Println("Filecoin CID:", c.String())
}

If I have a file with the content Hello, the above function prints the following cid: bafybeievjvim3p2qexhlxek5yqftxsizm6fx2mtrgrsyfx43f52sozkwga If I add it to Lotus, or upload to Filecoin I get: bafkreiayl6g3gitr7ys7kyng7sjywlrgimdoymco3jiyab6rozecmoazne

I would like to have a function that returns me the same CID.



Solution

  • I figured it out, I had to chunk the data as well. My updated code is below. If I now upload the same file to Filecoin I get the same CID.

     import (
         "bytes"
         "fmt"
         "io"
         "os"
         "github.com/ethereum/go-ethereum/common"
         chunker "github.com/ipfs/boxo/chunker"
         "github.com/ipfs/go-cid"
         "github.com/libp2p/go-libp2p/core/host"
         mh "github.com/multiformats/go-multihash"
    )
    
    func Cid(data []byte) {
    // Create an IPLD UnixFS chunker with size 1 MiB
    chunks := chunker.NewSizeSplitter(bytes.NewReader(data), 1024*1024)
    
    // Concatenate the chunks to build the DAG
    var buf bytes.Buffer
    for {
        chunk, err := chunks.NextBytes()
        if err == io.EOF {
            break
        } else if err != nil {
            panic(err)
        }
    
        buf.Write(chunk)
    }
    
    // Calculate the CID for the DAG
    hash, err := mh.Sum(buf.Bytes(), mh.SHA2_256, -1)
    if err != nil {
        panic(err)
    }
    
    // Create a CID version 1 (with multibase encoding base58btc)
    c := cid.NewCidV1(cid.DagProtobuf, hash)
    
    // Print the CID as a string
    fmt.Println("IPFS CID in Golang:", c.String())
    }