Skip to content

Latest commit

 

History

History
323 lines (212 loc) · 11.5 KB

badges.md

File metadata and controls

323 lines (212 loc) · 11.5 KB

Badges

This section introduces the basic concepts of Canvas badges. For jumping into code examples, see Badge Examples.

What is a badge?

Each Canvas badge is an EAS attestation, with some additional logic attached to it.

The badge attestation uses the official Scroll Canvas schema (see BADGE_SCHEMA in Deployments). This means that the badge data contains two fields: address badge, bytes payload, and badges are issued through the official Canvas badge resolver contract.

How to implement a new badge?

Each badge must implement a certain interface to ensure it is compatible with Canvas. In particular, each badge must implement 3 APIs (see IScrollBadge):

  • issueBadge: Implement arbitrary logic that is triggered when a new badge is created.
  • revokeBadge: Implement arbitrary logic that is triggered when a badge is revoked.
  • badgeTokenURI: Return the badge token URI. This follows the same schema as ERC721's tokenURI. In most cases, the badge contract would use a static image, shared by all instances of this badge. However, on-chain-generated SVG data URLs are also possible.

As a badge developer, it is strongly recommended that your contract inherits from ScrollBadge. Additionally, you can use one or more extensions. Refer to the examples in examples.

While this is not mandatory, we recommend creating badges that do no expire, are non-revocable, and are singletons (at most 1 badge per user).

Badge Token URI

Each badge must define a badge token URI.

The badge token URI is very similar to the tokenURI in ERC-721. It must point to a metadata JSON object that contains name, description, image, and issuerName. You can use a normal URL, an IPFS link, or a data URL as your token URI. The metadata is used by the Canvas frontend to render the badge.

For example, the badge token URI https://nft.scroll.io/canvas/year/2024.json points to the following metadata:

{
  "name": "Ethereum Year",
  "description": "Check out the Ethereum Year Badge! It's like a digital trophy that shows off the year your wallet made its debut on Ethereum. It's a little present from Scroll to celebrate all the cool stuff you've done in the Ethereum ecosystem.",
  "image": "https://nft.scroll.io/canvas/year/2024.webp",
  "issuerName": "Scroll"
}

Your badge contract can provide a single URI for all badges, in which case all instances of your badge will look the same. Alternatively, you can also render a different image for different instances of your badge, see EthereumYearBadge. You should also configure a default badge token URI, see ScrollBadgeDefaultURI.

Design guidelines for badge images:

  • Maximum resolution: 480px x 480px
  • Optimal resolution: 600px x 600px
  • File size: Under 300KB

Ways to Issue Badges

Badges are created by attesting to the recipient using the BADGE_SCHEMA. EAS provides multiple interfaces to attest: attest, attestByDelegation, multiAttest, multiAttestByDelegation. See IEAS.sol.

There are three main badge types of badges:

  1. Permissionless. Permissionless badges allow users to attest to themselves using EAS.attest. The badge contract ensures that the user is authorized to mint. See ScrollBadgePermissionless.sol and ScrollBadgeTokenOwner.sol.

  2. Backend-authorized. For backend-authorized badges, the issuer maintains a centralized backend service. This backend implements some off-chain eligibility check and exposes an eligibility check and claim API. If the user is authorized to mint, the backend issues a signed permit. The user then mints using this permit.

    See this document for the API requirements.

    For backend-authorized badges, you need to deploy two contracts: the badge contract, and an AttesterProxy. AttesterProxy allows executing delegated attestations in arbitrary order. The user can mint the badge by calling AttesterProxy.attestByDelegation and providing the signed permit.

  3. Gifted. Badges can also be issued with no user interaction. To do this, the issuer uses EAS.attest or EAS.multiAttest to airdrop these badges to a list of users.

Overview of Requirements

Type Description Requirements Required Extensions Examples

Permissionless

Badge checks eligibility based on smart contract.

Example: Badges attesting to completing an onchain transaction or holding an NFT are eligible to mint the badge.

Basic Requirements:

Additional Requirements:

ScrollBadgeDefaultURI, ScrollBadgeEligibilityCheck

ScrollBadgePermissionless, ScrollBadgeTokenOwner, ScrollBadgeWhale.

Backend-authorized

Badge checks eligibility based on the issuer’s API.

Example: Badges attesting to completing offchain actions or a certain allow list.

All Basic Requirements, plus

  • The check API (off-chain eligibility check) and claim API have been deployed to production.

  • All involved URLs, including those for the Check API, Claim API, and the badgeTokenURI returned by the contract, are configured for cross-origin access (CORS) on https://scroll.io.

  • The attester proxy contract is deployed on the Scroll Mainnet and verified on Scrollscan.

  • The attester proxy contract is authorized to mint your badge (through badge.toggleAttester).

  • The backend signer is authorized to sign permits (through attesterProxy.toggleAttester).

ScrollBadgeDefaultURI, ScrollBadgeAccessControl

EthereumYearBadge, ScrollBadgeSimple.

Gifted

Badge checks eligibility based on the issuer’s API and automatically sends to users' canvas. There is no minting required for users to display the badge.

Example: Badges attesting to ownership or paid membership on other platforms / chains.

All Basic Requirements, plus

  • The check API has been deployed to production.

Upgradable Badges

This section is not about contract upgradability. If you want to make your badge contract upgradable, use any standard upgradability pattern.

Upgradable badges are badges that can evolve over time. This pattern is most suitable for badges that represent that the user has reached a certain "level". A user can first mint a badge at a certain level. Then, once the user is eligible, they can upgrade their badge to a higher level.

Upgradable badges must implement the IScrollBadgeUpgradeable interface. Currently this interface only supports on-chain upgrade conditions.

Extensions

This repo contains some useful extensions:

  • ScrollBadgeAccessControl restricts who can create and revoke this badge.
  • ScrollBadgeCustomPayload adds custom payload support to the badge.
  • ScrollBadgeDefaultURI sets a default badge token URI.
  • ScrollBadgeEligibilityCheck adds a standard on-chain eligibility check interface.
  • ScrollBadgeNoExpiry disables expiration for the badge.
  • ScrollBadgeNonRevocable disables revocation for the badge.
  • ScrollBadgeSBT attaches an SBT token to each badge attestation.
  • ScrollBadgeSelfAttest ensures that only the recipient of the badge can create the badge.
  • ScrollBadgeSingleton ensures that each user can only have at most one of the badge.

Examples

This repo also contains some examples:

  • ScrollBadgeSimple is a simple badge with fixed metadata.
  • ScrollBadgePermissionless is a permissionless badge that anyone can mint to themselves.
  • ScrollBadgeLevels is an SBT badge that stores a level in its payload and renders different images based on this level.
  • ScrollBadgeTokenOwner is a badge that is tied to the ownership of a Scroll Origins NFT.

Troubleshooting

We recommend going through the requirements before your badge is published.

Once your badge has been deployed on Scroll, you can auto-check some of these requirements by running yarn check-badge.

If your badge minting transaction reverts, we recommend debugging using cast:

cast run --rpc-url https://rpc.scroll.io [txhash]

This call will simulate the transaction in a local environment and show you the call stack and revert reason.