Solidity

There are many reasons you may want to generate an attestation on behalf of a wallet interacting with your smart contract. However, this cannot be done without the wallet approving (signing) the attestation your smart contract is creating on their behalf. Signatures must be initiated from the frontend and forwarded to your smart contract to create the delegate attestation. Depending on your use case, it may make sense to generate the attestation object on the frontend, or you may need to generate it from the smart contract through a getter. For this tutorial, we will assume that the attestation is generated on the frontend, but we have examples here to show how to create an attestation object in Solidity.

We will start with an empty solidity contract. We will need to import ISP and Attestation from @ethsign/sign-protocol-evm.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ISP } from "@ethsign/sign-protocol-evm/src/interfaces/ISP.sol";
import { Attestation } from "@ethsign/sign-protocol-evm/src/models/Attestation.sol";

contract DelegateAttest is Ownable {
    constructor() Ownable(_msgSender()) { }
}

We will keep track of the Sign Protocol contract address. Create state variables and helper functions to set these values. This variable will need to be set based on the network you deploy your contract on, which can be found here. Your contract should now look something like the following:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ISP } from "@ethsign/sign-protocol-evm/src/interfaces/ISP.sol";
import { Attestation } from "@ethsign/sign-protocol-evm/src/models/Attestation.sol";

contract DelegateAttest is Ownable {
    ISP public spInstance;

    constructor() Ownable(_msgSender()) { }

    function setSPInstance(address instance) external onlyOwner {
        spInstance = ISP(instance);
    }
}

Create a function to handle delegate attestation creation. We will pass in the attestation object, indexing value, delegation signature, and extra data to mimic the Sign Protocol attest function, however, you can modify these parameters if you wish to hardcode the indexing value or extra data. The attestation object and delegation signature are required to create an attestation using delegation methods.

...
function createAttestation(Attestation calldata att, string calldata indexingKey, bytes calldata delegationSignature, bytes calldata extraData) external returns (uint64) {
    uint64 attestationId = spInstance.attest(att, indexingKey, delegationSignature, extraData);
    return attestationId;
}
...

(Frontend) Generating a Delegation Signature

This section must be implemented on your frontend. Delegation signatures are a mechanism to allow a third party to upload an attestation on behalf of an attester. The attester must approve (sign) the attestation that is being created to prevent fraudulent attestations. In other words, you would not want someone making attestations using your wallet address without you approving the attestation content first - unapproved attestations could pose a major security threat. After attaining a signature from the user/attester, the attestation and signature can be sent to the backend we wrote above. Your frontend code should include the following:

import {
  EvmChains,
  delegateSignAttestation
} from "@ethsign/sp-sdk";

const schemaId = "0x...";
const attestationData = {
  ...
};
const indexingValue = "0x...";
const extraData = "0x...";

const res = await delegateSignAttestation(
  {
    schemaId: schemaId,
    data: attestationData,
    indexingValue: indexingValue
  },
  { chain: EvmChains.sepolia }
);

const response = await yourSmartContract.createAttestation(res.attestation, indexingValue, res.delegationSignature, extraData);

...

// You can now use `response` for anything you need in your frontend code

Recap

The general flow to create a delegated attestation using a backend is the following:

  1. Generate the attestation content. This can be done on the frontend (as shown above) or from your smart contract (and requested by the frontend for step 2).

  2. Request a delegation signature from the user in a browser.

  3. Pass in the attestation and delegation signature to your smart contract.

  4. Create the attestation in your smart contract, providing the attestation and delegation signature.

Last updated

Logo

Copyright Sign 2021-2024