Posted By : Vishal
A soulbound token typically refers to a digital token or asset that is uniquely tied to a specific user or account, such that it cannot be transferred or traded to another user. The concept of a soulbound token is commonly used in video games and blockchain-based applications.
In video games, a soulbound token might be an item that can only be used by the player who obtained it and cannot be sold or traded to other players. This is often used to prevent players from gaining an unfair advantage by buying or trading powerful items with other players.
In the context of blockchain-based applications, a soulbound token might refer to a non-fungible token (NFT) that is permanently linked to a specific user's digital identity. This can be useful for applications like digital art, where the ownership and authenticity of a piece can be verified by the fact that it is soulbound to a specific user.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
/**
* An experiment in Soul Bound Tokens (SBTs) following Vitali k's
* co-authored whitepaper at:
* https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4105763
*
*/
contract SBT {
struct Soul {
string identity;
// add issuer specific fields below
string url;
uint256 score;
uint256 timestamp;
}
mapping (address => Soul) private souls;
mapping (address => mapping (address => Soul)) soulProfiles;
mapping (address => address[]) private profiles;
string public name;
string public ticker;
address public operator;
bytes32 private zeroHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
event Mint(address _soul);
event Burn(address _soul);
event Update(address _soul);
event SetProfile(address _profiler, address _soul);
event RemoveProfile(address _profiler, address _soul);
constructor(string memory _name, string memory _ticker) {
name = _name;
ticker = _ticker;
operator = msg.sender;
}
function mint(address _soul, Soul memory _soulData) external {
require(keccak256(bytes(souls[_soul].identity)) == zeroHash, "Soul already exists");
require(msg.sender == operator, "Only operator can mint new souls");
souls[_soul] = _soulData;
emit Mint(_soul);
}
function burn(address _soul) external {
require(msg.sender == _soul || msg.sender == operator, "Only users and issuers have rights to delete their data");
delete souls[_soul];
for (uint i=0; i<profiles[_soul].length; i++) {
address profiler = profiles[_soul][i];
delete soulProfiles[profiler][_soul];
}
emit Burn(_soul);
}
function update(address _soul, Soul memory _soulData) external {
require(msg.sender == operator, "Only operator can update soul data");
require(keccak256(bytes(souls[_soul].identity)) != zeroHash, "Soul does not exist");
souls[_soul] = _soulData;
emit Update(_soul);
}
function hasSoul(address _soul) external view returns (bool) {
if (keccak256(bytes(souls[_soul].identity)) == zeroHash) {
return false;
} else {
return true;
}
}
function getSoul(address _soul) external view returns (Soul memory) {
return souls[_soul];
}
/**
* Profiles are used by 3rd parties and individual users to store data.
* Data is stored in a nested mapping relative to msg.sender
* By default they can only store data on addresses that have been minted
*/
function setProfile(address _soul, Soul memory _soulData) external {
require(keccak256(bytes(souls[_soul].identity)) != zeroHash, "Cannot create a profile for a soul that has not been minted");
soulProfiles[msg.sender][_soul] = _soulData;
profiles[_soul].push(msg.sender);
emit SetProfile(msg.sender, _soul);
}
function getProfile(address _profiler, address _soul) external view returns (Soul memory) {
return soulProfiles[_profiler][_soul];
}
function listProfiles(address _soul) external view returns (address[] memory) {
return profiles[_soul];
}
function hasProfile(address _profiler, address _soul) external view returns (bool) {
if (keccak256(bytes(soulProfiles[_profiler][_soul].identity)) == zeroHash) {
return false;
} else {
return true;
}
}
function removeProfile(address _profiler, address _soul) external {
require(msg.sender == _soul, "Only users have rights to delete their profile data");
delete soulProfiles[_profiler][msg.sender];
emit RemoveProfile(_profiler, _soul);
}
}
November 21, 2024 at 12:08 pm
Your comment is awaiting moderation.