top of page

Soul Bound Token (SBT): A catalyst to the next web3 onboarding

This blog aims to provide a complete overview of the SoulBound Token (SBT), discussing its feature, its use cases, and covering the different available standards, its tech stack, its completion status, and its implementation requirements.


Introduction

A persistent problem that web3 industries face is the ability to verify and identify unique individuals and institutions in a decentralized manner. A recent paper published by a prominent personality supported by the likes of Ethereum founder proposes a decentralized digital identity based on non-transferable NFT that could serve as a foundational direction to the solution for the above problem.


Abstract (Non-Technical)

A SoulBound Token is a token that is bound to another Non-Fungible Token (NFT) when it is minted, and cannot be transferred/moved after that.

the application of proof of ownership of historical records and personal credentials becomes inherently important in society to maintain consistency and transparency in on-chain record keeping. Thus, by leveraging the infrastructural advancement and the immutability of blockchain technology and decentralized storage mechanisms, a new form of real-life applications in which values can be stored emerges. @authorityjoel

What is SBT? (Non-technical)

The Soul Bound token is a publicly visible non-transferable token that has the ability to act as an achievement badge, proof of reputation, authentication, etc…

for non-web3 natives, a simple similar example could be KYC (Know Your Customer) but here we only identify the wallet address.

credit: Cointelegraph


How SBT Works? (Non-technical)

SoulBound is not different from other NFT projects, albeit in terms of non-transferability. Souls or blockchain accounts and wallets can issue SBTs and store them. In addition, Souls can assign self-certified tokens to themselves.

However, the major highlight in the working of SoulBound NFTs would refer to the SBT creators issuing a token to another address (Soul). Such transactions feature open verification of the SBT, issuers, and the address of the Soul. As a result, it is easier to verify or track the integrity of the trust circles associated with a specific Soul.


Use-case (Non-technical)

credit: The Crypto Times

The above use case might look similar to some of the existing NFT features, and that is the idea behind the soul bound it’s not about re-inventing the wheel but finding extensions to the existing feature to make it better and extracting game-changing use cases out of it.


SBT Standards (Technical)

A soul-bound token is a non-fungible token bound to a single account. It is an extension of EIP-721 which is the same used in the NFT smart contract of the ERC-721 standard.

There are different standards used for different use cases:


1. EIP-5114, SoulBound Badge:

EIP-5114 standard is a token that is bound when it’s minted to another NFT such as ERC-721 smart contract. Once minted, it cannot be transferred or moved. It’s a badge that is attached to the receiver wallet (Soul). For a successful implementation of the SBT, collection URI must be both immutable and content addressable, for example, ipfs:// and not https://

Status: EIP-5114 is at a draft status and requires an ERC-721 contract standard for deployment.

Key Characteristics: - The NFT will be non-transferable after the initial mint. - Partially compatible with EIP-721.


2. EIP-5516, SoulBound Multi-owner Tokens:

Previous account-bound token standards face the issue of users losing their account keys or having them rotated, thereby losing their tokens in the process. EIP-5516 proposes a standard interface for non-fungible double signature soulbound multi-tokens. Given the multi-owner characteristic of EIP-1155 compliant interfaces and contracts, SBTs will be able to bind to multiple accounts, providing a potential solution to the issue. Multi-token functionality permits the implementation of multiple token types in the same contract.

Status: EIP-5516 is at a review status and requires EIP1155 or EIP165 contract standard for implementation

Key Characteristics: - The NFT will be non-transferable after the initial transfer - Partially compatible with EIP-1155 - Double Signature - Multi-Token - Multi-Owner - Semi-Fungible


3. EIP-5192, Minimal SoulBound Tokens:

EIP-5192 standard proposes a minimal interface to make tokens Soulbound using the feature detection functionality of EIP-165.

Status: EIP-5192 is at a final status and can be safely deployed and used

Key Characteristics: Token emitter can lock and unlock the token on the holder’s wallet


Standard Interface:

// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
interface IERC5192 {
  /// @notice Emitted when the locking status is changed to locked.
  /// @dev If a token is minted and the status is locked, this event should be emitted.
  /// @param tokenId The identifier for a token.
  event Locked(uint256 tokenId);
  /// @notice Emitted when the locking status is changed to unlocked.
  /// @dev If a token is minted and the status is unlocked, this event should be emitted.
  /// @param tokenId The identifier for a token.
  event Unlocked(uint256 tokenId);
  /// @notice Returns the locking status of an Soulbound Token
  /// @dev SBTs assigned to zero address are considered invalid, and queries
  /// about them do throw.
  /// @param tokenId The identifier for an SBT.
  function locked(uint256 tokenId) external view returns (bool);
}

SBT Smart Contract Functions // Technical

The locked & unlocked functions are essential in order to Soulbound an NFT. These 2 functions enable the SBT to enjoy the following features:

  • NFT cannot be transferred to other addresses like a usual ERC721 token

  • NFT can be retrieved back by the source/smart contract creator

credit: Binance

The Below code is an example of Soul bound Token. It is a simple Erc721 token with features such as mintable, auto-increment ids, URI storage, and access control set to ownable. On top of it, we add the above-mentioned interface and add burn, and revoke before and after the token transfer feature. This is how we make an SBT out of the NFT.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts@4.7.0/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts@4.7.0/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts@4.7.0/access/Ownable.sol";
import "@openzeppelin/contracts@4.7.0/utils/Counters.sol";
contract Web3ClubTourToken is ERC721, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIdCounter;
    event Attest(address indexed to, uint256 indexed tokenId);
    event Revoke(address indexed to, uint256 indexed tokenId);
    constructor() ERC721("Web3 Club Tour", "W3CT") {}
    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }
    function burn(uint256 tokenId) external {
        require(ownerOf(tokenId) == msg.sender, "Only owner of the token can burn it");
        _burn(tokenId);
    }
    function revoke(uint256 tokenId) external onlyOwner {
        _burn(tokenId);
    }
    function _beforeTokenTransfer(address from, address to, uint256) pure override internal {
        require(from == address(0) || to == address(0), "Not allowed to transfer token");
    }
    function _afterTokenTransfer(address from, address to, uint256 tokenId) override internal {
    if (from == address(0)) {
            emit Attest(to, tokenId);
        } else if (to == address(0)) {
            emit Revoke(to, tokenId);
        }
    }
    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }
    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
}

In the above figure, the“Attest” function provides the address with the badge through an “emit” in an on-chain transaction. The “Revoke” function is used to revoke the badge. Only smart-contract creator is able to use this function.


The Binance version, Binance Account Bound (BAB)

The BAB Token interface is similar to the ones we mentioned above. Here, we invoke the balanceOf method with the wallet address and it will return 0 (does not have any SBT locked to the wallet) or 1 (has an SBT locked to the wallet).

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ISBT721 {
    /**
     * @dev This emits when a new token is created and bound to an account by
     * any mechanism.
     * Note: For a reliable `to` parameter, retrieve the transaction's
     * authenticated `to` field.
     */
    event Attest(address indexed to, uint256 indexed tokenId);
    /**
     * @dev This emits when an existing SBT is revoked from an account and
     * destroyed by any mechanism.
     * Note: For a reliable `from` parameter, retrieve the transaction's
     * authenticated `from` field.
     */
    event Revoke(address indexed from, uint256 indexed tokenId);
    /**
     * @dev This emits when an existing SBT is burned by an account
     */
    event Burn(address indexed from, uint256 indexed tokenId);
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    /**
     * @dev Mints SBT
     *
     * Requirements:
     *
     * - `to` must be valid.
     * - `to` must not exist.
     *
     * Emits a {Attest} event.
     * Emits a {Transfer} event.
     * @return The tokenId of the minted SBT
     */
    function attest(address to) external returns (uint256);
    /**
     * @dev Revokes SBT
     *
     * Requirements:
     *
     * - `from` must exist.
     *
     * Emits a {Revoke} event.
     * Emits a {Transfer} event.
     */
    function revoke(address from) external;
    /**
     * @notice At any time, an SBT receiver must be able to
     *  disassociate themselves from an SBT publicly through calling this
     *  function.
     *
     * Emits a {Burn} event.
     * Emits a {Transfer} event.
     */
    function burn() external;
    /**
     * @notice Count all SBTs assigned to an owner
     * @dev SBTs assigned to the zero address is considered invalid, and this
     * function throws for queries about the zero address.
     * @param owner An address for whom to query the balance
     * @return The number of SBTs owned by `owner`, possibly zero
     */
    function balanceOf(address owner) external view returns (uint256);
    /**
     * @param from The address of the SBT owner
     * @return The tokenId of the owner's SBT, and throw an error if there is no SBT belongs to the given address
     */
    function tokenIdOf(address from) external view returns (uint256);
    /**
     * @notice Find the address bound to a SBT
     * @dev SBTs assigned to zero address are considered invalid, and queries
     *  about them do throw.
     * @param tokenId The identifier for an SBT
     * @return The address of the owner bound to the SBT
     */
    function ownerOf(uint256 tokenId) external view returns (address);
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);
}
# A example of how to check if an account holds BABT or not?
const provider = new Web3.providers.HttpProvider('https://data-seed-prebsc-1-s1.binance.org:8545')
const web3 = new Web3(provider)
const contractInstance = new web3.eth.Contract(abi, '0x2B09d47D550061f995A3b5C6F0Fd58005215D7c8')
// 0 - does not have any SBT
// 1 - has an SBT
const balance = await contractInstance.methods.balanceOf(address).call()

Projects using SBT // Non-Technical

Soulbound token technology is still in its genesis phase. No final standard has been adopted for full SBT uses by the Ethereum community yet. An official release is expected to take place by Q1 2023. However, few actors already started the SBT journey, here are some examples:


1. Binance Account Bound (BAB) Token

Binance uses BAB token badges on its platform for KYC purposes.

Features of the BAB Tokens:

  • Non-transferable: Users cannot transfer BAB tokens to other users.

  • Revocable: Users can revoke their BAB tokens.

  • Unique: One verified Binance user ID allows the user to mint one BAB token, and BABs are mintable only on a certain chain such as the BSC.

2. ARC

ARC is Asia’s app-based NFT membership private platform, comprising a close-knit community of creatives and thought leaders. Built on the belief that community is the key to creating a future that excites and motivates everyone, it is driven by a people-focused vision of co-creation, connection, and growth, which can spark infinite possibilities. Apart from the ARC app which has been built and will be ready upon mint, members have access to ARC Playgrounds, which are a network of IRL spaces where they can relax, play and connect with each other. Its utility NFT membership will give members opportunities to collaborate with a diverse community of talents, and co-create one-of-a-kind content and experiences with world-class partners. For more information on ARC, you may download relevant media assets here.


3. Zero-Code

Zero-Code is building the next-gen Smart-Contract Generator, which is a one-stop customizable solution for all web3 needs, enabling a wide selection of token standards (ERC 721 & 1155), total control over its functionality (SBT, rentable NFTs), and implementation with multi-chain selection for deployment (Ethereum, Polygon & Binance Smart Chain). Learn, create, implement, and deploy at the click of a button.

Visit our landing page to know more.


Sources








52 views0 comments

Comments


bottom of page