Encoding Attestation Data
Attestation data is encoded according to the Schema the Attestation is associated with. The Schema is parsed by the client reading the Attestation, in a way that results in a series of data types that can be used to abi.decode
the attestation data. In order for this to happen, the Attestation data must first be encoded using abi.encode
.
The SDK offers a much easier to encode a JSON object into attestation data. However, this information outlines the low-level steps required to encode attestation data.
Modelling a Schema as a Solidity Struct
The easiest way to think of a Schema is like a Solidity struct. Let's consider a simple Schema:
(string username, string teamname, uint16 points, bool active)
This can be thought of as a struct:
struct Profile {
string username;
string teamname;
uint16 points;
bool active;
}
If we were to encode an attestation that references this schema, we could do it client side using the ethers library (or equivalent):
const encodedStruct = ethers.utils.defaultAbiCoder.encode(
['string', 'string', 'uint16', 'bool'],
['bojo','torries', 3, false]
);
This can later be decoded by some off-chain client, with the subgraph, or by another on-chain contract using Solidity:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract StructDecodingExample {
struct Profile {
string username;
string teamname;
uint16 points;
bool active;
}
function receiveEncodedStruct(
bytes memory encodedStruct
) public pure returns (gamer memory) {
Profile memory gamer;
// Decode the struct using abi.decode
(gamer.username, gamer.teamname, gamer.points, gamer.active) = abi.decode(encodedStruct, (string, string, uint16, bool));
return gamer;
}
}
Encoding Nested Data
Sometimes a schema is a bit more complicated, in that it contains more than just a flat data structure, and may contain nested data structure like so:
(string username, string teamname, uint16 points, bool active, ( string gametype, string gamemode ) preferences)
Which can be thought of as this nested struct:
struct Preferences {
string gametype;
string gamemode;
}
struct Profile {
string username;
string teamname;
uint16 points;
bool active;
Preferences setup;
}
Again, encoding the attestation for this schema using a client side library such as ethers would look like this:
const encodedStruct = ethers.utils.defaultAbiCoder.encode(
['string', 'string', 'uint16', 'bool', 'tuple(string gametype, string gamemode)'],
['bojo','torries', 3, false, {gametype: 'RPG', gamemode: 'multiplayer'}]
);
Encoding Arrays
Encoding arrays within attestation data is also straightforward, let's use the example before, but with arrays:
(string username, string teamname, uint16 points, bool active, ( string[] gametype, string[] gamemode ) preferences)
Which can be thought of as this nested struct:
struct Preferences {
string[] gametype;
string[] gamemode;
}
struct Profile {
string username;
string teamname;
uint16 points;
bool active;
Preferences setup;
}
Again, encoding the attestation for this schema using a client side library such as ethers would look like this:
const encodedStruct = ethers.utils.defaultAbiCoder.encode(
['string', 'string', 'uint16', 'bool', 'tuple(string[] gametype, string[] gamemode)'],
['bojo','torries', 3, false, {gametype: ['RPG', 'first-person-shooter', 'racing'], gamemode: ['multiplayer', 'singleplayer'] }]
);
Last updated