A Proof-of-Contribution (PoC) reputation protocol quantifies and records an entity's valuable actions within a decentralized network. Unlike simple transaction counts, it aims to measure meaningful participation—such as code commits, governance votes, or liquidity provision—and translate it into a verifiable, on-chain reputation score. This guide outlines the core architecture and provides a basic implementation using Solidity. The system we'll build tracks contributions, calculates a score, and allows for the querying of a user's reputation, forming a foundation for more advanced features like Sybil resistance or reward distribution.
Setting Up a Proof-of-Contribution Reputation Protocol
Setting Up a Proof-of-Contribution Reputation Protocol
A step-by-step tutorial for developers to implement a foundational Proof-of-Contribution (PoC) reputation system using smart contracts.
The protocol's state is managed by a smart contract with three key data structures. First, a mapping stores each user's aggregate reputation score. Second, an enum defines the recognized contribution types (e.g., DEVELOPMENT, GOVERNANCE, COMMUNITY). Third, a Contribution struct logs individual actions, containing the contributor's address, a timestamp, the contribution type, and a weight. Events like ContributionRecorded are emitted for off-chain indexing. This structure ensures immutable audit trails; every point of reputation is linked to a specific, recorded action that can be verified by anyone.
The core logic resides in a recordContribution function. This restricted function validates the caller and the contribution data, creates a new Contribution entry, and updates the user's total score. The scoring algorithm is critical. A simple approach adds a fixed weight per contribution type. A more robust system might use a decaying formula where newer contributions weigh more, or a context-aware model that adjusts weights based on network state. All calculations must be performed on-chain to maintain transparency and prevent manipulation of the historical record.
For practical use, the contract must expose a view function to fetch a user's current reputation score. Consider implementing attestation features, allowing trusted oracles or designated community members to vouch for off-chain contributions. To prevent spam, integrate a staking mechanism or a governance vote to approve new contribution records. The completed contract can serve as a modular component within larger DeFi or DAO ecosystems, enabling systems where governance power, access, or rewards are directly tied to proven, on-chain contribution history.
Prerequisites and Tech Stack
This guide outlines the core technologies and foundational knowledge required to build a proof-of-contribution reputation protocol.
A proof-of-contribution protocol is a decentralized system that quantifies and verifies user actions to generate a reputation score. Before development, you need a solid grasp of smart contract development on a blockchain like Ethereum, Polygon, or an L2 like Arbitrum. Core concepts include token standards (ERC-20, ERC-721), decentralized storage (IPFS, Arweave), and oracle networks (Chainlink) for reliable off-chain data. Familiarity with a decentralized identity (DID) framework, such as Ceramic or Ethereum Attestation Service, is also essential for linking contributions to a persistent identity.
Your primary development stack will consist of a smart contract language, a testing framework, and a frontend library. Solidity is the standard for EVM-compatible chains, while Vyper is a viable alternative. Use Hardhat or Foundry for local development, testing, and deployment. For the frontend, React or Vue.js paired with a Web3 library like wagmi or ethers.js is common. You'll also need a wallet integration SDK, such as RainbowKit or ConnectKit, to handle user authentication and transaction signing seamlessly within your dApp interface.
Reputation logic requires secure and verifiable data. You will need to design contribution schemas that define measurable actions (e.g., codeCommit, proposalVoted, grantFunded). These schemas are often stored on-chain as attestations or off-chain with content-addressed pointers. For complex scoring algorithms that cannot be computed on-chain due to gas costs, consider a layer-2 solution or a dedicated verifiable compute service like RISC Zero. Always plan for upgradeability patterns (like Transparent Proxy or UUPS) to iteratively improve your scoring model without breaking user reputations.
Core System Components
A Proof-of-Contribution protocol requires specific technical components to track, verify, and reward on-chain activity. This section details the essential building blocks.
Step 1: Sourcing Contribution Data
The first step in building a Proof-of-Contribution (PoC) reputation protocol is identifying and aggregating verifiable on-chain and off-chain activity. This data forms the raw material for your reputation algorithm.
A robust PoC system must source data from multiple, verifiable channels to create a holistic view of a user's contributions. The primary sources are on-chain activity and off-chain attestations. On-chain data is the most objective, including transactions, smart contract interactions, governance votes, and liquidity provisions. This data is immutable and publicly auditable, making it a core pillar for trustless reputation scoring. For example, contributions could be measured by the volume of DAI deposited into a lending protocol, the number of successful snapshot.org votes, or the deployment of verified smart contracts on a testnet.
Off-chain contributions are equally critical but require different verification mechanisms. This includes code commits to a project's GitHub repository, meaningful discussions and issue resolutions in a project's Discord or Forum, and content creation like technical tutorials or research papers. To integrate this data trustlessly, you must use verifiable credentials or attestation protocols like Ethereum Attestation Service (EAS) or Verax. These systems allow trusted entities (e.g., project maintainers, DAO committees) to issue on-chain signed statements that can be queried by your reputation protocol, bridging the gap between off-chain actions and on-chain reputation.
Technically, sourcing this data involves setting up indexers or using existing data providers. For on-chain data, you can run a subgraph on The Graph protocol to index specific event logs, or use an RPC provider like Alchemy or Infura with custom filtering logic. For off-chain attestations, you would query the smart contracts of the chosen attestation registry. A basic example using Ethers.js to fetch EAS attestations for a user would look like:
javascriptconst attestations = await easContract.getAttestations({ recipient: userAddress, schemaId: contributionSchemaUID });
This fetches all attestations issued to a specific address under a predefined schema for contributions.
The key challenge is data normalization. Contributions from different sources (e.g., 1 ETH staked vs. 1 GitHub PR) are not directly comparable. Your sourcing layer must attach standardized metadata to each data point, such as a contribution type (development, governance, liquidity), a platform identifier (Compound, Uniswap, GitHub), and a timestamp. This structured data is then passed to the next stage: the scoring and weighting engine. Without clean, normalized input data, any reputation score derived from it will be flawed or easily gamed.
Finally, consider data freshness and pruning. Not all contributions have perpetual value; a governance vote from three years ago may be less relevant than one from last month. Your data sourcing strategy should include logic to weight contributions based on recency or implement decay mechanisms. Furthermore, you must plan for data revocation—especially for off-chain attestations—where an issuer can nullify a previously granted credential if a contribution is found to be malicious or fraudulent, ensuring the reputation system remains dynamic and accountable.
Step 2: Designing the Scoring Algorithm
The scoring algorithm is the mathematical heart of your reputation protocol, translating on-chain actions into a quantifiable score. This step defines the rules for how contributions are valued and aggregated over time.
A robust scoring algorithm must be transparent, sybil-resistant, and context-aware. Start by defining the contribution events your protocol will track. Common examples include: successful governance votes on Snapshot or Tally, verified GitHub commits to a project's repository, consistent liquidity provision on a DEX like Uniswap V3, and completion of quests on platforms like Galxe. Each event type should map to a discrete action type in your smart contract, such as VOTE, CODE_COMMIT, or LP_PROVISION.
Next, assign a base point value to each action type. This is not a flat number but a function that can incorporate key variables. For instance, a governance vote's value could be weighted by the voter's token stake, or a liquidity provision event could be scaled by the USD value of the deposited assets and the duration of the lock. The formula points = base_weight * stake_multiplier * time_coefficient is a typical pattern. This ensures the score reflects both the quality and commitment of the contribution, not just frequency.
To prevent inflation and gamification, you must implement score decay or aging mechanisms. A common approach is the exponential decay model, where a user's total score decreases by a fixed percentage per epoch (e.g., 5% per month). This is calculated as S_t = S_{t-1} * (1 - decay_rate), where S_t is the score at time t. This incentivizes ongoing participation and ensures the reputation reflects recent contributions, preventing early actors from resting on historical laurels.
Finally, the algorithm must be upgradeable and parameterizable without compromising the immutability of historical records. Implement your scoring logic in a separate library or using a proxy pattern, with key parameters (like base weights and decay rates) controlled by a governance module. This allows the community to refine the algorithm based on observed behavior and new contribution types. The output is a single, time-weighted reputation score that can be used for permissions, rewards, or governance power in downstream applications.
Example Contribution Weighting Matrix
Comparison of different approaches for assigning reputation scores to on-chain contributions.
| Contribution Type | Linear Weighting | Quadratic Weighting | Logarithmic Weighting |
|---|---|---|---|
Governance Vote | 1 point per vote | sqrt(voting power) | log10(voting power + 1) |
Code Contribution | 10 points per PR | 25 points per merged PR | 5 * log10(LOC added) |
Liquidity Provision | $100 TVL = 1 point | $100 TVL = 10 points | $100 TVL = 2 * log10(TVL) |
Community Moderation | |||
Sybil Attack Resistance | |||
Gas Cost Sensitivity | High | Medium | Low |
Implementation Complexity | Low | Medium | High |
Typical Use Case | Simple DAOs | Gitcoin Grants | Mature Reputation Systems |
Step 3: Issuing Verifiable Attestations
This guide details how to issue on-chain attestations for contributions using the Ethereum Attestation Service (EAS) to build a decentralized reputation system.
Verifiable attestations are the core data structure of a reputation protocol. An attestation is a signed piece of data, issued by an attester (like a project or DAO), that makes a claim about a subject (a contributor). Using a standard schema on Ethereum Attestation Service (EAS) or Ethereum Attestation Service (EAS) ensures these records are portable, interoperable, and cryptographically verifiable across applications. This moves reputation from being siloed on a single platform to being a user-owned asset. The attestation itself contains the reputation data (e.g., contribution score, project ID, timestamp) and metadata linking it to the schema and attester.
To issue an attestation, you first define a schema that structures your reputation data. A schema for proof-of-contribution might include fields for projectId (bytes32), contributionType (string), score (uint256), and contributionDate (uint64). You register this schema on the EAS contract using eas.registerSchema. Once registered, the schema receives a unique Schema UID, which all attestations using it will reference. This standardization is crucial for other applications to parse and trust your attestations.
With a schema in place, you can issue attestations. The core function is eas.attest. You must provide the schema UID, the recipient's address (the subject), an expiration time (use 0 for none), whether it's revocable, the actual data encoded according to your schema, and a refUID if linking to a prior attestation. The transaction is signed by the attester's wallet (e.g., a project's multisig). Upon success, the function returns a unique Attestation UID, serving as a permanent, on-chain reference to this specific reputation claim. Here's a simplified example:
soliditybytes32 schemaUID = 0x123...abc; address recipient = 0x456...def; bytes memory data = abi.encode(projectId, "Code Commit", 850, block.timestamp); bytes32 attestationUID = eas.attest({ schema: schemaUID, data: { recipient: recipient, expirationTime: 0, revocable: true, data: data } });
For automated systems, you can implement off-chain attestations signed by a private key and later bridged on-chain, reducing gas costs. However, on-chain attestations provide the strongest guarantee of availability and are directly queryable by smart contracts. You should also implement a revocation mechanism. If an attestation was issued with revocable: true, the original attester can call eas.revoke with the attestation UID to invalidate it. This is essential for maintaining system integrity if a contribution is later found to be fraudulent or needs correction.
To make attestations useful, they must be discoverable. You can index attestation UIDs and their data using The Graph or by listening to the Attested event emitted by the EAS contract. Front-end applications can then query for all attestations for a given recipient and schema, aggregating them to compute a reputation score or display a contribution history. By following this pattern, you create a composable reputation layer where contributions from multiple projects form a verifiable, user-centric reputation graph.
Essential Tools and Resources
These tools and protocols are commonly used to design, deploy, and operate a proof-of-contribution reputation protocol. Each card focuses on a concrete building block you can integrate into a production system.
Full Implementation Walkthrough
This guide walks through building a Proof-of-Contribution reputation protocol from scratch, covering smart contract development, on-chain verification, and frontend integration.
We'll implement a protocol where users earn non-transferable Soulbound Tokens (SBTs) for verifiable contributions, like submitting a successful pull request to a GitHub repository. The core architecture consists of three smart contracts: a Reputation Registry for minting SBTs, an Oracle for verifying off-chain data, and a Contribution Verifier containing the logic for what constitutes a valid contribution. We'll use Solidity, Hardhat for development, and the OpenZeppelin library for the ERC-721 standard, which we'll modify to create non-transferable tokens.
First, deploy the ReputationRegistry.sol contract. It inherits from OpenZeppelin's ERC721 and overrides the _beforeTokenTransfer function to revert all transfers, making tokens soulbound. The contract includes a mintReputation function that can only be called by the authorized ContributionVerifier contract. Each token's metadata should encode the contribution type (e.g., GITHUB_PR) and a unique identifier for the contribution event, which is stored on-chain for permanent verification.
Next, build the ContributionVerifier.sol contract. This contains the business logic. For a GitHub PR contribution, the verifier would require proof that a user's address is linked to a GitHub account that merged a PR into a specified repository. It defines a function, verifyAndMint, which takes user-provided data (like a GitHub username and PR number) and an off-chain cryptographic proof. This function calls a trusted Oracle contract to validate the proof against the real-world API (e.g., GitHub's API).
The Oracle is a critical trust-minimized component. For development, you can run a centralized server that signs verified data, but production systems use decentralized oracle networks like Chainlink. The oracle contract has a fulfill function that receives the API response. If the verification passes (e.g., the PR exists and was merged by the claimed user), the oracle callback triggers the ContributionVerifier, which then calls mintReputation on the registry, issuing the SBT to the user's wallet address.
Finally, integrate the system with a frontend. Use a framework like Next.js with ethers.js or wagmi. The user flow involves connecting their wallet, signing a message to link their Ethereum address to their GitHub account (via OAuth), and submitting the contribution details. The frontend interacts with the verifier contract, and users pay the gas fee for the minting transaction. Once confirmed, the SBT appears in their wallet, serving as a portable, verifiable record of their specific contribution to the project.
Frequently Asked Questions
Common technical questions and solutions for implementing a Proof-of-Contribution (PoC) reputation protocol, focusing on smart contract logic, Sybil resistance, and integration patterns.
A Proof-of-Contribution (PoC) protocol is a decentralized system that quantifies and records non-financial actions—like code commits, governance participation, or community moderation—on-chain to build a persistent reputation score. Unlike a token-based DAO where voting power is directly tied to token holdings (1 token = 1 vote), PoC systems decouple influence from capital. They use verifiable credentials, attestations, or soulbound tokens (SBTs) to represent contributions.
Key differences:
- Basis of Power: Token DAOs use financial stake; PoC uses proven work history.
- Sybil Resistance: PoC relies on social graphs, biometrics (like World ID), or proof-of-personhood, not just capital barriers.
- Vesting & Slashing: Reputation can be earned gradually and can be slashed for malicious acts, unlike static token balances.
- Use Case: Token DAOs excel at capital allocation; PoC is better for permissioning, weighted voting on non-financial matters, and reward distribution based on merit.
Protocols like SourceCred, Coordinape, and Gitcoin Passport are early examples of contribution-tracking systems.
Conclusion and Next Steps
You have now configured the core components of a proof-of-contribution protocol. This final section reviews the key takeaways and outlines pathways for extending the system.
Your deployed protocol now tracks on-chain contributions, calculates a verifiable reputation score, and allows users to stake tokens to signal trust. The core smart contracts—ContributionTracker.sol, ReputationOracle.sol, and StakingVault.sol—form a modular foundation. Key decisions you made, such as the weightings for different contribution types (e.g., code commits vs. governance votes) and the staking slash conditions, define the economic and social incentives of your ecosystem. It is critical to verify these parameters on a testnet and simulate edge cases before a mainnet launch.
To build upon this foundation, consider integrating with existing infrastructure. Connect your ReputationOracle to a decentralized data source like The Graph for automated contribution indexing. Implement an off-chain attestation system using EAS (Ethereum Attestation Service) to allow for nuanced, non-financial endorsements that feed into the reputation score. For enhanced security, you can migrate the staking logic to a modular framework like OpenZeppelin Governor for community-controlled slashing proposals.
The next logical step is to make reputation actionable. Develop a ReputationGatedAccess.sol contract that uses the calculated score to gate participation in exclusive governance rounds, token airdrops, or whitelists for new protocol features. You could also issue non-transferable Soulbound Tokens (SBTs) representing reputation tiers using standards like ERC-4973. This creates a persistent, user-owned record of achievement that can be used across multiple applications.
For ongoing maintenance, establish clear governance procedures for updating contribution parameters and oracle logic. Consider implementing a timelock on the ReputationOracle owner functions before fully decentralizing control to a DAO. Monitor key metrics such as the distribution of reputation scores, staking participation rates, and the correlation between high reputation and positive ecosystem outcomes. These analytics will inform future iterations of your protocol's incentive design.
Further resources for exploration include studying established reputation models like SourceCred for algorithm design, and Otterspace's Badge protocol for implementing SBTs. The goal is to evolve your system from a simple tracker into a robust, community-owned layer that accurately rewards and recognizes valuable work in your decentralized network.