Skip to content

CIDv1 is not supported by Loopring Contracts #193

@ghost

Description

Issue

Loopring's API does not support CIDv1 for metadata files

Example CIDv1:

bafkreicheapqqbwjm2j46gi5kprbkfa3d2ls7kvrcyt6jeh73pem6byk4u

User Impact

  1. If a user was to use, say, https://nft.storage to upload their metadata they would only receive a CIDv1. When they then go to mint on the Loopring UI, and paste their CIDv1, the UI uses a pinata gateway to look up the metadata, read, and verify the fields are all there and also display a preview for the user. Where it falls apart is that Pinata gateways handle CIDv1 just fine, so it appears as though the mint is all good. But in reality when that NFT is then read back from the API the returned CIDv0 is incorrect because the nftID was originally derived from a CIDv1.
  2. Users can't use the latest CID standard, or move NFTs from L1 to L2 that are minted with CIDv1.
  3. The issue being present pretty much locks users into using Pinata or IPFS desktop. Pinata just changed their policy and made their free accounts even more strict than before, so it's quickly becoming a bad option for users on a budget. NFT.storage however is free and also utilizes filecoin for replication, not to mention that their single file size upload limit is 31GB.
  4. Due to (2) and (3), CAR files are much less accessible to end users.

The Quick Fix (not ideal)

Block CIDv1 from being minted in the "Advanced Mint" screen. You can do this with a simple HTML pattern attribute on the input text box.

pattern="^Qm[a-zA-Z0-9]{44}$"

The Real Solution

Support CIDv1. In other words, convert the nftID hex to CIDv1 or CIDv0, based on which was used to mint an NFT.

It's possible this is just a contract change to lines 1221 - 1271

Click to Expand Code Section
// File: contracts/external/IPFS.sol

pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;


/// @title IPFS
/// @author Brecht Devos - <[email protected]>
library IPFS
{
    bytes constant ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';

    // Encodes the 32 byte data as an IPFS v0 CID
    function encode(uint256 data)
        internal
        pure
        returns (string memory)
    {
        // We'll be always be encoding 34 bytes
        bytes memory out = new bytes(46);

        // Copy alphabet to memory
        bytes memory alphabet = ALPHABET;

        // We have to encode 0x1220data, which is 34 bytes and doesn't fit in a single uint256.
        // Keep the first 32 bytes in the uint, but do the encoding as if 0x1220 was part of the data value.
        // 0 = (0x12200000000000000000000000000000000000000000000000000000000000000000) % 58
        out[45] = alphabet[data % 58];
        data /= 58;
        // 4 = (0x12200000000000000000000000000000000000000000000000000000000000000000 / 58) % 58
        data += 4;
        out[44] = alphabet[data % 58];
        data /= 58;
        // 40 = (0x12200000000000000000000000000000000000000000000000000000000000000000 / 58 / 58) % 58
        data += 40;
        out[43] = alphabet[data % 58];
        data /= 58;

        // Add the top bytes now there is anough space in the uint256
        // This constant is 0x12200000000000000000000000000000000000000000000000000000000000000000 / 58 / 58 / 58
        data += 2753676319555676466672318311740497214108679778017611511045364661305900823779;

        // The rest is just simple base58 encoding
        for (uint i = 3; i < 46; i++) {
            out[45 - i] = alphabet[data % 58];
            data /= 58;
        }

        return string(out);
    }
}

Additional Info

Broken NFT Examples:

The issue is if I go to mint using this CID in the web wallet, I am not blocked from minting. In fact, this screen will read the metadata and display the image/name properly, leading me to believe that everything is OK. I and another user minted a few items last night this way.

image

However, after mint in both the web wallet and the explorer, these NFTs cannot be loaded.

screenshot_20220312_002532

The XHR request response is:

ipfs cat /ipfs/QmT8J4gNgfGvRYvn29NBBVdcSgUN2dA6hiGGLZ4J6EMuDE: protobuf: (PBNode) invalid wireType, expected 2, got 3
 - ERR_ID:00019

As you can see, Explorer has a CIDv0 that it is attempting to load, but it does not exist.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions