Profile DIDs for Learners and Educators
Decentralized Identifiers (DIDs) are self-sovereign identities stored on the blockchain, enabling users to own, control, and verify their educational credentials, achievements, and learning history without reliance on centralized institutions. By integrating ERC-725 (Identity Standard) and ERC-735 (Claims Standard), Alme Mater ensures that learners and educators have portable, verifiable, and immutable identities that function across the entire Web3 education ecosystem.
DIDs form the backbone of the Decentralized Learning Protocol (DLP), allowing learners to build on-chain learning profiles that store credentials, certifications, and reputation without intermediaries. Why ERC-725 and ERC-735 for DIDs?
ERC-725 (Identity Standard) – Defines a flexible identity contract that can store key-value data, enabling self-sovereign identity management. ERC-735 (Claims Standard) – Enables verifiable claims, allowing institutions to issue, update, or revoke educational credentials securely. Non-Custodial & Interoperable – Users control their DID without intermediaries, ensuring cross-platform portability. On-Chain Verification – Employers, institutions, and platforms can instantly verify credentials without third-party validation.
DID Smart Contract Using ERC-725 and ERC-735 on Ethereum & EVM Chains
The following Solidity smart contract implements decentralized identity using ERC-725 (for identity) and ERC-735 (for claim verification).
📝 Solidity Smart Contract for DIDs
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract DecentralizedIdentity is Ownable {
using EnumerableSet for EnumerableSet.Bytes32Set;
struct DID {
string identifier;
address owner;
bool isActive;
EnumerableSet.Bytes32Set claims;
}
mapping(address => DID) private identities;
mapping(bytes32 => string) private claimData;
event DIDCreated(address indexed user, string identifier);
event ClaimAdded(address indexed user, bytes32 claimId, string claim);
event ClaimRevoked(address indexed user, bytes32 claimId);
event DIDRevoked(address indexed user);
modifier onlyDIDOwner(address user) {
require(identities[user].owner == msg.sender, "Not DID owner");
_;
}
function createDID(string memory identifier) public {
require(bytes(identities[msg.sender].identifier).length == 0, "DID already exists");
identities[msg.sender] = DID(identifier, msg.sender, true);
emit DIDCreated(msg.sender, identifier);
}
function addClaim(bytes32 claimId, string memory claim) public onlyDIDOwner(msg.sender) {
identities[msg.sender].claims.add(claimId);
claimData[claimId] = claim;
emit ClaimAdded(msg.sender, claimId, claim);
}
function revokeClaim(bytes32 claimId) public onlyDIDOwner(msg.sender) {
require(identities[msg.sender].claims.contains(claimId), "Claim not found");
identities[msg.sender].claims.remove(claimId);
delete claimData[claimId];
emit ClaimRevoked(msg.sender, claimId);
}
function revokeDID() public onlyDIDOwner(msg.sender) {
identities[msg.sender].isActive = false;
emit DIDRevoked(msg.sender);
}
function getDID(address user) public view returns (string memory, bool) {
return (identities[user].identifier, identities[user].isActive);
}
function getClaim(bytes32 claimId) public view returns (string memory) {
return claimData[claimId];
}
}
Last updated