How to save CIDv1 in bytes32 solidity?

Hello.

How to save CIDv1 in bytes32 solidity? How to CIDv1 convert to bytes32?

CIDv0 to bytes32:

ethers.utils
            .hexlify(
              ethers.utils.base58
                .decode("QmewVYx1r9drCsf9mjuty8R67tLjQhBQjBvSqyb4xxD1z3")
                .slice(2)
            )

Why are you using ether js to do that ?
Just use the GitHub - multiformats/js-multiaddr: JavaScript implementation of multiaddr lib.

Thanks for your reply.
How can I get the address to be 32 bytes?

CIDv1: bafybeihwu73nw6cee4e4m6pdhnh4ll5p425ythu7efyvgejrytzi2fewlq

CID are not 32 bytes and you cannot assume they are.
I belive you got confused with base32 (which means that there are 5 bits per character encoded).

If you care about optimising space, you can use binary or identity CIDs.
(the difference is that identity CID have a null byte in front to be multibase decodable, most of our protocols internally use binary CIDs)

But even binary CIDs are variable length (which is above 32 bytes most of the time).

Thanks for your reply.

I understand that only CIDv0 I can save in bytes32, I can’t save CIDv1 in any way?

ethers.utils.base58
  .decode("QmewVYx1r9drCsf9mjuty8R67tLjQhBQjBvSqyb4xxD1z3")
  .slice(2)

Binary CIDv0 is not 32 bytes but 34.

I remove the prefix Qm and it is placed in bytes32.

ethers.utils
    .hexlify(
        ethers.utils.base58
            .decode("QmewVYx1r9drCsf9mjuty8R67tLjQhBQjBvSqyb4xxD1z3")
            .slice(2)
    )
// Save to blockchain bytes32
//=> 0xf6a7f6db78442709c679e33b4fc5afafe6bb899e9f2171531131c4f28d14965c
ethers.utils.base58.encode(
    Buffer.from("1220" + "0xf6a7f6db78442709c679e33b4fc5afafe6bb899e9f2171531131c4f28d14965c".slice(2), "hex")
)
// Get address from blockchain
//=> QmewVYx1r9drCsf9mjuty8R67tLjQhBQjBvSqyb4xxD1z3

oh ok so, doing that effectively you are just storing the sha256 digest.

I mean …
We worked on a future proof solution, it supports cbor, json, raw, protobuf, future formats that doesn’t exists (we just have to add them).

Many hash functions blake2, sha3, Poseidon hash, … in various sizes (256 bits, 512, …).

And you are saying “I want to use sha256 dag-pb FOREVER.”

FYI we are probably gonna enable --raw-leaves by default in go-ipfs v.14 or v.15, which aren’t compatible with your hack because they require full CIDv1 (since they have a different codec (raw) instead of dag-pb).

(I also want to remind that dag-pb is hacks on top of hacks, we are somewhat moving towards cbor + raw instead)

If you don’t mind using something incompatible with the next version of IPFS. You can just store the digest yes.

1 Like

I know solidity people have a thing for using as less SSTORE possible.
But this solution sounds terrible.

What I would do instead is truncate the hash to 28~26 bytes (we do support using truncated hashes).
So adding the ~4 bytes (depends whats it is encoding, some codecs are bigger) header bump it to 32bytes.

To do that, you just have to set a smaller size in the CIDv1 mh length field.
And you just store this as a binary CID.

Realistically 28 bytes SHA256 is only 2**32 times less secure, which is probably still fine (and since you are using CIDv1 you could use SHA3 if you cared about compensating somewhat).

1 Like

Thanks for your reply.

If I keep using CIDv0 is that a good idea? Everything works fine for me and the Pinata Cloud service gives exactly the CIDv0 address after sending the file.

I’m just afraid that sooner or later CIDv0 may be removed from IPFS? Or am I worried for nothing?

There is no plan to remove it.

What is gonna happen is that we are gonna (probably) enable new features that are CIDv1 exclusive (by default, thoses features already exists).

1 Like