Proof of Integrity

We publicly introduced the concept of Proof of Integrity along with our first release of PSA Graded Pokémon cards as Connected Collectibles. In short, a Proof of Integrity acts like a tamper-proof seal and establishes that every Courtyard NFT is provably linked to a unique matching physical item stored in our vaults. If someone tries to alter the NFT's fingerprint (i.e. its identity), the Proof of Integrity will show that the token is corrupted.

1. Item identity and fingerprints

Every item that is stored at Courtyard is identified by an accurate, human readable description and a unique ID. While the description allows anyone to quickly identify the item visually, the unique ID brings further differentiation when we store multiple copies of the same item. Some items, like graded caards, already have a unique ID imprinted on them. WHen an item does not already have a unique identifier, we create one for it and include it on the IRL picture of the item that is associated with the NFT. The accurate description of the asset and the unique ID are used together to form the fingerprint of the asset, which is both unique and human readable at the same time:

Graded Pokemon TCG | PSA 23303316 | 1999 Pokemon Base Set Shadowless 1st Edition Red Cheeks Pikachu #58 | PSA 9 MINT

Before storing an asset, we always take a picture of it and make sure that the unique ID that differentiates it from other similar items is shown in the picture, and we include a link to that picture in the metadata of the NFT, along with the 3D rendering:

2. From a fingerprint to a Proof of Integrity

Because the fingerprint of an item has an arbitrary length, we encode it using a cryptographic function called keccak256, which is widely used on the Ethereum blockchain as a standard way to securely encode sensitive data. The result of this encoding is what we call the Proof of Integrity. It is a string starting with 0x, followed by 64 hexadecimal characters that uniquely represents the corresponding physical item:

0x0b58386d08014f001c1a37ca6b11afd2f3f3e3a578e69a8ed7e7acf68103258e

The on-chain function that is used to calculate the Proof of Integrity is the following:

/**
 * @dev Generates a Proof Of Integrity as the keccak256 hash of a {fingerprint} and a {salt} value.
 *  - the fingerprint is a unique, human readable description of an item.
 *  - the salt value is a random number used to bring some further functionalities, like creating NFTs that can provably exist but remain "unrevealed" until the salt value is made public.
 */
function generateProofOfIntegrity(string memory fingerprint, uint256 salt) public pure returns (bytes32) {
    return keccak256(abi.encodePacked(fingerprint, salt));
}

A useful property of the keccak256 function is that if the fingerprint changes by a single character, the resulting Proof of Integrity would be a completely different value, that has nothing to do with the original one. This is how we can tell if a fingerprint has been altered.

A useful property of the keccak256 function is that if the fingerprint changes by a single character, the resulting Proof of Integrity would be a completely different value, that has nothing to do with the original one. This is how we can tell if a fingerprint has been altered.

In addition to the human readable fingerprint, we also use a salt value when generating the Proof of Integrity. The salt is a random number that we use to prevent people from reverse-engineering a fingerprint from a Proof of Integrity when we organize events such as drops with sealed packs, where we're making the Proof of Integrity of each pack public, but want to keep the actual fingerprint hidden until the pack is open.

Example:

FingerprintProof of Integrity (using salt = 834659742360)

Graded Pokemon TCG | PSA 23303316 | 1999 Pokemon Base Set Shadowless 1st Edition Red Cheeks Pikachu #58 | PSA 9 MINT

0x0b58386d08014f001c1a37ca6b11afd2f3f3e3a578e69a8ed7e7acf68103258e

graded Pokemon TCG | PSA 23303316 | 1999 Pokemon Base Set Shadowless 1st Edition Red Cheeks Pikachu #58 | PSA 9 MINT

0x3533294d06d102c4e6c1c93b28d4dd9cfb62c80111053363950af2af9eebdd91

3. How does a Proof of Integrity relate to an NFT?

Once we obtained the Proof of Integrity of an item, we can use it to generate the corresponding NFT. We create the NFT using the Proof of Integrity as its token ID.

But wait... aren't token IDs on Ethereum numbers, and not hexadecimal strings?

Exactly! And this is where something special happens. We already established that a Proof of Integrity is a unique hexadecimal value of 64 characters. However, hexadecimal values are nothing more than numbers encoded in a way to save space on a computer. And as such, to every hexadecimal value corresponds an actual decimal number. For instance, the following hexadecimal value:

0x0b58386d08014f001c1a37ca6b11afd2f3f3e3a578e69a8ed7e7acf68103258e

corresponds to the very long number:

5131313313389071742384083343855484226773370949666220711435372176261821703566

We store that number on-chain and use as the token ID of the NFT.

The tokenId and the Proof of Integrity are the same thing, just written differently. An NFT's token ID corresponds exactly to a Proof of Integrity that identifies a unique physical item stored at Courtyard, and vice-versa.

4. How is this tamperproof, and why does it matter?

On the blockchain side, it is well established that the token ID of an NFT, once recorded on-chain, is there to stay forever, unchanged. However, we cannot say as much of the metadata of that NFT, which may or may not be stored in decentralized storage, and may or may not be subject to evolve over-time, either because the creators of the NFT want to regularly provide a richer experience to the holder of the NFT, or because a malicious actor came and was able to alter the metadata and completely change the nature of the NFT.

The Proof of Integrity is Courtyard's way of making the NFT really tamperproof by using the 3 following properties:

  • Once an NFT's token ID is recorded on-chain, it will never change.

  • A Proof of Integrity of an NFT is exactly the same thing as its token ID, and so it will never change either.

  • The unique, human readable fingerprint of a physical asset stored with Courtyard corresponds exactly to the Proof of Integrity, and only that fingerprint corresponds to it.

Together, these 3 properties ensure that if the metadata changes as the result of a malicious attack to alter the identity of the underlying physical asset, the seal of integrity will be "broken", meaning that the Proof of integrity will invalidate the NFT.

Last updated