Since 2009, we have been utilizing our extensive expertise in blockchain technologies to help businesses, both large and small, maximize their efficiency.
Explore More
With more than 400+ experts, Oodles comprises a fantastic resource of business knowledge that spans multiple industries. Whatever the circumstances, we keep to our obligations.
Explore More
At Oodles, we help our clients work with a human understanding but at superhuman speed something that others can't. They thus advance and maintain their lead
29th May 2023
13 min read
Associate Consultant - Development
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
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);
}
}
Vishal Prajapati
Vishal is a highly proficient Backend Developer with expertise in Mern Stack technology. He possesses a strong command over designing and developing smart contracts using Solidity and has successfully built REST APIs to facilitate communication between the blockchain and frontend systems. He effectively manages data using MongoDB and MySQL databases. He has a comprehensive skill set that includes JavaScript, Node.js, NestJS, MongoDB, MySQL, Docker, Solidity, and Microservices. Vishal has made significant contributions to various notable projects. Some of his noteworthy works include MisterZ, M2A, TRG Volume Bot, Arbitrage Bot, WethioNFT, Bitorio (Hedgex), Rafa, Apollo, and HODL Token. These projects highlight his ability to tackle diverse challenges and deliver innovative solutions in the field of backend development.
Associate Consultant - Development
By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.
We would love to
hear from you!
Innovate with confidence!