编译器
0.8.26+commit.8a97fa7a
文件 1 的 5:ComicBurn.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract ComicBurn is Ownable {
constructor() Ownable(msg.sender) {}
mapping(address => uint256[]) public userBurnTokens;
mapping(uint256 => bool) public animatedToken;
uint256 public maxSupply = 625;
uint256 public tokensToBurn = 10;
address public comicAddress = 0x21493e9fD8aEEc95bf7608A51c75333F40eB192A;
address public burnAddress = 0x000000000000000000000000000000000000dEaD;
mapping(uint256 => uint256) public tokenEditions;
uint256 public totalBurned;
bool public burnEnabled = false;
event BurnToken(uint256 token, uint256 timeStamp, address user);
event TokenUpdated(uint256 token, uint256 timeStamp, address user);
error BurnNotEnabled();
error InvalidTokenCount();
error MaxSupplyReached();
error InvalidToken();
error NotTokenOwner(uint256 tokenId);
error InvalidTokenType(uint256 tokenId);
function burn(uint256[] calldata tokenIds, uint256 _editionType) external {
if (!burnEnabled) revert BurnNotEnabled();
if (tokenIds.length != tokensToBurn) revert InvalidTokenCount();
if (totalBurned + tokenIds.length > maxSupply)
revert MaxSupplyReached();
IERC721 comic = IERC721(comicAddress);
if (
comic.ownerOf(tokenIds[0]) != msg.sender ||
tokenEditions[tokenIds[0]] != _editionType ||
animatedToken[tokenIds[0]]
) {
revert InvalidToken();
}
for (uint256 i = 1; i < tokenIds.length; i++) {
if (comic.ownerOf(tokenIds[i]) != msg.sender)
revert NotTokenOwner(tokenIds[i]);
if (tokenEditions[tokenIds[i]] != _editionType)
revert InvalidTokenType(tokenIds[i]);
if (animatedToken[tokenIds[i]])
revert InvalidTokenType(tokenIds[i]);
comic.transferFrom(msg.sender, burnAddress, tokenIds[i]);
userBurnTokens[msg.sender].push(tokenIds[i]);
emit BurnToken(tokenIds[i], block.timestamp, msg.sender);
}
uint256 tokenToUpdate = tokenIds[0];
emit TokenUpdated(tokenToUpdate, block.timestamp, msg.sender);
animatedToken[tokenToUpdate] = true;
totalBurned++;
}
function setMaxSupply(uint256 _maxSupply) public onlyOwner {
maxSupply = _maxSupply;
}
function setTokensToBurn(uint256 _tokensToBurn) public onlyOwner {
tokensToBurn = _tokensToBurn;
}
function isAnimated(uint256 _tokenId) public view returns (bool) {
return animatedToken[_tokenId];
}
function setBurnEnabled(bool _state) public onlyOwner {
burnEnabled = _state;
}
function setComicAddress(address _comicAddress) public onlyOwner {
comicAddress = _comicAddress;
}
function setTokenEditions(
uint256[] calldata _tokens,
uint256 _editionType
) public onlyOwner {
for (uint256 i = 0; i < _tokens.length; i++) {
tokenEditions[_tokens[i]] = _editionType;
}
}
function balanceOfBurned(address _user) public view returns (uint256) {
return userBurnTokens[_user].length;
}
}
文件 2 的 5:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 3 的 5:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 4 的 5:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 5 的 5:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
{
"compilationTarget": {
"contracts/ComicBurn.sol": "ComicBurn"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BurnNotEnabled","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTokenCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"InvalidTokenType","type":"error"},{"inputs":[],"name":"MaxSupplyReached","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NotTokenOwner","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeStamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"BurnToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeStamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"TokenUpdated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"animatedToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"balanceOfBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"_editionType","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"comicAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isAnimated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setBurnEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_comicAddress","type":"address"}],"name":"setComicAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokens","type":"uint256[]"},{"internalType":"uint256","name":"_editionType","type":"uint256"}],"name":"setTokenEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokensToBurn","type":"uint256"}],"name":"setTokensToBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenEditions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensToBurn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userBurnTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]