Attestation schema
Onchain Passports use Attestations to verify that a particular address owns specific Stamps. Ultimately, an Attestation is just a piece of data with a cryptographic signature.
The data follows a known structure, known as a 'schema'. The schema is critical because it ensures the signing participant knows what they are signing, and provides a uniform data layout that enables users to decode the Attestations.
The schema is the layout of information being attested. The signature is the proof that a known, trusted verifier has seen the data and attested that it is truthful.
There are two attestations that are issued when users mint their Passports onchain, both of which are described below:
- Passport (Stamp) attestation
- Score attestation
Passport (Stamp) attestation schema
Overview
The raw schema looks as follows:
uint256[] providers, bytes32[] hashes, uint64[] issuanceDates, uint64[] expirationDates, uint16 providerMapVersion
Notice that the types for all these fields are numerical types or raw bytes. This is because the human-readable information is compressed and encoded before being added to the attestation.
You can see an example of a Stamp attestation on the Optimism network by visiting the following link:
Example Passport (Stamp) attestation on Optimism (opens in a new tab)
Fields
The fields are as follows:
providers
: a u256 that is actually a bitmap where each position maps to a provider name. The mapping is made available offchain.hashes
: an ordered array of elements, with each element being 32 raw bytes. Each element in the array is a 32-byte hash that maps to a known Stamp. A provider might have multiple Stamps that each have a hash. The mapping is made available offchain.issuanceDates
: an ordered array of elements, with each element being 32 raw bytes. Each element represents the UNIX timestamp when the Stamp was verified.expirationDates
: an ordered array of elements, with each element being 32 raw bytes. Each element represents the UNIX timestamp when the Stamp expires.providerMapVersion
: an unsigned integer specifying which version of theproviders
mapping the Attestation conforms to. This allows updates as providers are added and removed from the canonical set.
Score attestation schema
The raw schema looks as follows:
uint256 score, uint32 scorer_id, uint8 score_decimals
You can see an example of a score attestation on the Optimism network by visiting the following link:
Example score attestation on Optimism (opens in a new tab)
Fields
The fields are as follows:
score
: the user's Passport score as an unsigned integerscorer_id
: the ID number for the specific Scorer instance that issued thescore
score_decimals
: number of decimals inscore
, similar to how ETH is divided into 1e18 Wei.
Decoding Attestations
The schema is used to encode and decode Attestations.
From a raw attestation, you can extract the data that belongs to each field in the schema using an ABI decode method (such as abi.decode
in Solidity, abiCoder.decode()
in Ethers, etc) as follows:
// Decode the attestion output
(providers, hashes, issuanceDates, expirationDates, providerMapVersion) = abi.decode(
attestation.data,
(uint256[], bytes32[], uint64[], uint64[], uint16)
);
You then need to apply some logic to the decoded data to extract actionable insights.
For example, you should extract the position indexes of each 1
value in the providers
bitmap, then look up the Providers
at those same indexes in the providers mapping, found on the Passport Github (opens in a new tab).
You may also wish to extract each value from hashes
and find the matching entry in the Stamps mapping to determine which specific Stamps the Attestation contains.
Similarly, you can determine the current time and check whether it is before or after the expirationDates
for each Stamp.
You can see an example of how to do this in a Nextjs app in our onchain Passports tutorial.
Note if you have more questions about the Attestation schema, you can chat in our developer support channel on Telegram (opens in a new tab).