Base Learn Supreme-5——SCD ERC721 、Minimal Token、ERC20
- 获取链接
- X
- 电子邮件
- 其他应用
感谢X用户@isnotberlin提供的代码
以下是,Base Learn Supreme的3个NFT代码,SCD ERC721 、Minimal Token、ERC20
1. Own a(n) SCD ERC721 Pin NFT
Solidity 接口
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Importing OpenZeppelin ERC721 contract
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
// Interface for interacting with a submission contract
interface ISubmission {
// Struct representing a haiku
struct Haiku {
address author; // Address of the haiku author
string line1; // First line of the haiku
string line2; // Second line of the haiku
string line3; // Third line of the haiku
}
// Function to mint a new haiku
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external;
// Function to get the total number of haikus
function counter() external view returns (uint256);
// Function to share a haiku with another address
function shareHaiku(uint256 _id, address _to) external;
// Function to get haikus shared with the caller
function getMySharedHaikus() external view returns (Haiku[] memory);
}
// Contract for managing Haiku NFTs
contract HaikuNFT is ERC721, ISubmission {
Haiku[] public haikus; // Array to store haikus
mapping(address => mapping(uint256 => bool)) public sharedHaikus; // Mapping to track shared haikus
uint256 public haikuCounter; // Counter for total haikus minted
// Constructor to initialize the ERC721 contract
constructor() ERC721("HaikuNFT", "HAIKU") {
haikuCounter = 1; // Initialize haiku counter
}
string salt = "value"; // A private string variable
// Function to get the total number of haikus
function counter() external view override returns (uint256) {
return haikuCounter;
}
// Function to mint a new haiku
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external override {
// Check if the haiku is unique
string[3] memory haikusStrings = [_line1, _line2, _line3];
for (uint256 li = 0; li < haikusStrings.length; li++) {
string memory newLine = haikusStrings[li];
for (uint256 i = 0; i < haikus.length; i++) {
Haiku memory existingHaiku = haikus[i];
string[3] memory existingHaikuStrings = [
existingHaiku.line1,
existingHaiku.line2,
existingHaiku.line3
];
for (uint256 eHsi = 0; eHsi < 3; eHsi++) {
string memory existingHaikuString = existingHaikuStrings[
eHsi
];
if (
keccak256(abi.encodePacked(existingHaikuString)) ==
keccak256(abi.encodePacked(newLine))
) {
revert HaikuNotUnique();
}
}
}
}
// Mint the haiku NFT
_safeMint(msg.sender, haikuCounter);
haikus.push(Haiku(msg.sender, _line1, _line2, _line3));
haikuCounter++;
}
// Function to share a haiku with another address
function shareHaiku(uint256 _id, address _to) external override {
require(_id > 0 && _id <= haikuCounter, "Invalid haiku ID");
Haiku memory haikuToShare = haikus[_id - 1];
require(haikuToShare.author == msg.sender, "NotYourHaiku");
sharedHaikus[_to][_id] = true;
}
// Function to get haikus shared with the caller
function getMySharedHaikus()
external
view
override
returns (Haiku[] memory)
{
uint256 sharedHaikuCount;
for (uint256 i = 0; i < haikus.length; i++) {
if (sharedHaikus[msg.sender][i + 1]) {
sharedHaikuCount++;
}
}
Haiku[] memory result = new Haiku[](sharedHaikuCount);
uint256 currentIndex;
for (uint256 i = 0; i < haikus.length; i++) {
if (sharedHaikus[msg.sender][i + 1]) {
result[currentIndex] = haikus[i];
currentIndex++;
}
}
if (sharedHaikuCount == 0) {
revert NoHaikusShared();
}
return result;
}
// Custom errors
error HaikuNotUnique(); // Error for attempting to mint a non-unique haiku
error NotYourHaiku(); // Error for attempting to share a haiku not owned by the caller
error NoHaikusShared(); // Error for no haikus shared with the caller
}
直接复制代码,在Remix IDE部署HaikuNFT
2. Own a(n) Minimal Token Pin NFT
Solidity 接口
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Contract for an unburnable token
contract UnburnableToken {
string private salt = "value"; // A private string variable
// Mapping to track token balances of addresses
mapping(address => uint256) public balances;
uint256 public totalSupply; // Total supply of tokens
uint256 public totalClaimed; // Total number of tokens claimed
mapping(address => bool) private claimed; // Mapping to track whether an address has claimed tokens
// Custom errors
error TokensClaimed(); // Error for attempting to claim tokens again
error AllTokensClaimed(); // Error for attempting to claim tokens when all are already claimed
error UnsafeTransfer(address _to); // Error for unsafe token transfer
// Constructor to set the total supply of tokens
constructor() {
totalSupply = 100000000; // Set the total supply of tokens
}
// Public function to claim tokens
function claim() public {
// Check if all tokens have been claimed
if (totalClaimed >= totalSupply) revert AllTokensClaimed();
// Check if the caller has already claimed tokens
if (claimed[msg.sender]) revert TokensClaimed();
// Update balances and claimed status
balances[msg.sender] += 1000;
totalClaimed += 1000;
claimed[msg.sender] = true;
}
// Public function for safe token transfer
function safeTransfer(address _to, uint256 _amount) public {
// Check for unsafe transfer conditions, including if the target address has a non-zero ether balance
if (_to == address(0) || _to.balance == 0) revert UnsafeTransfer(_to);
// Ensure the sender has enough balance to transfer
require(balances[msg.sender] >= _amount, "Insufficient balance");
// Perform the transfer
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
}
直接复制代码,在Remix IDE部署
3. Own a(n) ERC20 Pin NFT
Solidity 接口
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
// Importing OpenZeppelin contracts for ERC20 and EnumerableSet functionalities
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
// Contract for weighted voting using ERC20 token
contract WeightedVoting is ERC20 {
string private salt = "value"; // A private string variable
using EnumerableSet for EnumerableSet.AddressSet; // Importing EnumerableSet for address set functionality
// Custom errors
error TokensClaimed(); // Error for attempting to claim tokens again
error AllTokensClaimed(); // Error for attempting to claim tokens when all are already claimed
error NoTokensHeld(); // Error for attempting to perform an action without holding tokens
error QuorumTooHigh(); // Error for setting a quorum higher than total supply
error AlreadyVoted(); // Error for attempting to vote more than once
error VotingClosed(); // Error for attempting to vote on a closed issue
// Struct to represent an issue
struct Issue {
EnumerableSet.AddressSet voters; // Set of voters
string issueDesc; // Description of the issue
uint256 quorum; // Quorum required to close the issue
uint256 totalVotes; // Total number of votes casted
uint256 votesFor; // Total number of votes in favor
uint256 votesAgainst; // Total number of votes against
uint256 votesAbstain; // Total number of abstained votes
bool passed; // Flag indicating if the issue passed
bool closed; // Flag indicating if the issue is closed
}
// Struct to represent a serialized issue
struct SerializedIssue {
address[] voters; // Array of voters
string issueDesc; // Description of the issue
uint256 quorum; // Quorum required to close the issue
uint256 totalVotes; // Total number of votes casted
uint256 votesFor; // Total number of votes in favor
uint256 votesAgainst; // Total number of votes against
uint256 votesAbstain; // Total number of abstained votes
bool passed; // Flag indicating if the issue passed
bool closed; // Flag indicating if the issue is closed
}
// Enum to represent different vote options
enum Vote {
AGAINST,
FOR,
ABSTAIN
}
// Array to store all issues
Issue[] internal issues;
// Mapping to track if tokens are claimed by an address
mapping(address => bool) public tokensClaimed;
uint256 public maxSupply = 1000000; // Maximum supply of tokens
uint256 public claimAmount = 100; // Amount of tokens to be claimed
string saltt = "any"; // Another string variable
// Constructor to initialize ERC20 token with a name and symbol
constructor(string memory _name, string memory _symbol)
ERC20(_name, _symbol)
{
issues.push(); // Pushing an empty issue to start from index 1
}
// Function to claim tokens
function claim() public {
// Check if all tokens have been claimed
if (totalSupply() + claimAmount > maxSupply) {
revert AllTokensClaimed();
}
// Check if the caller has already claimed tokens
if (tokensClaimed[msg.sender]) {
revert TokensClaimed();
}
// Mint tokens to the caller
_mint(msg.sender, claimAmount);
tokensClaimed[msg.sender] = true; // Mark tokens as claimed
}
// Function to create a new voting issue
function createIssue(string calldata _issueDesc, uint256 _quorum)
external
returns (uint256)
{
// Check if the caller holds any tokens
if (balanceOf(msg.sender) == 0) {
revert NoTokensHeld();
}
// Check if the specified quorum is higher than total supply
if (_quorum > totalSupply()) {
revert QuorumTooHigh();
}
// Create a new issue and return its index
Issue storage _issue = issues.push();
_issue.issueDesc = _issueDesc;
_issue.quorum = _quorum;
return issues.length - 1;
}
// Function to get details of a voting issue
function getIssue(uint256 _issueId)
external
view
returns (SerializedIssue memory)
{
Issue storage _issue = issues[_issueId];
return
SerializedIssue({
voters: _issue.voters.values(),
issueDesc: _issue.issueDesc,
quorum: _issue.quorum,
totalVotes: _issue.totalVotes,
votesFor: _issue.votesFor,
votesAgainst: _issue.votesAgainst,
votesAbstain: _issue.votesAbstain,
passed: _issue.passed,
closed: _issue.closed
});
}
// Function to cast a vote on a voting issue
function vote(uint256 _issueId, Vote _vote) public {
Issue storage _issue = issues[_issueId];
// Check if the issue is closed
if (_issue.closed) {
revert VotingClosed();
}
// Check if the caller has already voted
if (_issue.voters.contains(msg.sender)) {
revert AlreadyVoted();
}
uint256 nTokens = balanceOf(msg.sender);
// Check if the caller holds any tokens
if (nTokens == 0) {
revert NoTokensHeld();
}
// Update vote counts based on the vote option
if (_vote == Vote.AGAINST) {
_issue.votesAgainst += nTokens;
} else if (_vote == Vote.FOR) {
_issue.votesFor += nTokens;
} else {
_issue.votesAbstain += nTokens;
}
// Add the caller to the list of voters and update total votes count
_issue.voters.add(msg.sender);
_issue.totalVotes += nTokens;
// Close the issue if quorum is reached and determine if it passed
if (_issue.totalVotes >= _issue.quorum) {
_issue.closed = true;
if (_issue.votesFor > _issue.votesAgainst) {
_issue.passed = true;
}
}
}
}
直接复制代码,在Remix IDE部署WeightedVoting
- 获取链接
- X
- 电子邮件
- 其他应用
评论
发表评论