VC output example introduction

VC Structure

The Verifiable Credential (VC) output in JSON format is generated by the Litentry sidechain worker based on the returned data from the DynamicAssertion smart contract.

Example VC JSON

Below is an example VC JSON of token holding amount contract for token Bean:

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
    ],
    "id": "0x5f18937abbe9a499b79a3751aaaba8cd8d6c89ddbe680f61e96388c26abba0fb",
    "type": ["VerifiableCredential"],
    "credentialSubject": {
        "id": "did:litentry:evm:0x651614ca9097c5ba189ef85e7851ef9cff592b2c",
        "description": "The amount of a particular token you are holding",
        "type": "Token Holding Amount",
        "assertionText": "",
        "assertions": [
            {
                "and": [
                    {
                        "src": "$token",
                        "op": "==",
                        "dst": "bean"
                    },
                    {
                        "and": [
                            {
                                "src": "$network",
                                "op": "==",
                                "dst": "Bsc"
                            },
                            {
                                "src": "$network",
                                "op": "==",
                                "dst": "Combo"
                            }
                        ]
                    },
                    {
                        "src": "$holding_amount",
                        "op": ">=",
                        "dst": "0"
                    },
                    {
                        "src": "$holding_amount",
                        "op": "<",
                        "dst": "1"
                    }
                ]
            }
        ],
        "values": [false],
        "endpoint": "http://localhost:9933"
    },
    "issuer": {
        "id": "did:litentry:substrate:0xd1903fbb8a5cac3de73c70f33a980e41b938e9a0193f71c353019fd27626d40d",
        "name": "Litentry TEE Worker",
        "mrenclave": "AjXWy3vvBSknZJf6NBQ3yV1LriVZQ2DAXEfEgFf5DTjV",
        "runtimeVersion": {
            "parachain": 9183,
            "sidechain": 109
        }
    },
    "issuanceDate": "2024-10-01T00:00:00.000000000+00:00",
    "parachainBlockNumber": 69,
    "sidechainBlockNumber": 131,
    "proof": {
        "created": "2024-10-01T00:00:00.000000000+00:00",
        "type": "Ed25519Signature2020",
        "proofPurpose": "assertionMethod",
        "proofValue": "6aa3d2f00665e61b2d1e8b0eeb621be27abbd54815f4a2dd27a3098d34055c39983b70a4304a3aa10a208def548f581fb0a7f0adf6d8eb17a4c212c55ab0d003",
        "verificationMethod": "0xa2ff08c95ffb86ae1eeb7b35582f0d2b6bfc6775cd780c4b03f58f72ec6c95f8"
    },
    "credentialSchema": {
        "id": "https://raw.githubusercontent.com/litentry/vc-jsonschema/main/dist/schemas/25-token-holding-amount/1-1-0.json",
        "type": "JsonSchemaValidator2018"
    }
}

VC Output Components Mapping

The VC output fields are mapped to the return values of the DynamicAssertion.execute function as follows:

  • credentialSubject.description: returnValue[0]

  • credentialSubject.type: returnValue[1]

  • credentialSubject.assertions: returnValue[2]

  • credentialSubject.values[0]: returnValue[4]

  • credentialSchema.id: returnValue[3]

To generate the VC JSON shown in the example, the corresponding return values from the DynamicAssertion.execute function should be:

string[] memory assertions = new string[](1);
assertions[0] = "[{"and":[{"src":"$token","op":"==","dst":"bean"},{"and":[{"src":"$network","op":"==","dst":"Bsc"},{"src":"$network","op":"==","dst":"Combo"}]},{"src":"$holding_amount","op":">=","dst":"0"},{"src":"$holding_amount","op":"<","dst":"1"}]}]";
string memory schemaUrl = "https://raw.githubusercontent.com/litentry/vc-jsonschema/main/dist/schemas/25-token-holding-amount/1-1-0.json";

return (
    "The amount of a particular token you are holding", // returnValue[0] -> credentialSubject.description
    "Token Holding Amount",                             // returnValue[1] -> credentialSubject.type
    assertions,                                         // returnValue[2] -> credentialSubject.assertions
    schemaUrl,                                          // returnValue[3] -> credentialSchema.id
    false                                               // returnValue[4] -> credentialSubject.values[0]
);

DynamicAssertion.execute Definition

The DynamicAssertion.execute function defines how the credential information is generated. Below is its contract definition:

abstract contract DynamicAssertion {
    string schema_url;

    function execute(
        Identity[] memory identities,
        string[] memory secrets,
        bytes memory params
    )
        public
        virtual
        returns (
            string memory description,         // returnValue[0]
            string memory type,                // returnValue[1]
            string[] memory assertions,        // returnValue[2]
            string memory schemaUrl,           // returnValue[3]
            bool value                         // returnValue[4]
        );
}

Why Add the $network Clause in Assertions?

In the token holding amount contract, a single token may be available on multiple blockchain networks. Adding the $network clause surface which networks the current contract calculates.

For example, if Token A is available on BSC, Combo, and Ethereum, but the current contract only supports BSC and Combo, you would include only BSC and Combo in the $network clause. This ensures that the assertion accurately reflects the supported networks for that specific contract implementation.

Last updated