Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Launching a Soulbound Token Reputation System

A technical tutorial for developers to implement a non-transferable, identity-linked reputation system using modified ERC standards, minting logic, and credential graphs.
Chainscore © 2026
introduction
IMPLEMENTATION GUIDE

Launching a Soulbound Token Reputation System

A technical guide to designing and deploying a non-transferable token system for on-chain reputation, governance, and identity.

A Soulbound Token (SBT) is a non-transferable, non-fungible token permanently bound to a single wallet address. Unlike standard ERC-721 NFTs, SBTs cannot be sold or transferred, making them ideal for representing persistent on-chain credentials such as reputation scores, educational certificates, governance rights, and proof-of-attendance. The concept, popularized by Vitalik Buterin, aims to create a decentralized society (DeSoc) where identity is composable and verifiable across applications without centralized intermediaries.

To launch an SBT system, you must first define its purpose and the rules for minting. Common designs include attestation-based SBTs (minted by a trusted entity to verify an action), achievement-based SBTs (automatically awarded for completing on-chain tasks), and reputation SBTs (where the token's metadata updates based on user behavior). The core technical decision is choosing a base standard. While a modified ERC-721 is common, the ERC-5192 standard provides a minimal interface for non-transferability, where the locked flag is set to true. For more complex logic like expirations or tier upgrades, a custom implementation is required.

Here is a basic example of an SBT contract using Solidity and the OpenZeppelin library, implementing ERC-721 with a permanent lock:

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract SoulboundReputation is ERC721 {
    address public admin;
    uint256 private _tokenIdCounter;

    constructor() ERC721("DevReputation", "DREP") {
        admin = msg.sender;
    }

    // Override transfer functions to disable them
    function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
        internal virtual override
    {
        require(from == address(0) || to == address(0), "Soulbound: token non-transferable");
        super._beforeTokenTransfer(from, to, tokenId, batchSize);
    }

    // Mint function callable only by admin
    function awardReputation(address to) external {
        require(msg.sender == admin, "Not authorized");
        uint256 tokenId = _tokenIdCounter;
        _tokenIdCounter++;
        _safeMint(to, tokenId);
    }
}

This contract ensures tokens can only be minted (from == address(0)) or burned (to == address(0)), blocking all peer-to-peer transfers.

After deployment, you must integrate the SBT with your application's logic. For a reputation system, you could create a separate Reputation Registry contract that reads SBT ownership and updates an on-chain score. A common pattern is to store metadata off-chain (e.g., on IPFS or Arweave) and reference it via the token's tokenURI. For dynamic reputation, the URI can point to a mutable resource or the on-chain contract can emit events that frontends use to update a user's profile. Key considerations include privacy (using zero-knowledge proofs for private verification), revocability (whether admins can burn tokens), and composability (how other protocols can read and trust your SBT data).

Successful SBT implementations are already in use. The Ethereum Attestation Service (EAS) allows any entity to create on- or off-chain attestations that function like SBTs. Gitcoin Passport aggregates Web2 and Web3 credentials into a non-transferable score for sybil resistance. When designing your system, audit the security model thoroughly: ensure minting permissions are robust, prevent metadata manipulation, and consider the implications of a permanently locked asset. The goal is to create a persistent, trustworthy signal that enhances user identity across the decentralized web.

prerequisites
GETTING STARTED

Prerequisites and Setup

Before deploying a Soulbound Token (SBT) reputation system, you need to establish your development environment, choose the right tools, and understand the core architectural decisions.

A functional development environment is the first prerequisite. You will need Node.js (v18 or later) and npm or yarn installed. For smart contract development, the Hardhat framework is the industry standard for Ethereum Virtual Machine (EVM) chains, providing a testing environment, local blockchain, and deployment scripts. Alternatively, Foundry is gaining popularity for its speed and direct Solidity testing. Install your chosen framework globally: npm install --global hardhat.

The core of your system will be the smart contracts that mint and manage SBTs. You must be proficient in Solidity (v0.8.x) and understand key ERC standards. The foundational standard for non-transferable tokens is ERC-721, but you will modify it to remove transfer functions. For a more standardized approach, consider implementing ERC-5192, the minimal interface for soulbound tokens, which adds a locked function. Your development workflow will involve writing, compiling (npx hardhat compile), and extensively testing your contracts on a local network before any mainnet deployment.

You will also need a wallet for deployment and interaction. Set up a MetaMask wallet and fund it with testnet ETH (e.g., from a Sepolia faucet) for deployment trials. Securely manage your private keys or mnemonic phrase, as they control the contract deployer address, which will have special minting privileges. For automated scripting and backend integration, you may use libraries like ethers.js (v6) or web3.js to connect your application to the blockchain.

Finally, decide on your target blockchain. While Ethereum mainnet offers maximum security, high gas costs can be prohibitive for a reputation system. Layer 2 solutions like Arbitrum, Optimism, or Polygon POS provide significantly lower costs while inheriting Ethereum's security. Alternatively, you could use a dedicated appchain or a testnet like Sepolia for initial development. Your choice will determine your RPC endpoint and final deployment commands (npx hardhat run scripts/deploy.js --network sepolia).

key-concepts-text
CORE CONCEPTS

Launching a Soulbound Token Reputation System

Soulbound tokens (SBTs) create non-transferable digital credentials on-chain. This guide explains how to design and deploy a reputation system using SBTs and attestations.

Soulbound tokens (SBTs) are non-transferable, non-financialized tokens bound to a single wallet, or "Soul." Unlike fungible or standard NFTs, they cannot be sold or transferred, making them ideal for representing persistent identity attributes like memberships, educational credentials, and work history. This inherent non-transferability is the core feature that prevents reputation from being bought or sold, creating a more authentic on-chain identity layer. Projects like Ethereum Attestation Service (EAS) provide the infrastructure to issue these credentials as on-chain attestations, which can be represented as SBTs.

Designing a reputation system starts with defining the schema for your attestations. A schema is a blueprint that defines the data structure of your credential, such as the fields for a "Proof of Attendance" or "Skill Certification." Using EAS, you register this schema on-chain. For example, a DAO membership attestation schema might include fields for memberSince (timestamp), role (string), and contributionScore (uint256). This standardized structure ensures all issued credentials are consistent and can be easily interpreted and verified by other smart contracts and applications.

Once the schema is registered, you issue attestations to user wallets. This is an on-chain transaction that creates a permanent, verifiable record linking a credential to a specific Soul. The issuer signs the data, providing cryptographic proof of its authenticity. Because the attestation is stored on-chain, any application can query it to verify a user's reputation without relying on a central database. For instance, a governance portal can check for a "Verified Contributor" attestation before allowing a wallet to vote on proposals, automating permissioned access based on proven reputation.

The real power emerges when SBTs from multiple issuers are composed. A user's Soul can accumulate attestations from various sources—a degree from a university SBT, a work history from a DAO, and KYC verification from an identity provider. Applications can then create complex reputation graphs by reading this portfolio. A DeFi protocol might offer better loan terms to a Soul holding both a "Long-term Holder" attestation and a "Verified Identity" SBT. This composability turns static credentials into a dynamic, interoperable reputation score.

To launch your system, you must manage issuer authority and revocation. Using a smart contract as the attestation issuer allows for programmable rules, like auto-issuing an SBT after a user completes ten tasks in a dApp. It's also critical to plan for revocation mechanisms, such as expiring credentials or allowing an issuer to revoke an attestation in case of bad behavior. Tools like EAS support both on-chain and off-chain attestations with revocation lists, giving you flexibility between cost and decentralization based on your use case's requirements.

Finally, consider the user experience and privacy. While all data is on-chain, you can use zero-knowledge proofs (ZKPs) via schemes like Semaphore to allow users to prove they hold a valid attestation without revealing which specific one, or to prove their reputation score exceeds a threshold. This preserves privacy while maintaining verifiability. Start by deploying a simple attestation schema on a testnet like Sepolia using the EAS Explorer, issuing test credentials to understand the flow before building a full application on mainnet.

STANDARD COMPARISON

ERC-721 vs. ERC-1155 for SBT Implementation

A technical comparison of the two primary Ethereum token standards for building a Soulbound Token (SBT) reputation system.

Feature / MetricERC-721ERC-1155

Token Standard Type

Non-Fungible Token (NFT)

Multi Token (Fungible & Non-Fungible)

SBT Core Requirement (Non-Transferable)

Requires custom logic to override or block transferFrom

Requires custom logic to override or block safeTransferFrom

Gas Efficiency for Batch Operations

Native Support for Multiple Token Types in One Contract

Required Interface for Wallets/Marketplaces

ERC-721 Metadata & Enumerable

ERC-1155 Metadata URI

Typical Minting Cost (First Token, Approx.)

$50 - $150

$80 - $200 (deploy), < $5 per batch mint

On-Chain Metadata Storage Flexibility

Token URI per token

URI per token ID (can represent a class)

Ideal Use Case for Reputation

Unique, indivisible achievements or identities

Reputation points, badges with tiers, or multi-faceted systems

implementation-steps
SOULBOUND TOKEN DEVELOPMENT

Step 1: Implementing a Non-Transferable ERC-721 Contract

This guide details the foundational step of creating a smart contract for a Soulbound Token (SBT) by modifying the ERC-721 standard to enforce non-transferability.

Soulbound Tokens (SBTs) are a concept for non-transferable, non-financialized NFTs that represent credentials, affiliations, or reputation. The most straightforward technical implementation is to modify the widely adopted ERC-721 standard to disable its transfer functions. This approach leverages existing infrastructure like OpenSea and Etherscan while ensuring the token cannot be sold or moved from the wallet that initially received it. We'll start by using a standard OpenZeppelin ERC-721 contract as our base.

The core logic for non-transferability is implemented by overriding key functions. In your contract, you must override _beforeTokenTransfer from the ERC-721 base contract. This internal hook is called before any minting, burning, or transferring. To block transfers, you add a simple check that reverts the transaction if the from address is not the zero address (minting) or if the to address is not the zero address (burning). This effectively allows tokens to be minted and burned by the contract owner but prevents all peer-to-peer transfers.

Here is the essential Solidity code snippet for the override:

solidity
function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId,
    uint256 batchSize
) internal virtual override {
    super._beforeTokenTransfer(from, to, tokenId, batchSize);
    // Allow minting (from == address(0)) and burning (to == address(0))
    require(from == address(0) || to == address(0), "Token is non-transferable");
}

This single requirement is the heart of a basic SBT contract. It's crucial to call the parent function with super._beforeTokenTransfer(...) first to maintain any other logic from inherited contracts.

For a production-ready system, you should also consider overriding the approve and setApprovalForAll functions to revert all approval attempts, as these are precursors to transfers in marketplaces. Furthermore, you may want to implement a controlled burning mechanism, allowing a designated authority (or the token holder themselves) to revoke a credential. Always thoroughly test the contract using a framework like Hardhat or Foundry to ensure the transfer restrictions behave as expected under all conditions before deployment to a mainnet.

minting-logic
CORE ARCHITECTURE

Step 2: Designing Minting Logic and Access Control

Define the rules that govern how and when your SBTs are issued, and who has the authority to do so.

The minting logic is the core business rule of your reputation system. It defines the specific conditions under which a Soulbound Token (SBT) is issued to a user's wallet. This logic is typically encoded in a smart contract and can be triggered by on-chain events, off-chain attestations, or a combination of both. For example, a DeFi protocol might mint a "Liquidity Provider Tier 1" SBT after a user supplies over 10 ETH to a specific pool. The logic must be deterministic and transparent, ensuring the system's fairness and auditability.

Access control determines which entities are authorized to trigger the minting function. A common pattern is to implement a role-based system using OpenZeppelin's AccessControl library. You would typically designate a minter role granted to a secure, off-chain backend server (a "minting oracle") or a decentralized autonomous organization (DAO). This separation prevents arbitrary minting and centralizes trust in the oracle or DAO's logic. The contract's constructor should set up these roles, and functions like grantRole and revokeRole should be protected behind administrative permissions.

Here is a simplified Solidity snippet illustrating a basic minting contract with access control:

solidity
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract ReputationSBT is ERC721, AccessControl {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    constructor() ERC721("ReputationSBT", "RSBT") {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
    }
    function safeMint(address to, uint256 tokenId) public onlyRole(MINTER_ROLE) {
        _safeMint(to, tokenId);
    }
    // Override to make token non-transferable
    function _beforeTokenTransfer(address from, address to, uint256) internal virtual override {
        require(from == address(0), "Soulbound: Token is non-transferable");
    }
}

This contract uses the onlyRole(MINTER_ROLE) modifier to restrict minting and overrides _beforeTokenTransfer to enforce soulbinding by only allowing minting (from == address(0)).

For more complex logic, consider an off-chain verifier with on-chain enforcement pattern. An off-chain service (the oracle) listens for events or checks conditions. When criteria are met, it cryptographically signs a message containing the recipient's address and a token identifier. The smart contract then has a claimReputation function that accepts this signature as proof, verifies it came from the trusted minter, and mints the token. This design keeps gas costs low and allows for flexible, complex logic without deploying new contracts.

Key design considerations include: - Revocation logic: How are tokens burned if reputation is lost? - Upgradability: Can reputation tiers be upgraded (e.g., burning a Tier 1 to mint a Tier 2)? - Sybil resistance: Link minting to a proof-of-personhood or unique identity system to prevent gaming. - Gas optimization: Batch minting operations or using gas-efficient standards like ERC-1155 for multi-token systems. Your choices here will define the security, cost, and user experience of your reputation layer.

credential-graph
ARCHITECTURE

Step 3: Building a Graph of Identity-Linked Credentials

This step focuses on creating a dynamic, queryable network of verifiable credentials anchored to a user's primary identity, moving beyond a simple list of SBTs.

A Soulbound Token (SBT) reputation system's true power is unlocked when individual credentials are interconnected. Instead of treating each SBT as an isolated data point, we construct a graph data structure where the user's primary identity (e.g., their wallet address) is the central node. Each issued credential—be it a proof-of-attendance NFT, a skill certification, or a governance participation badge—becomes a linked node. This structure allows for complex queries like "find all developers who attended EthDenver 2024 and hold an advanced Solidity certification."

To build this graph, you need a standardized way to link credentials to the identity and to each other. The Verifiable Credentials (VC) data model and W3C Decentralized Identifiers (DIDs) provide this framework. A credential's metadata should include the issuer (a DID), the subject (the user's DID), and optional evidence fields that can reference other credential IDs. Storing these relationships on-chain can be done by emitting standardized events from your SBT minting contract or by using a dedicated registry contract that maps subjectDID -> credentialDID[].

For efficient querying, an off-chain indexer or subgraph (using The Graph protocol) is essential. This service listens to your contract's events and populates a database that mirrors the credential graph. You can then use GraphQL to execute rich queries against this indexed data. For example, a query might traverse the graph to aggregate a reputation score by summing weighted values from connected credential nodes, or to verify a credential chain's validity by checking the issuer's status for each link.

Practical implementation involves defining your credential schema. Using ERC-721 or ERC-1155 for SBTs, you can store a reference URI in the token's metadata that points to a JSON file conforming to the VC standard. A basic schema includes @context, type (e.g., "AchievementCredential"), issuer, issuanceDate, credentialSubject.id (the user's DID), and credentialSubject.achievement. More advanced schemas from projects like Veramo or SpruceID's Kepler can be adopted for interoperability.

Finally, consider privacy and selective disclosure. Users may not want to reveal their entire credential graph. Techniques like zero-knowledge proofs (ZKPs) allow a user to prove they hold a credential from a trusted issuer meeting certain criteria (e.g., "KYC verified after date X") without revealing the credential itself. Integrating with ZK toolkits like Semaphore or Sismo's ZK Badges can add this layer, making your reputation system both powerful and privacy-preserving.

testing-deployment
LAUNCHING A SOULBOUND TOKEN REPUTATION SYSTEM

Step 4: Testing, Deploying, and Verifying

This final step covers the essential processes to ensure your smart contract is secure, functional, and transparently deployed to the blockchain.

Before deployment, rigorous testing is non-negotiable. Start by writing unit tests for your core functions like mintSBT, burnSBT, and reputation updates. Use a framework like Hardhat or Foundry to simulate transactions and edge cases. For a reputation system, key tests include verifying that only authorized issuers can mint tokens, tokens cannot be transferred between wallets (enforcing soulbinding), and reputation scores update correctly based on on-chain events. Mocking external dependencies, such as oracle data feeds for off-chain reputation inputs, is crucial for comprehensive coverage.

Once tests pass, you must choose a network and deploy. For development, use a local node or a testnet like Sepolia or Goerli. Configure your deployment script to handle constructor arguments, such as the initial admin address and the base URI for token metadata. A typical Hardhat deployment command is npx hardhat run scripts/deploy.js --network sepolia. Always estimate gas costs beforehand and fund your deployer wallet with sufficient test ETH. After deployment, immediately interact with the contract using a script or frontend to confirm basic minting and querying functions work as expected on the live network.

Contract verification is the final step for transparency and trust. Platforms like Etherscan or Blockscout allow users to read your source code and interact with it directly. You'll need to provide the compiler version, constructor arguments (encoded), and your source files. For complex setups with libraries (like OpenZeppelin's ERC721), use flattened source code or the Etherscan's multi-file verification. A verified contract is essential for any reputation system, as it allows the community to audit the immutable rules governing their on-chain standing. Post-verification, you can also publish the contract ABI for easier integration with dApps.

DEVELOPER TROUBLESHOOTING

Frequently Asked Questions (FAQ)

Common technical questions and solutions for developers implementing a Soulbound Token (SBT) reputation system on EVM-compatible chains.

A Soulbound Token (SBT) is a non-transferable, non-fungible token that is permanently bound to a specific wallet address, often called a "Soul." Unlike a regular ERC-721 or ERC-1155 NFT, it cannot be sold or transferred to another address after minting. This is enforced at the smart contract level, typically by overriding the transferFrom and safeTransferFrom functions to revert all transfer attempts.

Key technical distinctions:

  • Transfer Logic: SBT contracts block all transfer functions, while NFTs allow them.
  • Burnability: SBTs can often be burned (self-destructed) by the issuer or the holder, providing an escape hatch.
  • Utility: SBTs represent immutable credentials, memberships, or achievements, whereas NFTs primarily represent ownership of a unique asset.
conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully deployed a foundational Soulbound Token (SBT) reputation system. This guide covered the core concepts, smart contract development, and basic on-chain integration. The next steps involve enhancing security, improving user experience, and exploring advanced applications.

Your deployed system now has a functional SoulboundReputation contract on a testnet, capable of minting non-transferable tokens to represent user achievements or contributions. You have integrated a basic frontend using wagmi and viem to connect wallets and interact with the contract. This foundation demonstrates the core value proposition of SBTs: creating a persistent, verifiable, and user-controlled record of reputation that cannot be bought or sold. The next phase is to move from a proof-of-concept to a production-ready system.

To harden your system, consider implementing several key upgrades. Access control should be refined using OpenZeppelin's Ownable or role-based systems (AccessControl) to strictly define which addresses can mint or burn tokens. For enhanced security and user experience, explore gasless transactions via meta-transactions with a relayer or account abstraction with ERC-4337. You should also implement robust event emission for all state changes, which is crucial for off-chain indexing and frontend updates. Tools like The Graph can be used to create a subgraph for efficient querying of reputation data.

The real power of a reputation layer is realized through integration. Consider how your SBTs can interact with other protocols. For example, a governance DAO could use SBT holdings to calculate vote weight. A lending protocol might offer better rates to users with a "Trusted Borrower" SBT. A gated community or event platform could use SBTs for permissioned access. Design your token metadata and issuance logic with these specific utility cases in mind from the start.

For further development, explore the EIP-4973 standard for a more formalized SBT interface. Investigate zero-knowledge proofs (ZKPs) with libraries like SnarkJS to allow users to prove they hold a reputation credential without revealing their entire wallet address. To manage complex reputation graphs, look into Ceramic Network or Tableland for storing and updating composable, decentralized data associated with your SBTs. The Sismo protocol offers frameworks for creating ZK badges, which are a form of privacy-preserving SBT.

Continue your learning by examining production implementations. Study how Gitcoin Passport aggregates Web2 and Web3 credentials into a reputation score. Analyze Orange Protocol's modular reputation oracle. Review the Ethereum Attestation Service (EAS) as a generic framework for making on- and off-chain attestations, which can be used as a more flexible reputation primitive. Engage with the community on forums like EthResearch to discuss the latest design patterns and ethical considerations for non-transferable tokens.