文件 1 的 13:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 13:CryptoDeddies.sol
pragma solidity ^0.8.4;
import "erc721a/contracts/ERC721A.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import 'base64-sol/base64.sol';
import "./EddieRenderer.sol";
contract CryptoDeddies is ERC721A, Ownable {
struct GhostData {
uint256 eddieTokenId;
uint256 eddieTokenSeed;
}
EddieRenderer public contractRenderer;
mapping(uint256 => GhostData) public ghostData;
error EddieGhostIsSoulbound();
event EddieGhostSpawned(uint256 indexed tokenId, uint256 indexed eddieTokenId, uint256 indexed eddieTokenSeed);
constructor(address _contractRenderer) ERC721A("CryptoDeddies", "DEDDIE") {
contractRenderer = EddieRenderer(_contractRenderer);
}
modifier verifyTokenId(uint256 tokenId) {
require(tokenId >= _startTokenId() && tokenId <= _totalMinted(), "Out of bounds");
_;
}
function _startTokenId() override internal pure virtual returns (uint256) {
return 1;
}
function spawnGhost(address to, uint256 eddieTokenId, uint256 eddieTokenSeed) external {
require(msg.sender == address(contractRenderer), "Only callable from contract");
_mintGhost(to, eddieTokenId, eddieTokenSeed);
}
function spawnGhostAdmin(address to, uint256 eddieTokenId, uint256 eddieTokenSeed) external onlyOwner {
_mintGhost(to, eddieTokenId, eddieTokenSeed);
}
function _mintGhost(address to, uint256 eddieTokenId, uint256 eddieTokenSeed) private {
_safeMint(to, 1);
uint256 tokenId = _totalMinted();
ghostData[tokenId] = GhostData({
eddieTokenId: eddieTokenId,
eddieTokenSeed: eddieTokenSeed
});
emit EddieGhostSpawned(tokenId, eddieTokenId, eddieTokenSeed);
}
function _beforeTokenTransfers(address from, address, uint256, uint256) internal pure override {
if (from != address(0)) {
revert EddieGhostIsSoulbound();
}
}
function setContractRenderer(address newAddress) external onlyOwner {
contractRenderer = EddieRenderer(newAddress);
}
function tokenURI(uint256 tokenId) override(ERC721A) public view verifyTokenId(tokenId) returns (string memory) {
require(_exists(tokenId), "Nonexistent token");
GhostData memory ghost = ghostData[tokenId];
uint256 eddieTokenId = ghost.eddieTokenId;
uint256 seed = ghost.eddieTokenSeed;
string memory image = contractRenderer.getGhostSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"CryptoDeddie Ghost #', Strings.toString(eddieTokenId),'",',
'"description": "CryptoDeddie Ghost is a memorialized ghost of your original CryptoEddie, forever soulbound to your wallet.",',
'"attributes":[',
contractRenderer.getTraitsMetadata(seed),
'{"trait_type":"Dead", "value":"True"}, {"trait_type":"Soulbound", "value":"True"}'
'],',
'"image": "data:image/svg+xml;base64,', Base64.encode(bytes(image)), '"}'
)
))
);
return string(abi.encodePacked('data:application/json;base64,', json));
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
}
文件 3 的 13:CryptoDeddiesV2.sol
pragma solidity ^0.8.4;
import "erc721a/contracts/ERC721A.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import 'base64-sol/base64.sol';
import "./EddieRenderer.sol";
import "./CryptoEddiesV2.sol";
contract CryptoDeddiesV2 is ERC721A, Ownable {
struct GhostData {
uint256 eddieTokenId;
uint256 eddieTokenSeed;
}
EddieRenderer public contractRenderer;
CryptoEddiesV2 public contractEddiesV2;
mapping(uint256 => GhostData) public ghostData;
error EddieGhostIsSoulbound();
event EddieGhostSpawned(uint256 indexed tokenId, uint256 indexed eddieTokenId, uint256 indexed eddieTokenSeed);
constructor(address _contractRenderer) ERC721A("CryptoDeddiesV2", "DEDDIEV2") {
contractRenderer = EddieRenderer(_contractRenderer);
}
modifier verifyTokenId(uint256 tokenId) {
require(tokenId >= _startTokenId() && tokenId <= _totalMinted(), "Out of bounds");
_;
}
function _startTokenId() override internal pure virtual returns (uint256) {
return 1;
}
function spawnGhost(address to, uint256 eddieTokenId, uint256 eddieTokenSeed) external {
require(msg.sender == address(contractEddiesV2), "Only callable from contract");
_mintGhost(to, eddieTokenId, eddieTokenSeed);
}
function spawnGhostAdmin(address to, uint256 eddieTokenId, uint256 eddieTokenSeed) external onlyOwner {
_mintGhost(to, eddieTokenId, eddieTokenSeed);
}
function _mintGhost(address to, uint256 eddieTokenId, uint256 eddieTokenSeed) private {
_safeMint(to, 1);
uint256 tokenId = _totalMinted();
ghostData[tokenId] = GhostData({
eddieTokenId: eddieTokenId,
eddieTokenSeed: eddieTokenSeed
});
emit EddieGhostSpawned(tokenId, eddieTokenId, eddieTokenSeed);
}
function _beforeTokenTransfers(address from, address, uint256, uint256) internal pure override {
if (from != address(0)) {
revert EddieGhostIsSoulbound();
}
}
function setContractRenderer(address newAddress) external onlyOwner {
contractRenderer = EddieRenderer(newAddress);
}
function setContractEddieV2(address newAddress) external onlyOwner {
contractEddiesV2 = CryptoEddiesV2(newAddress);
}
function tokenURI(uint256 tokenId) override(ERC721A) public view verifyTokenId(tokenId) returns (string memory) {
require(_exists(tokenId), "Nonexistent token");
GhostData memory ghost = ghostData[tokenId];
uint256 eddieTokenId = ghost.eddieTokenId;
uint256 seed = ghost.eddieTokenSeed;
string memory image = contractRenderer.getGhostSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"CryptoDeddie Ghost #', Strings.toString(eddieTokenId),'",',
'"description": "CryptoDeddie Ghost is a memorialized ghost of your original CryptoEddie, forever soulbound to your wallet.",',
'"attributes":[',
contractRenderer.getTraitsMetadata(seed),
'{"trait_type":"Dead", "value":"True"}, {"trait_type":"Soulbound", "value":"True"}'
'],',
'"image": "data:image/svg+xml;base64,', Base64.encode(bytes(image)), '"}'
)
))
);
return string(abi.encodePacked('data:application/json;base64,', json));
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
}
文件 4 的 13:CryptoEddies.sol
pragma solidity ^0.8.4;
import "erc721a/contracts/ERC721A.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import 'base64-sol/base64.sol';
import "./EddieRenderer.sol";
import "./CryptoDeddies.sol";
contract CryptoEddies is EddieRenderer, ERC721A, Ownable {
uint256 public constant MAX_TOKEN_SUPPLY = 3500;
uint256 public tier0_price = 0.01 ether;
uint256 public tier1_price = 0.015 ether;
uint256 public tier2_price = 0.02 ether;
uint256 public tier0_supply = 2000;
uint256 public tier1_supply = 1000;
uint256 public maxMintsPerPersonPublic = 150;
uint256 public maxMintsPerPersonWhitelist = 1;
uint public constant MAX_HP = 5;
CryptoDeddies public contractGhost;
enum MintStatus {
CLOSED,
WHITELIST,
PUBLIC
}
MintStatus public mintStatus = MintStatus.CLOSED;
bool public revealed = false;
mapping(uint256 => uint256) public seeds;
mapping(uint256 => uint) public hp;
event EddieDied(uint256 indexed tokenId);
event EddieRerolled(uint256 indexed tokenId);
event EddieSacrificed(uint256 indexed tokenId);
constructor() ERC721A("CryptoEddies", "EDDIE") {
}
modifier verifySupply(uint256 numEddiesToMint) {
require(numEddiesToMint > 0, "Mint at least 1");
require(_totalMinted() + numEddiesToMint <= MAX_TOKEN_SUPPLY, "Exceeds max supply");
_;
}
modifier verifyTokenId(uint256 tokenId) {
require(tokenId >= _startTokenId() && tokenId <= _totalMinted(), "Out of bounds");
_;
}
function _mintEddies(address to, uint256 numEddiesToMint) private verifySupply(numEddiesToMint) {
uint256 startTokenId = _startTokenId() + _totalMinted();
for(uint256 tokenId = startTokenId; tokenId < startTokenId+numEddiesToMint; tokenId++) {
_saveSeed(tokenId);
hp[tokenId] = MAX_HP;
}
_safeMint(to, numEddiesToMint);
}
function reserveEddies(address to, uint256 numEddiesToMint) external onlyOwner {
_mintEddies(to, numEddiesToMint);
}
function reserveEddiesToManyFolk(address[] calldata addresses, uint256 numEddiesToMint) external {
uint256 num = addresses.length;
for (uint256 i = 0; i < num; ++i) {
address to = addresses[i];
_mintEddies(to, numEddiesToMint);
}
}
function mintEddies(uint256 numEddiesToMint) external payable {
require(mintStatus == MintStatus.PUBLIC, "Public mint closed");
require(msg.value >= _getPrice(numEddiesToMint), "Incorrect ether" );
require(_numberMinted(msg.sender) + numEddiesToMint <= maxMintsPerPersonPublic, "Exceeds max mints");
_mintEddies(msg.sender, numEddiesToMint);
}
function _rerollEddie(uint256 tokenId) verifyTokenId(tokenId) private {
require(revealed == true, "Not revealed");
require(hp[tokenId] > 0, "No HP");
require(msg.sender == ownerOf(tokenId), "Not yours");
_saveSeed(tokenId);
_takeDamageHP(tokenId, msg.sender);
emit EddieRerolled(tokenId);
}
function rerollEddie(uint256 tokenId) external {
_rerollEddie(tokenId);
}
function rerollEddieMany(uint256[] calldata tokenIds) external {
uint256 num = tokenIds.length;
for (uint256 i = 0; i < num; ++i) {
uint256 tokenId = tokenIds[i];
_rerollEddie(tokenId);
}
}
function _saveSeed(uint256 tokenId) private {
seeds[tokenId] = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), tokenId, msg.sender)));
}
function burnSacrifice(uint256 tokenId) external {
require(msg.sender == ownerOf(tokenId), "Not yours");
_burn(tokenId);
if (hp[tokenId] > 0) {
hp[tokenId] = 0;
emit EddieDied(tokenId);
if (address(contractGhost) != address(0)) {
contractGhost.spawnGhost(msg.sender, tokenId, seeds[tokenId]);
}
}
emit EddieSacrificed(tokenId);
}
function _startTokenId() override internal pure virtual returns (uint256) {
return 1;
}
function tokensOfOwner(address owner) external view returns (uint256[] memory) {
unchecked {
uint256 tokenIdsIdx;
address currOwnershipAddr;
uint256 tokenIdsLength = balanceOf(owner);
uint256[] memory tokenIds = new uint256[](tokenIdsLength);
TokenOwnership memory ownership;
for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
ownership = _ownershipAt(i);
if (ownership.burned) {
continue;
}
if (ownership.addr != address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
tokenIds[tokenIdsIdx++] = i;
}
}
return tokenIds;
}
}
function _getPrice(uint256 numPayable) private view returns (uint256) {
uint256 numMintedAlready = _totalMinted();
return numPayable
* (numMintedAlready < tier0_supply ?
tier0_price
: ( (numMintedAlready < (tier0_supply+tier1_supply)) ? tier1_price : tier2_price));
}
function setPricing(uint256[] calldata pricingData) external onlyOwner {
tier0_supply = pricingData[0];
tier0_price = pricingData[1];
tier1_supply = pricingData[2];
tier1_price = pricingData[3];
tier2_price = pricingData[4];
require(tier0_supply + tier1_supply <= MAX_TOKEN_SUPPLY);
}
function setPublicMintStatus(uint256 _status) external onlyOwner {
mintStatus = MintStatus(_status);
}
function setMaxMints(uint256 _maxMintsPublic, uint256 _maxMintsWhitelist) external onlyOwner {
maxMintsPerPersonPublic = _maxMintsPublic;
maxMintsPerPersonWhitelist = _maxMintsWhitelist;
}
function setContractGhost(address newAddress) external onlyOwner {
contractGhost = CryptoDeddies(newAddress);
}
function setRevealed(bool _revealed) external onlyOwner {
revealed = _revealed;
}
error SteveAokiNotAllowed();
address public constant STEVE_AOKI_ADDRESS = 0xe4bBCbFf51e61D0D95FcC5016609aC8354B177C4;
function _beforeTokenTransfers(address from, address to, uint256 startTokenId, uint256 quantity) internal override {
if (to == STEVE_AOKI_ADDRESS) {
revert SteveAokiNotAllowed();
}
if (from == address(0) || to == address(0))
return;
for (uint256 tokenId = startTokenId; tokenId < startTokenId + quantity; ++tokenId) {
_takeDamageHP(tokenId, from);
}
}
function _takeDamageHP(uint256 tokenId, address mintGhostTo) private verifyTokenId(tokenId){
if (hp[tokenId] == 0)
return;
hp[tokenId] -= 1;
if (hp[tokenId] == 0) {
emit EddieDied(tokenId);
if (address(contractGhost) != address(0)) {
contractGhost.spawnGhost(mintGhostTo, tokenId, seeds[tokenId]);
}
}
}
function rewardHP(uint256 tokenId, uint hpRewarded) external onlyOwner verifyTokenId(tokenId) {
require(hp[tokenId] > 0, "Already dead");
hp[tokenId] += hpRewarded;
if (hp[tokenId] > MAX_HP)
hp[tokenId] = MAX_HP;
}
function rewardManyHP(uint256[] calldata tokenIds, uint hpRewarded) external {
uint256 num = tokenIds.length;
for (uint256 i = 0; i < num; ++i) {
uint256 tokenId = tokenIds[i];
if (hp[tokenId] > 0 ) {
hp[tokenId] += hpRewarded;
if (hp[tokenId] > MAX_HP)
hp[tokenId] = MAX_HP;
}
}
}
function getHP(uint256 tokenId) external view verifyTokenId(tokenId) returns(uint){
return hp[tokenId];
}
function numberMinted(address addr) external view returns(uint256){
return _numberMinted(addr);
}
bytes32 public merkleRoot = 0x0;
function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
merkleRoot = _merkleRoot;
}
function _verifyMerkle(bytes32[] calldata _proof, bytes32 _leaf) private view returns (bool) {
return MerkleProof.verify(_proof, merkleRoot, _leaf);
}
function verifyMerkle(bytes32[] calldata _proof, bytes32 _leaf) external view returns (bool) {
return _verifyMerkle(_proof, _leaf);
}
function verifyMerkleAddress(bytes32[] calldata _proof, address from) external view returns (bool) {
bytes32 leaf = keccak256(abi.encodePacked(from));
return _verifyMerkle(_proof, leaf);
}
function mintEddiesMerkle(bytes32[] calldata _merkleProof, uint256 numEddiesToMint) external payable {
require(mintStatus == MintStatus.WHITELIST || mintStatus == MintStatus.PUBLIC, "Merkle mint closed");
uint256 numMintedAlready = _numberMinted(msg.sender);
require(numMintedAlready + numEddiesToMint <= maxMintsPerPersonPublic, "Exceeds max mints");
uint256 numToMintFromWhitelist = 0;
if (numMintedAlready < maxMintsPerPersonWhitelist) {
numToMintFromWhitelist = (maxMintsPerPersonWhitelist - numMintedAlready);
}
uint256 numToMintPayable = numEddiesToMint - numToMintFromWhitelist;
require(msg.value >= _getPrice(numToMintPayable), "Incorrect ether sent" );
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(_verifyMerkle(_merkleProof, leaf), "Invalid proof");
_mintEddies(msg.sender, numEddiesToMint);
}
function _tokenURI(uint256 tokenId) private view returns (string memory) {
string[6] memory lookup = [ '0', '1', '2', '3', '4', '5'];
uint256 seed = seeds[tokenId];
string memory image = _getSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"CryptoEddie #', Strings.toString(tokenId),'",',
'"description": "CryptoEddies is an 100% on-chain experimental NFT character project with unique functionality, inspired by retro Japanese RPGs.",',
'"attributes":[',
_getTraitsMetadata(seed),
_getStatsMetadata(seed),
'{"trait_type":"HP", "value":',lookup[hp[tokenId]],', "max_value":',lookup[MAX_HP],'}'
'],',
'"image": "data:image/svg+xml;base64,', Base64.encode(bytes(image)), '"}'
)
))
);
return string(abi.encodePacked('data:application/json;base64,', json));
}
function _tokenUnrevealedURI(uint256 tokenId) private view returns (string memory) {
uint256 seed = seeds[tokenId];
string memory image = _getUnrevealedSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"CryptoEddie #', Strings.toString(tokenId),'",',
'"description": "CryptoEddies is an 100% on-chain experimental character art project, chillin on the Ethereum blockchain.",',
'"attributes":[{"trait_type":"Unrevealed", "value":"True"}],',
'"image": "data:image/svg+xml;base64,', Base64.encode(bytes(image)), '"}'
)
))
);
return string(abi.encodePacked('data:application/json;base64,', json));
}
function tokenURI(uint256 tokenId) override(ERC721A) public view verifyTokenId(tokenId) returns (string memory) {
if (revealed)
return _tokenURI(tokenId);
else
return _tokenUnrevealedURI(tokenId);
}
function _randStat(uint256 seed, uint256 div, uint256 min, uint256 max) private pure returns (uint256) {
return min + (seed/div) % (max-min);
}
function _getStatsMetadata(uint256 seed) private pure returns (string memory) {
string[11] memory lookup = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ];
string memory metadata = string(abi.encodePacked(
'{"trait_type":"Determination", "display_type": "number", "value":', lookup[_randStat(seed, 2, 2, 10)], '},',
'{"trait_type":"Love", "display_type": "number", "value":', lookup[_randStat(seed, 3, 2, 10)], '},',
'{"trait_type":"Cringe", "display_type": "number", "value":', lookup[_randStat(seed, 4, 2, 10)], '},',
'{"trait_type":"Bonk", "display_type": "number", "value":', lookup[_randStat(seed, 5, 2, 10)], '},',
'{"trait_type":"Magic Defense", "display_type": "number", "value":', lookup[_randStat(seed, 6, 2, 10)], '},'
));
return metadata;
}
function withdraw() external onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
}
文件 5 的 13:CryptoEddiesV2.sol
pragma solidity ^0.8.4;
import "erc721a/contracts/ERC721A.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import 'base64-sol/base64.sol';
import "./EddieRenderer.sol";
import "./CryptoDeddiesV2.sol";
import "./CryptoEddies.sol";
contract CryptoEddiesV2 is ERC721A, Ownable {
uint256 public constant MAX_TOKEN_SUPPLY = 3500;
uint public constant MAX_HP = 5;
CryptoDeddiesV2 public contractGhost;
CryptoEddies public contractEddieOG;
address public contractHpEffector;
bool public revealed = true;
bool public rerollingEnabled = true;
bool public claimEnabled = true;
bool public burnSacrificeEnabled = false;
mapping(uint256 => uint256) public ogTokenId;
mapping(uint256 => uint256) public seeds;
mapping(uint256 => uint) public hp;
event EddieDied(uint256 indexed tokenId);
event EddieRerolled(uint256 indexed tokenId);
event EddieSacrificed(uint256 indexed tokenId);
constructor(address _contractEddieOG) ERC721A("CryptoEddiesV2", "EDDIEV2") {
contractEddieOG = CryptoEddies(_contractEddieOG);
}
modifier verifyTokenId(uint256 tokenId) {
require(tokenId >= _startTokenId() && tokenId <= _totalMinted(), "Out of bounds");
_;
}
modifier onlyApprovedOrOwner(uint256 tokenId) {
require(
_ownershipOf(tokenId).addr == _msgSender() ||
getApproved(tokenId) == _msgSender(),
"Not approved nor owner"
);
_;
}
function claimMany(uint256[] calldata tokenIds) external {
require(claimEnabled == true);
uint256 num = tokenIds.length;
uint256 startTokenId = _startTokenId() + _totalMinted();
address sender = msg.sender;
for (uint256 i = 0; i < num; ++i) {
uint256 originalTokenId = tokenIds[i];
uint256 newTokenId = startTokenId + i;
contractEddieOG.transferFrom(sender, address(this), originalTokenId);
contractEddieOG.burnSacrifice(originalTokenId);
ogTokenId[newTokenId] = originalTokenId;
hp[newTokenId] = MAX_HP;
_saveSeed(newTokenId);
}
_mint(sender, num);
}
function _rerollEddie(uint256 tokenId) verifyTokenId(tokenId) private {
require(revealed == true, "Not revealed");
require(hp[tokenId] > 0, "No HP");
require(msg.sender == ownerOf(tokenId), "Not yours");
_saveSeed(tokenId);
_takeDamageHP(tokenId, msg.sender);
emit EddieRerolled(tokenId);
}
function rerollEddie(uint256 tokenId) external {
require(rerollingEnabled == true);
_rerollEddie(tokenId);
}
function rerollEddieMany(uint256[] calldata tokenIds) external {
require(rerollingEnabled == true);
uint256 num = tokenIds.length;
for (uint256 i = 0; i < num; ++i) {
uint256 tokenId = tokenIds[i];
_rerollEddie(tokenId);
}
}
function _saveSeed(uint256 tokenId) private {
seeds[tokenId] = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), tokenId, msg.sender)));
}
function burnSacrifice(uint256 tokenId) external onlyApprovedOrOwner(tokenId) {
require(burnSacrificeEnabled == true);
address ownerOfEddie = ownerOf(tokenId);
_burn(tokenId);
if (hp[tokenId] > 0) {
hp[tokenId] = 0;
_resetAndCancelVibing(tokenId);
emit EddieDied(tokenId);
if (address(contractGhost) != address(0)) {
contractGhost.spawnGhost(ownerOfEddie, tokenId, seeds[tokenId]);
}
}
emit EddieSacrificed(tokenId);
}
function _startTokenId() override internal pure virtual returns (uint256) {
return 1;
}
function tokensOfOwner(address owner) external view returns (uint256[] memory) {
unchecked {
uint256 tokenIdsIdx;
address currOwnershipAddr;
uint256 tokenIdsLength = balanceOf(owner);
uint256[] memory tokenIds = new uint256[](tokenIdsLength);
TokenOwnership memory ownership;
for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
ownership = _ownershipAt(i);
if (ownership.burned) {
continue;
}
if (ownership.addr != address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
tokenIds[tokenIdsIdx++] = i;
}
}
return tokenIds;
}
}
function setContractEddieOG(address newAddress) external onlyOwner {
contractEddieOG = CryptoEddies(newAddress);
}
function setContractGhost(address newAddress) external onlyOwner {
contractGhost = CryptoDeddiesV2(newAddress);
}
function setClaimEnabled(bool _enabled) external onlyOwner {
claimEnabled = _enabled;
}
function setContractHpEffector(address newAddress) external onlyOwner {
contractHpEffector = newAddress;
}
function setRevealed(bool _revealed) external onlyOwner {
revealed = _revealed;
}
function setRerollingEnabled(bool _enabled) external onlyOwner {
rerollingEnabled = _enabled;
}
function setBurnSacrificeEnabled(bool _enabled) external onlyOwner {
burnSacrificeEnabled = _enabled;
}
function _beforeTokenTransfers(address from, address to, uint256 startTokenId, uint256 quantity) internal override {
if (from == address(0) || to == address(0))
return;
for (uint256 tokenId = startTokenId; tokenId < startTokenId + quantity; ++tokenId) {
_takeDamageHP(tokenId, from);
}
}
function _takeDamageHP(uint256 tokenId, address mintGhostTo) private verifyTokenId(tokenId){
if (hp[tokenId] == 0)
return;
hp[tokenId] -= 1;
_resetAndCancelVibing(tokenId);
if (hp[tokenId] == 0) {
emit EddieDied(tokenId);
if (address(contractGhost) != address(0)) {
contractGhost.spawnGhost(mintGhostTo, tokenId, seeds[tokenId]);
}
}
}
function rewardManyHP(uint256[] calldata tokenIds, int hpRewarded) external {
require(owner() == _msgSender() || (contractHpEffector != address(0) && _msgSender() == contractHpEffector), "Not authorized");
uint256 num = tokenIds.length;
for (uint256 i = 0; i < num; ++i) {
uint256 tokenId = tokenIds[i];
if (hp[tokenId] > 0 ) {
int newHp = int256(hp[tokenId]) + hpRewarded;
if (newHp > int(MAX_HP))
newHp = int(MAX_HP);
else if (newHp <= 0) {
newHp = 0;
emit EddieDied(tokenId);
if (address(contractGhost) != address(0)) {
contractGhost.spawnGhost(ownerOf(tokenId), tokenId, seeds[tokenId]);
}
}
hp[tokenId] = uint256(newHp);
if (hpRewarded < 0) {
_resetAndCancelVibing(tokenId);
}
}
}
}
function getHP(uint256 tokenId) external view verifyTokenId(tokenId) returns(uint){
return hp[tokenId];
}
function numberMinted(address addr) external view returns(uint256){
return _numberMinted(addr);
}
function _tokenURI(uint256 tokenId) private view returns (string memory) {
string[6] memory lookup = [ '0', '1', '2', '3', '4', '5'];
uint256 seed = seeds[tokenId];
string memory image = contractEddieOG.getSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"CryptoEddie #', Strings.toString(tokenId),'",',
'"description": "CryptoEddies is an 100% on-chain experimental NFT character project with unique functionality, inspired by retro Japanese RPGs. Formerly known as CryptoEddie #', Strings.toString(ogTokenId[tokenId]),'.",',
'"attributes":[',
contractEddieOG.getTraitsMetadata(seed),
_getStatsMetadata(seed),
'{"trait_type":"Vibing?", "value":', (vibingStartTimestamp[tokenId] != NULL_VIBING) ? '"Yes"' : '"Nah"', '},',
'{"trait_type":"HP", "value":',lookup[hp[tokenId]],', "max_value":',lookup[MAX_HP],'}'
'],',
'"image": "data:image/svg+xml;base64,', Base64.encode(bytes(image)), '"}'
)
))
);
return string(abi.encodePacked('data:application/json;base64,', json));
}
function _tokenUnrevealedURI(uint256 tokenId) private view returns (string memory) {
uint256 seed = seeds[tokenId];
string memory image = contractEddieOG.getUnrevealedSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"CryptoEddie #', Strings.toString(tokenId),'",',
'"description": "CryptoEddies is an 100% on-chain experimental character art project, chillin on the Ethereum blockchain.",',
'"attributes":[{"trait_type":"Unrevealed", "value":"True"}],',
'"image": "data:image/svg+xml;base64,', Base64.encode(bytes(image)), '"}'
)
))
);
return string(abi.encodePacked('data:application/json;base64,', json));
}
function tokenURI(uint256 tokenId) override(ERC721A) public view verifyTokenId(tokenId) returns (string memory) {
if (revealed)
return _tokenURI(tokenId);
else
return _tokenUnrevealedURI(tokenId);
}
function _randStat(uint256 seed, uint256 div, uint256 min, uint256 max) private pure returns (uint256) {
return min + (seed/div) % (max-min);
}
function _getStatsMetadata(uint256 seed) private pure returns (string memory) {
string[11] memory lookup = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ];
string memory metadata = string(abi.encodePacked(
'{"trait_type":"Determination", "display_type": "number", "value":', lookup[_randStat(seed, 2, 2, 10)], '},',
'{"trait_type":"Love", "display_type": "number", "value":', lookup[_randStat(seed, 3, 2, 10)], '},',
'{"trait_type":"Cringe", "display_type": "number", "value":', lookup[_randStat(seed, 4, 2, 10)], '},',
'{"trait_type":"Bonk", "display_type": "number", "value":', lookup[_randStat(seed, 5, 2, 10)], '},',
'{"trait_type":"Magic Defense", "display_type": "number", "value":', lookup[_randStat(seed, 6, 2, 10)], '},'
));
return metadata;
}
function withdraw() external onlyOwner {
uint balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
bool public isVibingEnabled = false;
mapping(uint256 => uint256) private vibingStartTimestamp;
mapping(uint256 => uint256) private vibingTotalTime;
uint256 private constant NULL_VIBING = 0;
event EventStartVibing(uint256 indexed tokenId);
event EventEndVibing(uint256 indexed tokenId);
event EventForceEndVibing(uint256 indexed tokenId);
function getVibingInfoForToken(uint256 tokenId) external view returns (uint256 currentVibingTime, uint256 totalVibingTime)
{
currentVibingTime = 0;
uint256 startTimestamp = vibingStartTimestamp[tokenId];
if (startTimestamp != NULL_VIBING) {
currentVibingTime = block.timestamp - startTimestamp;
}
totalVibingTime = currentVibingTime + vibingTotalTime[tokenId];
}
function setVibingEnabled(bool allowed) external onlyOwner {
require(allowed != isVibingEnabled);
isVibingEnabled = allowed;
}
function _toggleVibing(uint256 tokenId) private onlyApprovedOrOwner(tokenId)
{
require(hp[tokenId] > 0);
uint256 startTimestamp = vibingStartTimestamp[tokenId];
if (startTimestamp == NULL_VIBING) {
require(isVibingEnabled, "Disabled");
vibingStartTimestamp[tokenId] = block.timestamp;
emit EventStartVibing(tokenId);
} else {
vibingTotalTime[tokenId] += block.timestamp - startTimestamp;
vibingStartTimestamp[tokenId] = NULL_VIBING;
emit EventEndVibing(tokenId);
}
}
function toggleVibing(uint256[] calldata tokenIds) external {
uint256 num = tokenIds.length;
for (uint256 i = 0; i < num; ++i) {
uint256 tokenId = tokenIds[i];
_toggleVibing(tokenId);
}
}
function _resetAndCancelVibing(uint256 tokenId) private {
if (vibingStartTimestamp[tokenId] != NULL_VIBING) {
vibingStartTimestamp[tokenId] = NULL_VIBING;
emit EventEndVibing(tokenId);
}
if (vibingTotalTime[tokenId] != NULL_VIBING)
vibingTotalTime[tokenId] = NULL_VIBING;
}
function _adminForceStopVibing(uint256 tokenId) private {
require(vibingStartTimestamp[tokenId] != NULL_VIBING, "Character not vibing");
uint256 deltaTime = block.timestamp - vibingStartTimestamp[tokenId];
vibingTotalTime[tokenId] += deltaTime;
vibingStartTimestamp[tokenId] = NULL_VIBING;
emit EventEndVibing(tokenId);
emit EventForceEndVibing(tokenId);
}
function adminForceStopVibing(uint256[] calldata tokenIds) external onlyOwner {
uint256 num = tokenIds.length;
for (uint256 i = 0; i < num; ++i) {
uint256 tokenId = tokenIds[i];
_adminForceStopVibing(tokenId);
}
}
}
文件 6 的 13:ERC721A.sol
pragma solidity ^0.8.4;
import './IERC721A.sol';
interface ERC721A__IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
contract ERC721A is IERC721A {
struct TokenApprovalRef {
address value;
}
uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
uint256 private constant _BITPOS_NUMBER_MINTED = 64;
uint256 private constant _BITPOS_NUMBER_BURNED = 128;
uint256 private constant _BITPOS_AUX = 192;
uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
uint256 private constant _BITPOS_START_TIMESTAMP = 160;
uint256 private constant _BITMASK_BURNED = 1 << 224;
uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;
uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;
uint256 private constant _BITPOS_EXTRA_DATA = 232;
uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
uint256 private _currentIndex;
uint256 private _burnCounter;
string private _name;
string private _symbol;
mapping(uint256 => uint256) private _packedOwnerships;
mapping(address => uint256) private _packedAddressData;
mapping(uint256 => TokenApprovalRef) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
function _nextTokenId() internal view virtual returns (uint256) {
return _currentIndex;
}
function totalSupply() public view virtual override returns (uint256) {
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
function _totalMinted() internal view virtual returns (uint256) {
unchecked {
return _currentIndex - _startTokenId();
}
}
function _totalBurned() internal view virtual returns (uint256) {
return _burnCounter;
}
function balanceOf(address owner) public view virtual override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
}
function _numberMinted(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
function _numberBurned(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
function _getAux(address owner) internal view returns (uint64) {
return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
}
function _setAux(address owner, uint64 aux) internal virtual {
uint256 packed = _packedAddressData[owner];
uint256 auxCasted;
assembly {
auxCasted := aux
}
packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
_packedAddressData[owner] = packed;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
}
function _baseURI() internal view virtual returns (string memory) {
return '';
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return address(uint160(_packedOwnershipOf(tokenId)));
}
function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnershipOf(tokenId));
}
function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnerships[index]);
}
function _initializeOwnershipAt(uint256 index) internal virtual {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr)
if (curr < _currentIndex) {
uint256 packed = _packedOwnerships[curr];
if (packed & _BITMASK_BURNED == 0) {
while (packed == 0) {
packed = _packedOwnerships[--curr];
}
return packed;
}
}
}
revert OwnerQueryForNonexistentToken();
}
function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
ownership.addr = address(uint160(packed));
ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
ownership.burned = packed & _BITMASK_BURNED != 0;
ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
}
function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
assembly {
owner := and(owner, _BITMASK_ADDRESS)
result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
}
}
function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
assembly {
result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
}
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ownerOf(tokenId);
if (_msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_tokenApprovals[tokenId].value = to;
emit Approval(owner, to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId].value;
}
function setApprovalForAll(address operator, bool approved) public virtual override {
if (operator == _msgSenderERC721A()) revert ApproveToCaller();
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return
_startTokenId() <= tokenId &&
tokenId < _currentIndex &&
_packedOwnerships[tokenId] & _BITMASK_BURNED == 0;
}
function _isSenderApprovedOrOwner(
address approvedAddress,
address owner,
address msgSender
) private pure returns (bool result) {
assembly {
owner := and(owner, _BITMASK_ADDRESS)
msgSender := and(msgSender, _BITMASK_ADDRESS)
result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
}
}
function _getApprovedSlotAndAddress(uint256 tokenId)
private
view
returns (uint256 approvedAddressSlot, address approvedAddress)
{
TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
assembly {
approvedAddressSlot := tokenApproval.slot
approvedAddress := sload(approvedAddressSlot)
}
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
assembly {
if approvedAddress {
sstore(approvedAddressSlot, 0)
}
}
unchecked {
--_packedAddressData[from];
++_packedAddressData[to];
_packedOwnerships[tokenId] = _packOwnershipData(
to,
_BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
);
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
if (_packedOwnerships[nextTokenId] == 0) {
if (nextTokenId != _currentIndex) {
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, '');
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
transferFrom(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
bytes4 retval
) {
return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
function _mint(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
uint256 toMasked;
uint256 end = startTokenId + quantity;
assembly {
toMasked := and(to, _BITMASK_ADDRESS)
log4(
0,
0,
_TRANSFER_EVENT_SIGNATURE,
0,
toMasked,
startTokenId
)
for {
let tokenId := add(startTokenId, 1)
} iszero(eq(tokenId, end)) {
tokenId := add(tokenId, 1)
} {
log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
}
}
if (toMasked == 0) revert MintToZeroAddress();
_currentIndex = end;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
function _mintERC2309(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);
_currentIndex = startTokenId + quantity;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal virtual {
_mint(to, quantity);
unchecked {
if (to.code.length != 0) {
uint256 end = _currentIndex;
uint256 index = end - quantity;
do {
if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (index < end);
if (_currentIndex != end) revert();
}
}
}
function _safeMint(address to, uint256 quantity) internal virtual {
_safeMint(to, quantity, '');
}
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
address from = address(uint160(prevOwnershipPacked));
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
if (approvalCheck) {
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
assembly {
if approvedAddress {
sstore(approvedAddressSlot, 0)
}
}
unchecked {
_packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;
_packedOwnerships[tokenId] = _packOwnershipData(
from,
(_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
);
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
if (_packedOwnerships[nextTokenId] == 0) {
if (nextTokenId != _currentIndex) {
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
unchecked {
_burnCounter++;
}
}
function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
uint256 packed = _packedOwnerships[index];
if (packed == 0) revert OwnershipNotInitializedForExtraData();
uint256 extraDataCasted;
assembly {
extraDataCasted := extraData
}
packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
_packedOwnerships[index] = packed;
}
function _extraData(
address from,
address to,
uint24 previousExtraData
) internal view virtual returns (uint24) {}
function _nextExtraData(
address from,
address to,
uint256 prevOwnershipPacked
) private view returns (uint256) {
uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
}
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
function _toString(uint256 value) internal pure virtual returns (string memory str) {
assembly {
str := add(mload(0x40), 0x80)
mstore(0x40, str)
let end := str
for { let temp := value } 1 {} {
str := sub(str, 1)
mstore8(str, add(48, mod(temp, 10)))
temp := div(temp, 10)
if iszero(temp) { break }
}
let length := sub(end, str)
str := sub(str, 0x20)
mstore(str, length)
}
}
}
文件 7 的 13:EddieData.sol
pragma solidity ^0.8.0;
contract EddieData {
string[] public fullPalettes = ['ff00ff', '000000', 'ffffff', 'ff0000', '00ff00', '0000ff', '65656e', '212124', '343438', '212123', 'f83a00', 'fff200', 'ff5900', '0096ff', '2e07f2', '1f1f21', '858ac7', 'e31e27', '7e00de', 'f200ff', '292929', 'f5368f', 'ffff00', 'ff8282', '599cff', 'b2e1f8', 'ff9696', 'ff4747', '919191', 'b8b8b8', 'ff5e00', 'ff995e', 'ff3300', 'd32027', 'f3e106', 'd46a6d', '172f3b', '163545', 'f73b3b', '2c7899', '3fabd9', '2e81a5', '2f82a6', '44b0de', '237843', '47a66b', 'f3f700', 'ba6047', 'a85740', '592f23', '44c3c9', 'ede068', 'ffed4f', '68b84d', '599e42', '038604', '9c9083', '7a7166', '696158', '7ddcff', '00bbff', '009bd4', '5ed4ff', 'edda9d', 'eda200', '004f24', '00c458', '00a44b', '00ad4e', 'ff9500', 'f7ff0f', 'eaf041', 'cfd60d', 'faf5aa', 'ced439', 'b5b535', 'ffa3a3', 'a37b46', '966930', '579aff', '217aff', '4eff00', 'fffc00', 'ffff26', '007dfc', '0067cf', 'fcca97', '8a633c', 'cb8d52', 'fcf0c6', '180d1f', 'a16010', 'e5a925', '3a3a3a', '2057a8', 'b82323', 'ff3030', '3c3c3c', '0004fa', '2b2b2b', 'ff0009', '3150d6', '7c541a', 'ba2b00', 'bfb731', '505050', '729144', '9aa6c1', '3f3556', 'd246e8', 'e74dff', '00974c', '9ec45c', '20d47a', 'eded61', '78573e', 'b89174', '2b478f', '0024ff', '363b3c', '202324', '3587ab', '0044ff', '0145fd', 'b4633b', 'b5643b', '40b2e6', '83c6e5', '115c52', 'ffcc99', '64c0e8', '3a8228', 'fcd502', '165c58', 'f7c328', '8a1212', '008787', '2c3aa8', '8a3c3c', 'e8fd4d', '439958', '5e83ec', '00a800', '006600', '404040', 'c5b2a0', 'fd8c69', 'f7e83e', 'f75a3e', 'fccf03', '68d4cc', 'be8ade', 'b778de', '568746', '67ab50', 'fce2a9', '6edbb7', 'fcb39d', '79dbba', 'c74832', '40cfbc', '7dd8ff', 'dbf4ff', '9ce1ff', 'fbdd97', 'f9de9a', 'f9de9b', 'fade9a', 'f9df9b', 'fadf9b', 'fade9b', 'f8dfa0', 'f8e0a0', 'f7e0a0', 'f5e1a6', 'f4e2a6', 'f5e2a6', 'f4e2a7', 'f5e2a7', 'f2e4ad', 'f3e4ad', 'f2e3ad', 'efe6b5', 'efe5b4', 'f0e5b5', 'efe6b4', 'efe5b5', 'ece8bc', 'ece9bd', 'ece8bd', 'ece9bc', 'e9ebc5', 'e8ebc5', 'e9eac5', 'e9ebc4', 'e6edcd', 'e5eecd', 'e5eece', 'e6eecd', 'e5edcd', 'e5edce', 'e2f0d5', 'e2efd6', 'e2f0d6', 'e2efd5', 'dff2de', 'dcf4e5', 'dcf4e4', 'dcf5e5', 'dbf4e5', 'dcf5e4', 'd9f7ec', 'd9f6ec', 'd7f9f2', 'd7f8f2', 'd6f8f2', 'd4f9f7', 'd4faf7', 'd3fbfb', 'b7c6e8', 'e5edff', 'fae848', 'fae248'];
bytes[] public eyes = [
bytes(hex'840003061700020616000206040001020d000106090701020a00040604070108040701020a0004060307010801070108030701020d0001060907010217000102'),
bytes(hex'c400010201090100010113000102010903020200040a03000101090001020101010201090302010a010b020a0100020101020b000102010901020200030a0300010101020b0003021700010117000101'),
bytes(hex'e300020e0300020e0d00040e0202030e0202010e0f00010e0202010e0100010e0202010e1000020e0300020e'),
bytes(hex'd300010101020d00040201000402010101020a0004020205030202030102010101020d000102020501020100010202030102010101020d000402010004020101'),
bytes(hex'e200040d0100040d0c00040d01020101030d01020101010d0f00010d01020101010d0100010d01020101010d0f00040d0100040d'),
bytes(hex'e200040c0100040c0c00040c01020101030c01020101010c0f00010c01020101010c0100010c01020101010c0f00040c0100040c'),
bytes(hex'e30001010400010113000101020001011300010104000101'),
bytes(hex'df000b011000030102000102010111000301'),
bytes(hex'df00050f0210020f0210010f0f00010f0210020f0210010f11000110020f01000110020f'),
bytes(hex'df0003110212021302120213100001120213021202130112110001130212010001130212'),
bytes(hex'e2000101010001010200010101000101110001010400010111000101010001010200010101000101'),
bytes(hex'e200040101000301100001020201020001020201'),
bytes(hex'e30001010400010111000101010001010200010101000101'),
bytes(hex'e200030102000301110001020101020001020101'),
bytes(hex'9c00070110000101060201010f0001010802010101020d00010102020101030201010102010101020a000401040201030302010101020d00010102020101030201010102010101020d00010103020301020201010f0001010602010111000601'),
bytes(hex'9c00070110000101060201010f0001010802010101020d00010101020117010101170102011701010117010101020a00040102020118030201180102010101020d0001010202011801010102010101180102010101020d000101020201180102010101020118010201010f0001010102011803020118010111000601'),
bytes(hex'9b000801010001020d0001010816010101020c00010108160101010001020c0001010216010103160101011601010e000101081601010e0001010216010103160101011601010e00010103160301021601010f000101081610000801'),
bytes(hex'e200031402000314100001140115011402000114011501141000031402000314'),
bytes(hex'e2000302020003021000020201010200010102021000030202000302'),
bytes(hex'e200030202000302100001020101010202000102010101021000030202000302'),
bytes(hex'e300030101000301110001020101020001020101120001020101020001020101'),
bytes(hex'cc0001160300011613000b0301030a0001160103010203160102061601160c000b0301030c00011603000116'),
bytes(hex'e200030102000301110001020101020001020101120001020101020001020101'),
bytes(hex'cc000101030001011100020105000101110001020101030001010102110001020101030001010102'),
bytes(hex'b2000319140005191300011903010119030001010f00011901010103010101190100020101020f000119030101190200010101020f0005191200041914000219'),
bytes(hex'e200030102000301110001020101020001020101120001010102020001010102'),
bytes(hex'e3000301010003011100011a0101011a0100011a0101011a1100031a0100031a'),
bytes(hex'e2000301020003011100010201010200010201011200020202000202'),
bytes(hex'e900010110000401010002010102110001020101030001010102'),
bytes(hex'e200020117000102020101000301110001020101030001010102'),
bytes(hex'e200020105000101110001020201010002010102110001020101030001010102'),
bytes(hex'e200030102000301290001010102030001010102')
];
string[] public eyes_traits = [
'Virtual Reality',
'Scouter',
'Glasses',
'3D Glasses',
'Big Blue Glasses',
'Big Red Glasses',
'Shut',
'Pirate',
'Future Too Bright',
'Stunners',
'RIP',
'Smug',
'Overjoyed',
'Sus',
'Good Face',
'Sad Face',
'Happy Note',
'Corrupted',
'Dizzy',
'Low Key Shook',
'Optimistic',
'Maximalist',
'Watchful',
'Worried',
'Terminatooor',
'Senpai',
'Stoney Baloney',
'Skyward',
'Raised Left',
'Raise Right',
'U Mad Bro',
'Naughty'
];
uint8[] public eyes_indices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
bytes[] public mouths = [
bytes(hex'ff004400010118000301'),
bytes(hex'ff004500010101000101010001011400010101000101'),
bytes(hex'ff00450001010300010114000301'),
bytes(hex'ff004400010118000101021b010115000203'),
bytes(hex'ff001000010117000c010d0001010a1c0e000101021c011d031c011d021c0f000101071c11000101021c011d021c13000101031c15000101011c010116000101'),
bytes(hex'ff001000010117000c010d0001010a030e0001010203021e0103021e02030f0001010703110001010103021e0203130001010303150001010103010116000101'),
bytes(hex'2d000102300001022e0001021700010248000102170001022f00010229000101011f0202012015000201'),
bytes(hex'ff005c000201'),
bytes(hex'ff004300010f0600010f1100060f'),
bytes(hex'ff005c0002010102010101020201'),
bytes(hex'ff00460003011500010101000101'),
bytes(hex'ff00460003011400010103000101'),
bytes(hex'ff005e000301'),
bytes(hex'ff005c000601')
];
string[] public mouths_traits = [
'Smirk',
'Uwu',
'Smile',
'Silly',
'Grey Bandana',
'Red Bandana',
'Smoking',
'Hmmm',
'Big Honkin Smile',
'Buck',
'Micro Sad',
'Sad',
'Blah',
'Unsatisfied'
];
uint8[] public mouths_indices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13];
bytes[] public hair = [
bytes(hex'200009020e000102090101020c000102010103240625010101020a000102010102240925010101020500050201010124062502000225010101020500010205010124052504000125010101020500010201010424062504260125010106000202030114000302'),
bytes(hex'200009020e000102090101020c00010201010921010101020a0001020101042101220121012201210122022101010102090001020101042105220221010101020a0001010b210101010001020900010101210b23020101020b000c230101010214000201010216000102'),
bytes(hex'200009020e000102090103020a00010201010129022a022b07010102080001020101022a022b0201072a01010102070001020101012a022b0101092a0101010208000101012a012b01010a2a0101010208000101012a01010a2a01010102'),
bytes(hex'200009020e000102090101020c000102010103270628010101020a000102010102270928010101020500050201010127062802000228010101020500010205010127052804000128010101020500010201010427062804260128010106000202030114000302'),
bytes(hex'200009020e000102090101020c0001020101032c062d010101020a0001020101022c092d01010102050005020101012c062d0201022d01010102050001020501012c052d0401012d01010102050001020101042c062d042e012d010106000202030114000302'),
bytes(hex'0b00010201010202130001020101012f02010102110001020101012f0130022f010101020f0001020101033102300131010101020d0001020101012f0630012f010101020b0001020101012f01300731010101020b000102010101310730022f010101020c000a31'),
bytes(hex'200009020e00020204010102030101020c0002020101043501010335010101020b0001020101013501360137010201010236010201010135010101020a0001020101013509360101010209000102010101350a3601010102090001020101013502360300023603000101010209000102010102360900010101020b0002360900010101020b0002360900010101020b0002360900010101020c000136'),
bytes(hex'3a00050211000202050102020e00010202010532020101020c00010201010932010101020a000102010101330a34010101020b0001330a34'),
bytes(hex'2800010216000102010101020e00070201010102010101020c00010207010202010101020b00010201010a02010101020900010201010b020101010209000102010103020300020203000101010209000102010102020900010101020b0002020900010101020b0002020900010101020b0002020900010101020c000102'),
bytes(hex'2100020201000202010002020f0001020201010202010102020102020c000102010102380101023801010238020101020a000102010102380139013802390138013903380101010209000102010101380a390138010108000102010101380c39010108000102010103390300023903000201010208000102010102390900010101020b0002390900010101020b0002390900010101020b0002390900010101020c000139'),
bytes(hex'090007020e00030204010102020102020b0001020301043b0101023b02010102090001020101043b033c013b023c023b01010102070001020101023b0b3c01010102060001020101023b043c023d013c023d013c013d013c013b01010102050001020101013b033c0a3d023c01010102040001020101013b013c013d013c033d0600023d013c01010102040001020101013b013c033d0900013d013c01010102040002020101023c023d0900023d01010102040001020101023c033d0900013d01010102050001020101023c033d0900013d01010102060001020101013c0200013d130001020101013d17000101013d160001020101'),
bytes(hex'090007020f000202070102020c00010202010738020101020a000102010103380139013802390138013902380101010208000102010102380a3901380101010206000102010102380439013a0339013a0339010101020600010201010539073a03390101010204000102010102380239023a0700023a01390101010204000102010101380239023a0900023a0101010204000102010101380139013a0139013a0900023a01010102040001020101013a0139033a0900013a0101010206000102010101390100023a0b00010206000102010101390200013a130001020101013a160001020101013a160001020101'),
bytes(hex'200009020e000102090101020c00010201010938010101020a0001020101023809390101010209000102010101380a39010101020900010201010b3901010102090001020101033908000101010209000102010102390900010101020b0002390900010101020b0002390900010101020b0002390900010101020c000139'),
bytes(hex'390008020e000202080101020c0001020201083e010101020a0001020101023e093c01010102080001020101023e0a3c01010102080001020101013e073c0100033c01010102080001020101043c080001010102080001020101033c0900010101020b00023c0900010101020b00023c0900010101020c00013c2b0001020101013c150001020101023c14000202'),
bytes(hex'2800010216000102010101020e0007020101013f010101020c0001020701013f0140010101020b00010201010a40010101020900010201010b400101010209000102010103400300024003000101010209000102010102400900010101020b0002400900010101020b0002400900010101020b0002400900010101020c000140'),
bytes(hex'2800010216000102010101020e00070201010138010101020c000102070101380139010101020b00010201010a39010101020900010201010b390101010209000102010103390300023903000101010209000102010102390900010101020b0002390900010101020b0002390900010101020b0002390900010101020c000139'),
bytes(hex'2100010205000102100001020101010203000102010101020e00010201010103010101020100010201010103010101020d00010201010203010101000101020301010102'),
bytes(hex'0a0001020141010215000202014103021100010206410102100001410342014101430142014101020e00014104440142014101440142014101020e00014107440141100003410344024113000341'),
bytes(hex'0b00010203010102110002020101014501010145010101020f00010204010145030101020d00010201010846010101020b00010201010346010201010146010201010246010102020800010201010b460301010209000346014709450101010209000246014702000745010101020a000246014715000146014716000146014716000247170001471700014717000148'),
bytes(hex'080001020201010203000102010101020d000102010102490101030201010149010101020c00010201010149014602010102010101490146010101020c000102010103460101010001010246010101020e0001010246010102000146020001020d000249064601490e0001490246074a01460d0001490146014a0700014a0d000146014a16000146014a16000146014a16000146014a1700014a'),
bytes(hex'2100010205000102100001020101010203000102010101020e00010201010102010101020100010201010102010101020d00010201010202010101000101020201010102'),
bytes(hex'08000b020c00020203010302030102020b000102010103020101010201010302010101020b00010201010102014c01020101010001010102014c0102010101020b00010201000102014c0102010102000102014c0102010101020c000a02010101020b00020216000102170001021700010217000102'),
bytes(hex'05000402020003020200040209000102020104020101040202010102090001020101014b0101020201010116010102020101011601010102090001020101014b0116020103160201021601010102090001020101024b091601010102090001020101024b011601030216010302160103011601010102090001020101034b081601010b000101'),
bytes(hex'ff00'),
bytes(hex'090004021300020203010302100001020101034d0301010211000201014e034d010101020d000102020101000101044e014d010101020b0001020101094e014d010101020900010201010b4e01010102090001020101034e0300024e030001010102090001020101024e0900010101020b00024e0900010101020b00024e0900010101020b00024e0900010101020c00014e'),
bytes(hex'1d0003021400010203010102120001020101034f0101120001020101014f025003011000010202010b500b00010202000b500a000102020003501500025016000250160002501600025017000150'),
bytes(hex'1d000302140001020301010212000102010103530101120001020101035303011000010202010b530b00010202000b530a000102020003531500025316000253160002531600025317000153'),
bytes(hex'800001510152015101520151015203510e0003510152015101520151015203510d0003511500025116000251160002511600025117000151'),
bytes(hex'63000254170002541700015401550b5401550800025402550b54015507000254'),
bytes(hex'6300025a1700025a17000e5a0800105a0700025a')
];
string[] public hair_traits = [
'Black Hat',
'Bear Market Hat',
'Cap Front',
'Topo Hat',
'Chill Green Hat',
'Poop',
'Froggy',
'Eric',
'Old But Still Cool',
'Straight Bussin',
'Clowin',
'Success Perm',
'Poppin',
'Neetori',
'Blonde',
'Cool Guy',
'Devil Horns',
'Leaf',
'Ducky',
'Pipichu',
'Catbot',
'Easter',
'King',
'Bald',
'90s',
'3000',
'Sun Bun',
'Too Cool',
'Blue Bandana',
'Black Bandana'
];
uint8[] public hair_indices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,23,24,25,26,27,28,29];
bytes[] public bodies = [
bytes(hex'ff006e000102010101561400010201010356010112000102010104560157015804560101010209000102010103560159015701580659010101020800010201010256025901570158035901580259010101020800010201010256015901570158075901010102080001020101025601590157015802590158045901010102080001020101025601590157015805590158015901010102080001020101025601590157015801590158055901010102'),
bytes(hex'ff006e0001020101015b140001020101035b01011200010201010a5b01010102090001020101065b065c01010102080001020101025b025c045b045c01010102080001020101035b055c045b01010102080001020101045b085c01010102080001020101025b015c035b065c01010102080001020101025b035c035b045c01010102'),
bytes(hex'ff006e0001020101015f140001020101035f01011200010201010a5f01010102090001020101035f096001010102080001020101025f0a6001010102080001020101025f0a6001010102080001020101025f0a6001010102080001020101025f0a6001010102080001020101025f0a6001010102'),
bytes(hex'ff006d0001020101025d140001020201025d0101120002020101045d0101015d0101025d0c0001020101025d0101025d0101015d0101015d0d0001020101015d02000101055d120006011200065e1200015e0400015e1200015e0400015e'),
bytes(hex'ff00eb000561120006612a00010304000103'),
bytes(hex'ff00eb00050214000302'),
bytes(hex'ff008800010101631600046301010100010102630e00026301000363010102630f0001630300016301010363130005641200066312000163040001631200016304000163'),
bytes(hex'ff00890001651600046501010100010102650e00026501000365010102650f000165030001650101036513000366010301661200066512000165040001651200016504000165'),
bytes(hex'ff00b800010316000303070001030e0002030100050201000103100006621200016204000162'),
bytes(hex'ff008900016f1600096f0e00026f0100026f0370016f0f00016f02710100016f017001720170016f010001710e0002710100016f0370016f010001711000066f1200016f0400016f1200016f0400016f'),
bytes(hex'ff008900016a1600046a0101016b0101026a0e00026a0100026a0101016c0101016a0f00016a0300016a0101016b0101016a13000268010102681200066912000169040001691200016904000169'),
bytes(hex'ff00890001021600040201010167010102020e000202010002020101010a010101020f000102030001020101010a0101010213000268010102681200066912000169040001691200016904000169'),
bytes(hex'ff00890001021600040201010100010102020e00020201000302010102020f00010203000502130005681200060212000102040001021200010204000102'),
bytes(hex'ff00eb00056d1300046e'),
bytes(hex'ff00ff00030006761200017604000176'),
bytes(hex'ff00890001731600027301740173017401730174017301740e00027301000173017401730174017301740f000173030001730174017301740173130005731200067512000175040001751200017504000175'),
bytes(hex'ff0089000177160009770e000277010006770f00017703000577130005781200067912000179040001791200017904000179'),
bytes(hex'ff008900017e1600017e017f017e017f018001000180017f017e0e0002810100017f017e017f0180017f017e0f0001810300017f017e017f017e017f1300017e017f017e017f017e1200017e017f017e017f017e017f1200017e0400017e'),
bytes(hex'ff008900017a1600097a0e00017b017a0100067a0f00017a0300057a1300057a1200017c047d017c1200017c0400017c'),
bytes(hex'ff0089000182160009820e0002820100028201160182011601820f000182030001820316018213000582120006161200011604000116'),
bytes(hex'ff00a3000583120003830184028313000183018401830184018313000583120006851200018504000185'),
bytes(hex'ff00a300010203000102120006021300050213000502120006881200018804000188'),
bytes(hex'ff0089000189160009890e00028901000389020101890f0001890300018902010289130005891200068a1200018a0400018a'),
bytes(hex'ff0089000186160009860e00028601000286012b0186012b01860f00018603000286012b0286130005861200068712000187040001871200018704000187'),
bytes(hex'ff008900018b1600098b0e00028b0100038b018c028b0f00018b0300018b038c018b1300058b1200068d1200018d0400018d1200018d0400018d'),
bytes(hex'ff00a300019001000190010001901200019001000190010001901400019001000190010001901400019001000190140001900100019001000190'),
bytes(hex'ff00ed00018e1600038e1500018e018f018e')
];
string[] public bodies_traits = [
'Burrito',
'Monk',
'Comfy',
'Hoodie',
'Astro',
'Underwear',
'Ninja',
'Jiu Jitsu Gi Blue',
'Boxer',
'Andy',
'Myles',
'Business Time',
'Freddie',
'Hot Speedo',
'Swimmer',
'Argyle',
'Steve',
'Romphim',
'Meme Frog',
'Go Bruins',
'Staying Fit',
'LA Summer',
'Bicyclist',
'Funktronic',
'Ganja Shirt From College',
'Net',
'Leaf'
];
uint8[] public bodies_indices = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26];
bytes[] public heads = [
bytes(hex'500009020e000102090101020c00010201010991010101020a00010201010b910101010209000102010103910881010101020900010201010291098101010102090001020101029109810101010208000102020102910981010101020700010201010281029109810101010207000102010103810191058101920481010101020700010202010c81010101020800020201010b81010101020a00010201010981010101020a00010201010181090101020a00010201010981010101020a00010201010281010102810192018101920181020101020a000102010103810101058101010181010101020a000102010102810101058101010181010101020b00010202010681020101020d0001020101018104010181010101020e00010201010181010102020101018101010102'),
bytes(hex'500009020e000102090101020c00010201010993010101020a00010201010b930101010209000102010103930894010101020900010201010293099401010102090001020101029309940101010208000102020102930994010101020700010201010294029309940101010207000102010103940193059401950494010101020700010202010c94010101020800020201010b94010101020a00010201010994010101020a00010201010194090101020a00010201010994010101020a00010201010294010102940195019401950194020101020a000102010103940101059401010194010101020a000102010102940101059401010194010101020b00010202010694020101020d0001020101019404010194010101020e00010201010194010102020101019401010102'),
bytes(hex'500009020e000102090101020c00010201010999010101020a00010201010b99010101020900010201010399089a010101020900010201010299099a010101020900010201010299099a010101020800010202010299099a01010102070001020101029a0299099a01010102070001020101039a0199059a0192049a010101020700010202010c9a010101020800020201010b9a010101020a0001020101099a010101020a00010201010136090101020a0001020101099a010101020a0001020101029a01010136059a020101020a0001020101039a01010136049a0101019a010101020a0001020101029a01010136049a0101019a010101020b0001020201069a020101020d0001020101019a0401019a010101020e0001020101019a010102020101019a01010102'),
bytes(hex'500009020e000102090101020c0001020101099b010101020a00010201010b9b01010102090001020101039b089c01010102090001020101029b099c01010102090001020101029b099c01010102080001020201029b099c01010102070001020101029c029b099c01010102070001020101039c019b059c019d049c010101020700010202010c9c010101020800020201010b9c010101020a0001020101099c010101020a0001020101019e090101020a0001020101099e010101020a0001020101029e0101029e019f019e019f019e020101020a0001020101039e0101059e010101a0010101020a0001020101029e0101059e010101a0010101020b0001020201069e020101020d0001020101019e0401019e010101020e0001020101019e010102020101019e01010102'),
bytes(hex'500009020e000102090101020c00010201010996010101020a00010201010b960101010209000102010103960897010101020900010201010296099701010102090001020101029609970101010208000102020102960997010101020700010201010297029609970101010207000102010103970196059701920497010101020700010202010c97010101020800020201010b97010101020a00010201010997010101020a00010201010198090101020a00010201010998010101020a00010201010298010102980192019801920198020101020a000102010103980101059801010198010101020a000102010102980101059801010198010101020b00010202010698020101020d0001020101019804010198010101020e00010201010198010102020101019801010102'),
bytes(hex'500009020e000102090101020c00010201010902010101020a00010201010b02010101020900010201010b02010101020900010201010b02010101020900010201010b02010101020800010202010b02010101020700010201010d0201010102070001020101090201920402010101020700010202010c02010101020800020201010b02010101020a00010201010902010101020a00010201010102090101020a00010201010902010101020a00010201010202010102020192010201920102020101020a000102010103020101050201010102010101020a000102010102020101050201010102010101020b00010202010602020101020d0001020101010204010102010101020e00010201010102010102020101010201010102'),
bytes(hex'500009020e000102090101020c000102010109a1010101020a00010201010ba10101010209000102010103a108a20101010209000102010102a109a20101010209000102010102a109a20101010209000102010102a109a20101010209000102010102a109a20101010209000102010102a105a2019204a20101010208000102010102a10aa20101010209000102010101a10aa2010101020a000102010109a2010101020a000102010101a3090101020a000102010108a201a3010101020a000102010102a2010101a305a2020101020a000102010103a2010101a304a2010101a2010101020a000102010102a2010101a304a2010101a2010101020b000102020106a2020101020d000102010101a2040101a2010101020e000102010101a201010202010101a201010102'),
bytes(hex'500009020e000102090101020c000102010109a4010101020a00010201010ba40101010209000102010101a505a601a701a801a901a601aa0101010209000102010101ab01ac01ad01ac01ad01ac01ad01ac03ad0101010209000102010101ae01af01b001b102b001b201ae01b001ae01b00101010208000102020102b301b402b301b401b501b401b501b301b40101010207000102010101b601b701b601b801b901b701ba02b604b90101010207000102010101bb01bc01bd01be01bd02bb03bd01bb01be01bc01bd0101010207000102020102bf01c001c101c202c002bf01c001bf01c00101010208000202010101c301c401c501c401c601c402c702c801c3010101020a000102010101c901ca01c902cb01cc01cb01c901cb010101020a000102010101cd090101020a000102010101ce01cf02ce02d001d101d001d2010101020a000102010101d301d4010102d404d3020101020a000102010101d501d601d7010102d601d702d5010101d6010101020a000102010101d801d9010101d804d9010101d9010101020b000102020106da020101020d000102010101da040101da010101020e000102010101da01010202010101da01010102'),
bytes(hex'500009020e000102090101020c000102010109dd010101020a000102010102dd070202dd0101010209000102010101dd010209dd0101010209000102010101dd010209dd0101010209000102010101dd010209dd010101020800010202010bdd0101010207000102010102020bdd0101010207000102010103dd010205dd019203dd0102010101020700010202010cdd010101020800020201010bdd010101020a000102010109dd010101020a000102010101de090101020a000102010101dd010207dd010101020a000102010101dd0102010102dd019f01dd019f01dd020101020a000102010102dd0102010105dd01010102010101020a000102010102dd010101dd020202dd010101dd010101020b000102020106dd020101020d000102010101dd040101dd010101020e000102010101dd01010202010101dd01010102')
];
string[] public heads_traits = [
'Human',
'Tengu',
'Meme Frog',
'Orc',
'Night Elf',
'Spoopy',
'AI Bot',
'Prismatic',
'Golden Boy'
];
uint8[] public heads_indices = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,6,6,7,8];
bytes[] public misc = [
bytes(hex'500009020e000102090101020c000102010109db010101020a000102010103db08dc0101010209000102010102db09dc0101010209000102010102db09dc0101010209000102010102db09dc0101010208000102020102db09dc0101010207000102010104db09dc0101010207000102010103db03dc029203dc029201dc010101020700010202010cdc010101020800020201010bdc010101020a000102010109dc010101020a000102010101db090101020a000102010104db05dc010101020a000102010102db010106dc0201010208000302010101db02dc010105dc010101dc010101020600010202010202010102dc010105dc010101dc0101010205000102010102db020101db020106dc0201010207000102010104db08dc0101010209000102010103db07dc01010102'),
bytes(hex'500009020e000102090101020c0001020b0101020a0001020d0101020900010205010302050101020900010204010502040101020900010203010202030102020301010208000102040102020301020203010102070001020a010202030101020700010209010202050101020700010207010202060101020800020205010202060101020a0001020b0101020a00010205010202040101020a00010206010202030101020a0001020c0101020a0001020d0101020a0001020c0101020b0001020a0101020d000102080101020e0001020301020203010102')
];
string[] public misc_traits = [
'Ghost',
'Mystery'
];
}
文件 8 的 13:EddieRenderer.sol
pragma solidity ^0.8.0;
import 'base64-sol/base64.sol';
import "./EddieData.sol";
contract EddieRenderer is EddieData {
string[] public bgPaletteColors = [
'b5eaea', 'b5c7ea', 'eab6b5', 'c3eab5', 'eab5d9',
'fafc51', '3a89ff', '5eff8f', 'ff6efa', 'a1a1a1'
];
struct CharacterData {
uint background;
uint body;
uint head;
uint eyes;
uint mouth;
uint hair;
}
function getSVG(uint256 seed) external view returns (string memory) {
return _getSVG(seed);
}
function _getSVG(uint256 seed) internal view returns (string memory) {
CharacterData memory data = _generateCharacterData(seed);
string memory image = string(abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" shape-rendering="crispEdges" width="768" height="768">'
'<rect width="100%" height="100%" fill="#', bgPaletteColors[data.background], '"/>',
_renderRects(heads[data.head], fullPalettes),
_renderRects(bodies[data.body], fullPalettes),
_renderRects(hair[data.hair], fullPalettes),
_renderRects(mouths[data.mouth], fullPalettes),
_renderRects(eyes[data.eyes], fullPalettes),
'</svg>'
));
return image;
}
function getGhostSVG(uint256 seed) external view returns (string memory) {
return _getGhostSVG(seed);
}
function _getGhostSVG(uint256 seed) internal view returns (string memory) {
CharacterData memory data = _generateCharacterData(seed);
string memory image = string(abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" shape-rendering="crispEdges" width="768" height="768">'
'<rect width="100%" height="100%" fill="#3b89ff"/>',
_renderRects(misc[0], fullPalettes),
_renderRects(hair[data.hair], fullPalettes),
_renderRects(mouths[data.mouth], fullPalettes),
_renderRects(eyes[data.eyes], fullPalettes),
'</svg>'
));
return image;
}
function getUnrevealedSVG(uint256 seed) external view returns (string memory) {
return _getUnrevealedSVG(seed);
}
function _getUnrevealedSVG(uint256 seed) internal view returns (string memory) {
CharacterData memory data = _generateCharacterData(seed);
string memory image = string(abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" shape-rendering="crispEdges" width="768" height="768">'
'<rect width="100%" height="100%" fill="#', bgPaletteColors[data.background], '"/>',
_renderRects(misc[1], fullPalettes),
'</svg>'
));
return image;
}
function getTraitsMetadata(uint256 seed) external view returns (string memory) {
return _getTraitsMetadata(seed);
}
function _getTraitsMetadata(uint256 seed) internal view returns (string memory) {
CharacterData memory data = _generateCharacterData(seed);
string[24] memory lookup = [
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '10', '11', '12', '13', '14', '15',
'16', '17', '18', '19', '20', '21', '22', '23'
];
string memory metadata = string(abi.encodePacked(
'{"trait_type":"Background", "value":"', lookup[data.background+1], '"},',
'{"trait_type":"Outfit", "value":"', bodies_traits[data.body], '"},',
'{"trait_type":"Class", "value":"', heads_traits[data.head], '"},',
'{"trait_type":"Eyes", "value":"', eyes_traits[data.eyes], '"},',
'{"trait_type":"Mouth", "value":"', mouths_traits[data.mouth], '"},',
'{"trait_type":"Head", "value":"', hair_traits[data.hair], '"},'
));
return metadata;
}
function _renderRects(bytes memory data, string[] memory palette) private pure returns (string memory) {
string[24] memory lookup = [
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '10', '11', '12', '13', '14', '15',
'16', '17', '18', '19', '20', '21', '22', '23'
];
string memory rects;
uint256 drawIndex = 0;
for (uint256 i = 0; i < data.length; i = i+2) {
uint8 runLength = uint8(data[i]);
uint8 colorIndex = uint8(data[i+1]);
if (colorIndex != 0) {
uint8 x = uint8(drawIndex % 24);
uint8 y = uint8(drawIndex / 24);
string memory color = palette[colorIndex];
rects = string(abi.encodePacked(rects, '<rect width="', lookup[runLength], '" height="1" x="', lookup[x], '" y="', lookup[y], '" fill="#', color, '"/>'));
}
drawIndex += runLength;
}
return rects;
}
function _generateCharacterData(uint256 seed) private view returns (CharacterData memory) {
return CharacterData({
background: seed % bgPaletteColors.length,
body: bodies_indices[(seed/2) % bodies_indices.length],
head: heads_indices[(seed/3) % heads_indices.length],
eyes: eyes_indices[(seed/4) % eyes_indices.length],
mouth: mouths_indices[(seed/5) % mouths_indices.length],
hair: hair_indices[(seed/6) % hair_indices.length]
});
}
}
文件 9 的 13:IERC721A.sol
pragma solidity ^0.8.4;
interface IERC721A {
error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();
error MintERC2309QuantityExceedsLimit();
error OwnershipNotInitializedForExtraData();
struct TokenOwnership {
address addr;
uint64 startTimestamp;
bool burned;
uint24 extraData;
}
function totalSupply() external view returns (uint256);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
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);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
文件 10 的 13:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
function verifyCalldata(
bytes32[] calldata proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
文件 11 的 13:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 12 的 13:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 13 的 13:base64.sol
pragma solidity >=0.6.0;
library Base64 {
string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
bytes internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return '';
string memory table = TABLE_ENCODE;
uint256 encodedLen = 4 * ((data.length + 2) / 3);
string memory result = new string(encodedLen + 32);
assembly {
mstore(result, encodedLen)
let tablePtr := add(table, 1)
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
let resultPtr := add(result, 32)
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F))))
resultPtr := add(resultPtr, 1)
}
switch mod(mload(data), 3)
case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
}
return result;
}
function decode(string memory _data) internal pure returns (bytes memory) {
bytes memory data = bytes(_data);
if (data.length == 0) return new bytes(0);
require(data.length % 4 == 0, "invalid base64 decoder input");
bytes memory table = TABLE_DECODE;
uint256 decodedLen = (data.length / 4) * 3;
bytes memory result = new bytes(decodedLen + 32);
assembly {
let lastBytes := mload(add(data, mload(data)))
if eq(and(lastBytes, 0xFF), 0x3d) {
decodedLen := sub(decodedLen, 1)
if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
decodedLen := sub(decodedLen, 1)
}
}
mstore(result, decodedLen)
let tablePtr := add(table, 1)
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
let resultPtr := add(result, 32)
for {} lt(dataPtr, endPtr) {}
{
dataPtr := add(dataPtr, 4)
let input := mload(dataPtr)
let output := add(
add(
shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
add(
shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
and(mload(add(tablePtr, and( input , 0xFF))), 0xFF)
)
)
mstore(resultPtr, shl(232, output))
resultPtr := add(resultPtr, 3)
}
}
return result;
}
}
{
"compilationTarget": {
"contracts/CryptoEddiesV2.sol": "CryptoEddiesV2"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"details": {
"constantOptimizer": true,
"cse": true,
"deduplicate": true,
"inliner": true,
"jumpdestRemover": true,
"orderLiterals": true,
"peephole": true,
"yul": false
},
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_contractEddieOG","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EddieDied","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EddieRerolled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EddieSacrificed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EventEndVibing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EventForceEndVibing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EventStartVibing","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_HP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKEN_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"adminForceStopVibing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burnSacrifice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnSacrificeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claimMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractEddieOG","outputs":[{"internalType":"contract CryptoEddies","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractGhost","outputs":[{"internalType":"contract CryptoDeddiesV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractHpEffector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getHP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getVibingInfoForToken","outputs":[{"internalType":"uint256","name":"currentVibingTime","type":"uint256"},{"internalType":"uint256","name":"totalVibingTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isVibingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ogTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"rerollEddie","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"rerollEddieMany","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rerollingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"int256","name":"hpRewarded","type":"int256"}],"name":"rewardManyHP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"seeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setBurnSacrificeEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setClaimEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setContractEddieOG","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setContractGhost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setContractHpEffector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setRerollingEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_revealed","type":"bool"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setVibingEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"toggleVibing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]