文件 1 的 14:Chili.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 "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import 'base64-sol/base64.sol';
import "./IChiliRenderer.sol";
import "./ChiliRenderer.sol";
contract Chili is ChiliRenderer, ERC721A, Ownable, ReentrancyGuard {
uint256 public MAX_TOKEN_SUPPLY = 10000;
uint256 public mintPrice = 0.005 ether;
enum MintStatus {
CLOSED,
WHITELIST,
PUBLIC
}
MintStatus public mintStatus = MintStatus.CLOSED;
uint256 public maxTokensClaimableWhitelistPerWallet = 1;
uint256 public maxTokensClaimableWhitelistOverall = 3400;
uint256 public maxTokensOwnableInWallet = 100;
uint256 public numAlreadyMintedInAllowlist = 0;
mapping(uint256 => uint256) public seeds;
IChiliRenderer public contractRenderer;
bytes32 public merkleRoot;
address private constant WITHDRAWAL_ADDRESS_1 = 0x7daB7E71DD0AF5fF5bc66fBD953a09421E78c1ef;
address private constant WITHDRAWAL_ADDRESS_2 = 0x2861AFE1F71A9f6A8Aef7d577DE677cb6433ddC9;
address private constant WITHDRAWAL_ADDRESS_3 = 0xc0d236F98F904589436aC0a24bfB99851acB0534;
uint256 private constant WITHDRAWAL_PERCENTAGE_1 = 15;
uint256 private constant WITHDRAWAL_PERCENTAGE_2 = 20;
uint256 private constant WITHDRAWAL_PERCENTAGE_3 = 65;
constructor() ERC721A("ChiliBangs", "Chili") {
contractRenderer = IChiliRenderer(this);
}
modifier verifyTokenId(uint256 tokenId) {
require(tokenId >= _startTokenId() && tokenId <= _totalMinted(), "Invalid tokenId");
_;
}
modifier verifySupply(uint256 numToMint) {
require(numToMint > 0, "Mint at least 1");
require(_totalMinted() + numToMint <= MAX_TOKEN_SUPPLY, "Overcap");
_;
}
function _saveNewRandomSeed(uint256 tokenId) private {
seeds[tokenId] = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), tokenId, msg.sender)));
}
function _startTokenId() override internal pure virtual returns (uint256) {
return 1;
}
function _mintChili(address to, uint256 numToMint) verifySupply(numToMint) private {
uint256 startTokenId = _startTokenId() + _totalMinted();
for(uint256 tokenId = startTokenId; tokenId < startTokenId+numToMint; tokenId++) {
_saveNewRandomSeed(tokenId);
}
_safeMint(to, numToMint);
}
function reserveChili(address to, uint256 numToMint) external onlyOwner {
_mintChili(to, numToMint);
}
function reserveChiliMany(address[] calldata recipients, uint256 numToMint) external onlyOwner {
uint256 num = recipients.length;
require(num > 0);
for (uint256 i = 0; i < num; ++i) {
_mintChili(recipients[i], numToMint);
}
}
function publicMintChili(uint256 numToMint) external payable {
require(mintStatus == MintStatus.PUBLIC, "Public mint closed");
require(msg.value >= _getPrice(numToMint), "Incorrect payable" );
require(_numberMinted(msg.sender) + numToMint <= maxTokensOwnableInWallet, "Exceeds max mints");
_mintChili(msg.sender, numToMint);
}
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) {
return numPayable * mintPrice;
}
function allowListed(address _wallet, bytes32[] calldata _proof)
public
view
returns (bool)
{
return
MerkleProof.verify(
_proof,
merkleRoot,
keccak256(abi.encodePacked(_wallet))
);
}
function setMerkleRoot(bytes32 _newMerkleRoot) external onlyOwner {
merkleRoot = _newMerkleRoot;
}
function mintAllowList(bytes32[] calldata _proof) external {
require(mintStatus == MintStatus.WHITELIST || mintStatus == MintStatus.PUBLIC, "Minting disabled");
require(allowListed(msg.sender, _proof), "You are not on the allowlist");
require(_numberMinted(msg.sender) < maxTokensClaimableWhitelistPerWallet, "Exceeds max mints per wallet");
require(numAlreadyMintedInAllowlist < maxTokensClaimableWhitelistOverall, "Exceeds overall allowlist");
_mintChili(msg.sender, 1);
numAlreadyMintedInAllowlist++;
}
function getNumMinted() external view returns (uint256) {
return _totalMinted();
}
function setPricing(uint256 price) external onlyOwner {
mintPrice = price;
}
function setTokenMaxPerWallet(uint256 maxTokens) external onlyOwner {
maxTokensOwnableInWallet = maxTokens;
}
function getPrice(uint256 numToMint) external view returns (uint256) {
return _getPrice(numToMint);
}
function setMaxTokenSupply(uint256 _maxTokenSupply) external onlyOwner {
require(_maxTokenSupply >= _totalMinted(), "Cannot set lower than current supply");
MAX_TOKEN_SUPPLY = _maxTokenSupply;
}
function setAllowlistMaxMints(uint256 _max) external onlyOwner {
maxTokensClaimableWhitelistOverall = _max;
}
function setAllowlistMaxMintsWhitelist(uint256 _max) external onlyOwner {
maxTokensClaimableWhitelistPerWallet = _max;
}
function setMintStatus(uint256 _status) external onlyOwner {
mintStatus = MintStatus(_status);
}
function setContractRenderer(address newAddress) external onlyOwner {
contractRenderer = IChiliRenderer(newAddress);
}
function numberMinted(address addr) external view returns(uint256){
return _numberMinted(addr);
}
function _tokenURI(uint256 tokenId) private view returns (string memory) {
uint256 seed = seeds[tokenId];
string memory image = contractRenderer.getSVG(seed);
string memory json = Base64.encode(
bytes(string(
abi.encodePacked(
'{"name": ', '"ChiliBangs #', Strings.toString(tokenId),'",',
'"description": "Spice up your web3 experience",',
'"attributes":[',
contractRenderer.getTraitsMetadata(seed),
'{"trait_type":"Caliente", "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) {
return _tokenURI(tokenId);
}
function _randStat(uint256 seed, uint256 div, uint256 min, uint256 max) private pure returns (uint256) {
return min + (seed/div) % (max-min);
}
function withdraw() public nonReentrant {
uint256 contractBalance = address(this).balance;
uint256 amount1 = contractBalance * WITHDRAWAL_PERCENTAGE_1 / 100;
uint256 amount2 = contractBalance * WITHDRAWAL_PERCENTAGE_2 / 100;
uint256 amount3 = contractBalance * WITHDRAWAL_PERCENTAGE_3 / 100;
(bool success1,) = payable(WITHDRAWAL_ADDRESS_1).call{ value: amount1 }("");
(bool success2,) = payable(WITHDRAWAL_ADDRESS_2).call{ value: amount2 }("");
(bool success3,) = payable(WITHDRAWAL_ADDRESS_3).call{ value: amount3 }("");
require(success1 && success2 && success3, "WITHDRAWAL_FAILED");
}
}
文件 2 的 14:ChiliData.sol
pragma solidity ^0.8.0;
contract ChiliData {
string[] public fullPalettes = ['ff00ff', '000000', 'ffffff', 'c8f9fc', '92e0e0', 'ff80bd', '7a2f80', '8e488d', '1f2640', '232640', '212640', '45235a', 'ffd426', '6e3e1e', '6e3814', 'ebd9d9', 'ebc3c3', 'af8a62', 'ad8151', 'dcaf80', 'dba36b', 'ff3333', '3347ff', '33d3ff', '33ff33', 'ff7a33', '9933ff', 'c2323b', '4d7d3b', '9f2930', 'f1525b', 'ff868c', '828c91', 'a4abaf', 'fcb5db', 'f6d3e3', 'fceef4', 'ff2219', 'ffd519', 'cbdbfc', 'd67889', 'a1b1a3', 'f2f2f2', 'ff6a19', '5cbd8d', '683a23', 'd73238', '936a37', 'd3f4f2', '03e3fc', '612021', '541c1c', 'e43b45', 'feae33', 'ffd715', 'd75c0a', '5c6dbd', '9e9e9e', 'd2c0bf', '121212', '724d4e', '0e1212', '171717', '090909', 'dfe1e1', '9d2626', '253270', 'e1e4e8', '253570', '5976a4', 'dd7d4d', 'eb8552', 'f5c2a9', '4d5500', '767625', '4d3e18', '87872e', '565e01', '413411', 'e2b081', 'ebd7aa', '1985e5', 'dcd24d', 'ebe052', 'b0a420', 'f5f0a9', '199dcb', '19c77f', '25ac9e', 'd53434', 'f0f2f2', 'de4dde', 'eb52eb', 'f5a9f5', 'cd24cd', 'd926d9', 'b11fb1', 'ebdced', 'ebaaed', 'ebb4ed', 'ff6619', '221c18', 'ce2424', 'd92626', 'b21f1f', 'bb4160', 'ebe8ed', '662635', 'e4e1e6', 'ececec', 'dfdfdf', 'a6d2e5', 'd95766', 'afffff', '63c5ff', 'ea2629', '804919', 'ff4f19', 'ff3d19', 'ff7519', 'ff9919', 'ffbd19', '388220', '9ac08e', '1c4210', 'c0c0c0', 'f89e2b', 'f69430', '822121', 'c08e8e', '421010', '6d2888', 'b592c3', '371445', '828282', 'ffafaf', 'ff5b5b', '110e1a', 'f3d55f', 'f9eaae', '7b6c30', 'ffed80', '1a1a1a', '0d0d0d', '191919', '1c1c1c', '1f1f1f', '0c0c0c', '0a0a0a', 'ce3333', '080808', '070707', '050505', 'fcda70', 'fdd868', 'fcd662', 'ce33b9', '1959ff', 'f8d796', '1963ff', '2d5b7b', '306082', '336588', 'e88b4f', 'e98f54', 'e8925b', '33b1ce', '171516', '222034', 'c47f47', 'c49747', '595652', '43622c', '48692f', '4d7032', 'c8ddf2', '0e0e0e', 'da3130', 'db3736', 'da3c3c', '060606', '2bc960', '874eba', '604aba', '6d4bb9', 'df7126', 'cc6824', 'a66091', '955682', '5a5753', '19abb2', 'd73b38', '030303', '8c19ff', 'a53030', 'ac3232', 'b23535', 'ceb133', 'cd914b', 'cf924c', 'e82e32', 'ff6333', 'ffb833', 'b9e32d', '23abb0', '335cff', '7033ff', '651eff', 'e8c136', '2527ff', '181617', 'ffdc00', 'd77bba', '922b2b'];
bytes[] public Skin = [
bytes(hex'ce0004031b000603190008031800090316000b0315000b0315000b0315000b031500070301040303150007030104030316000a0316000a0316000903170009031800070319000703190006031a0006031a0005031a0005031b0004031b0004031c000203'),
bytes(hex'ce00040c1b00060c1900080c1800090c16000b0c15000b0c15000b0c15000b0c15000b0c15000b0c16000a0c16000a0c1600090c1700090c1800070c1900070c1900060c1a00060c1a00050c1a00050c1b00040c1b00040c1c00020c'),
bytes(hex'ce000106020701061b00010801090206020919000108010a060918000109010a070916000109010a090915000109010a090915000108010a090915000108010a090915000108010a090915000108010a090916000108010a080916000108010a080916000108010a070917000108010a070918000108010a050919000108010a050919000108010a04091a000108010a04091a000108010a03091a000108010a03091b00020b02091b000206010b01091c0001070106'),
bytes(hex'ce0004051b000605190008051800090516000b0515000b0515000b0515000b0515000b0515000b0516000a0516000a0516000905170009051800070519000705190006051a0006051a0005051a0005051b0004051b0004051c000205'),
bytes(hex'ce0004151b000615190008151800091516000b1515000b1515000b1515000b1515000b1515000b1516000a1516000a1516000915170009151800071519000715190006151a0006151a0005151a0005151b0004151b0004151c000215'),
bytes(hex'ce00040d1b00060d1900080d1800090d16000b0d15000b0d15000b0d15000b0d15000b0d1500070d010e030d16000a0d16000a0d1600090d1700090d1800070d1900070d1900060d1a00060d1a00050d1a00050d1b00040d1b00040d1c00020d'),
bytes(hex'ce00040f1b00060f1900080f1800090f16000b0f15000b0f15000b0f15000b0f15000b0f1500070f0110030f16000a0f16000a0f1600090f1700090f1800070f1900070f1900060f1a00060f1a00050f1a00050f1b00040f1b00040f1c00020f'),
bytes(hex'ce0004111b000611190008111800091116000b1115000b1115000b1115000b1115000b11150007110112031116000a1116000a1116000911170009111800071119000711190006111a0006111a0005111a0005111b0004111b0004111c000211'),
bytes(hex'ce0004131b000613190008131800091316000b1315000b1315000b1315000b1315000b13150007130114031316000a1316000a1316000913170009131800071319000713190006131a0006131a0005131a0005131b0004131b0004131c000213'),
bytes(hex'ce0004161b000616190008161800091616000b1615000b1615000b1615000b1615000b1615000b1616000a1616000a1616000916170009161800071619000716190006161a0006161a0005161a0005161b0004161b0004161c000216'),
bytes(hex'ce0004171b000617190008171800091716000b1715000b1715000b1715000b1715000b1715000b1716000a1716000a1716000917170009171800071719000717190006171a0006171a0005171a0005171b0004171b0004171c000217'),
bytes(hex'ce0004181b000618190008181800091816000b1815000b1815000b1815000b1815000b1815000b1816000a1816000a1816000918170009181800071819000718190006181a0006181a0005181a0005181b0004181b0004181c000218'),
bytes(hex'ce0004191b000619190008191800091916000b1915000b1915000b1915000b1915000b1915000b1916000a1916000a1916000919170009191800071919000719190006191a0006191a0005191a0005191b0004191b0004191c000219'),
bytes(hex'ce000120022101201b000621190001200621012018000921160001200921012015000b21150001200921012015000b21150001200921012015000b21160001200821012016000a2116000120072101201700092118000120052101201900072119000120042101201a0006211a000120032101201a0005211b000120022101201b000221012001211c0001200121'),
bytes(hex'ce00041a1b00061a1900081a1800091a16000b1a15000b1a15000b1a15000b1a15000b1a15000b1a16000a1a16000a1a1600091a1700091a1800071a1900071a1900061a1a00061a1a00051a1a00051a1b00041a1b00041a1c00021a'),
bytes(hex'ce00011b031c1b00011d051c1900011d011e061c1800011f011b071c1600011d011b091c1500011c011e091c15000b1c15000b1c15000b1c15000b1c16000a1c16000a1c1600091c1700091c1800071c1900071c1900061c1a00061c1a00051c1a00051c1b00041c1b00041c1c00021c')
];
string[] public Skin_traits = [
'Alien',
'Confident Yellow',
'Cosmic',
'Cotton Candy',
'Earthy Red',
'Human Prototype 1',
'Human Prototype 2',
'Human Prototype 3',
'Human Prototype 4',
'Insightful Indigo',
'Intuitive Blue',
'Loving Green',
'Passionate Orange',
'Robot',
'Spiritual Violet',
'Zombie'
];
bytes[] public Accessories = [
bytes(hex'ff00ff00170002221d0001220123012401221c000122022301221d000222'),
bytes(hex'ff003c0001293f0001291f0001291e000129200001291e0001291e0001291a00042a012b'),
bytes(hex'ff00f3000125'),
bytes(hex'ff00ac000131'),
bytes(hex'ff00ff00cf00013120000131030001311c000131010001311e0001311e000127012801271d000127012801271e000127'),
bytes(hex'ff00ac000126'),
bytes(hex'ff00ff00cf00012620000126030001261c000126010001261e0001261e000127012801271d000127012801271e000127'),
bytes(hex'ff00ac00012c1e00012c0100012c1d00012c0100012c1e00012c'),
bytes(hex'ff003c0001293f0001291f0001291e000129200001291e0001291e0001291a00042d012e'),
bytes(hex'ff00ff00cf00012f2000012f0300012f1c00012f0100012f1e00012f1e000127012801271d000127012801271e000127'),
bytes(hex'ff00'),
bytes(hex'ff00ac0001301e000130010001301d000130010001301e000130'),
bytes(hex'ff005c0001293f0001291f0001291e000129200001291e0001291e0001291a00013220000132020003321b00013201000133013201331c0002320133'),
bytes(hex'ff00ff0053000134013501361e0001360134013501371c000337'),
bytes(hex'ff00ac0001381e000138010001381d000138010001381e000138'),
bytes(hex'ff00ff00cf00013920000139030001391c000139010001391e0001391e000127012801271d000127012801271e000127')
];
string[] public Accessories_traits = [
'Bubble Gum',
'Cigar',
'Clown Nose',
'Diamond Earing',
'Diamond Necklace',
'Gold Earing',
'Gold Necklace',
'Jade Earring',
'Joint',
'Leather Necklace',
'None',
'Pearl Earring',
'Pipe',
'Pizza',
'Sapphire Earring',
'Stainless Steel Necklace'
];
bytes[] public Clothes = [
bytes(hex'ff00ff00af00013a013b0400013b1900013c013a013b0200013a1a00013a023b0200013c1a00013b013a013b1c00013b013a013c013a1c00013d013b013a013b1b00013c013a023b1c00013a013b'),
bytes(hex'ff00ff006c00023e1d00013e023b013e1d00013e023b023e0400013e1700023e023b043e1a00023b013f023b013f1a00023b013f023b1a00053b1b00043b1b00043b1c00023b'),
bytes(hex'ff00ff00af00023e0400013e1900023b043e1a00023b013f013b013f013b1a00023b013e013b013e1a00033b013f013b1b00033b013e1b00043b1c00023b'),
bytes(hex'ff00ff00af00013e01400400013e1900023b014001410140013e1a00033b0141023b1a00033b0141013b1a00053b1b00043b1b00043b1c00023b'),
bytes(hex'ff00ff00af0001420143040001421900024401430145014301421a000344014502441a000344014501441a0005441b0004441b0004441c000244'),
bytes(hex'ff00ff006c0002461d000146024701461d000146024702460400014617000246024704461a0002470148024701481a000247014802471a0005471b0004471b0004471c000247'),
bytes(hex'ff00ff00af000149014a0400014b1900024b014c0200014b1a00014c014a014b014d014a014c1a000149014d014c014d01491a00014c0149014b014e014c1b00014d014a014d014b1b00014d014c014e014b1c00014e014d'),
bytes(hex'ff00ff00ae00022e014f0400014f1900012e0150044f190002510350014f01501a0001510350014f1900022e04501b00012e03501a00025103501c0001510150'),
bytes(hex'ff00ff006c0002521d000152025301521d000152025302520400015217000252025304521a0002530155025301551a000253015502531a0005531b0004531b0004531c000253'),
bytes(hex'ff00ff00af000252040001521900025304521a00025301540153015401531a0002530152015301521a000353015401531b00035301521b0004531c000253'),
bytes(hex'ff00ff00ea0001561f0001560157030001571a000156015702000158025716000156015802570158020002580257160004560100025602581a000456'),
bytes(hex'ff00ff00af00023e0400013e1900023b0159023e01591a00025a0159025a01591a00023b0159023b1a00035a0159015a1b00033b01591b00045a1c00023b'),
bytes(hex'ff00'),
bytes(hex'ff00ff006c00025b1d00015b025c015b1d00015b025c025b0400015b1700025b025c045b1a00025c015d025c015d1a00025c015d025c1a00055c1b00045c1b00045c1c00025c'),
bytes(hex'ff00ff00af00025e0400015e1900025f045e1a00025f0160015f0160015f1a00025f015e015f015e1a00035f0160015f1b00035f015e1b00045f1c00025f'),
bytes(hex'ff00ff00af000161016204000162190001610262020001621a00016301610162020001621a000163016101621c00036301611c00036301611b0004631c000263'),
bytes(hex'ff00ff00af000264040001641900022b04641a00042b02651a00052b130002650500052b130004650400042b14000465010001650100042b160002650100016501000165022b'),
bytes(hex'ff00ff00af000266040001661900026704661a00026701680167016801671a0002670166016701661a000367016801671b00036701661b0004671c000267'),
bytes(hex'ff00ff00af000169016a0400016a1900016b0169016a020001691a000169026a0200016b1a00016a0169016a1c00016a0169016b01691c00016c016a0169016a1b00016b0169026a1c000169016a'),
bytes(hex'ff00ff00af00026d0400016d1900022a046d1a00022a016e012a016e012a1a00022a016d012a016d1a00032a016e012a1b00032a016d1b00042a1c00022a'),
bytes(hex'ff00ff00af00016f016c0400016c1900016f026c0200016c1a00016a016f016c0200016c1a00016a016f016c1c00036a016f1c00036a016f1b00046a1c00026a')
];
string[] public Clothes_traits = [
'Black Hawaiian Shirt',
'Black Hoodie',
'Black Quimono',
'Black Suit',
'Blue Suit',
'Brown Hoodie',
'Camo',
'Festive',
'Lime Hoodie',
'Lime Quimono',
'Mermaid',
'Mime',
'Nacked',
'Pink Hoodie',
'Pink Quimono',
'Pink Robe',
'Prisoner',
'Red Quimono',
'White Hawaiian Shirt',
'White Quimono',
'White Robe'
];
bytes[] public Eyes = [
bytes(hex'ff0011000102030001021a00030201000302180009021700020201010302010102021700090218000302010003021a00010203000102'),
bytes(hex'ff006f00027001010370010102701700097018000370010003701a00017003000170'),
bytes(hex'ff0011000101030001011a00030101000301180009011700020201010302010102021700090218000302010003021a00010203000102'),
bytes(hex'1b0001710300017100711a000171030001711a000171030001711a000171030001711a000171030001711a000171030001711a000171030001711a000171030001711a000171030001711a000171030001711a000171030001711800027201710372017102721700097218000372010003721a00017203000172'),
bytes(hex'ff0011000174030001741a00037401000374180009741700020201010302010102021700090218000302010003021a00010203000102'),
bytes(hex'ff00320003021c0005021a000302010103021a0005021c000302'),
bytes(hex'ff0011000102030001021a000302010003021800010201010102010101020101010201010102170002020101030201010202170001020101010201010102010101020101010218000302010003021a00010203000102'),
bytes(hex'ff004f0003010300030117000401010004011800020101730101017302011a00020101000201'),
bytes(hex'ff00340001011e0001011b00040102020101020217000401050218000201020003021800010105000102180001011e000101'),
bytes(hex'ff0011000175030001751a000176017501760100017601750176190002750177017602750177017617000176017702780176017702780176170001760179017801790176017901780179017618000176012601760100017601260176'),
bytes(hex'ff004f00090117000101012e0673010117000901'),
bytes(hex'ff004e000b011500017a027b017c037b017c027b017a1600097b1800037b0100037b'),
bytes(hex'ff006f00020201010302010102021700090218000302010003021a00010203000102'),
bytes(hex'ff0011000126030001261a00032601000326180009261700020201010302010102021700090218000302010003021a00010203000102'),
bytes(hex'ff001100017d0300017d1a00037d0100037d1800097d1700020201010302010102021700090218000302010003021a00010203000102'),
bytes(hex'ff002e000b7e1500017e047f017e047f017e15000b7e1500027e027f037e027f027e1600047e0100047e'),
bytes(hex'ff004e000b0115000183028401850384018502840183160009841800038401000384'),
bytes(hex'ff004e000b0115000180028101820381018202810180160009811800038101000381'),
bytes(hex'1b0001870300018700871a000187030001871a000187030001871a000187030001871a000187030001871a000187030001871a000187030001871a000187030001871a000187030001871a000187030001871a000187030001871800028801870388018702881700098818000388010003881a00018803000188'),
bytes(hex'ff004e000b011500030101860301018603011600030101860301018601011800030101000301'),
bytes(hex'ff006f0002020101030201010202'),
bytes(hex'ff0011000102030001021a00030201000302180001020101030201010302170009021700090218000302010003021a00010203000102'),
bytes(hex'ff0011000189030001891a0003890100038918000989170009891700098918000389010003891a00018903000189'),
bytes(hex'ff004e000b011500018a028b018c038b018c028b018a1600098b1800038b0100038b')
];
string[] public Eyes_traits = [
'Admired',
'Based',
'Black Eyelash',
'Blue Laser',
'Brown Eyelash',
'Cyclop',
'Dead Eyes',
'Devil Eyes',
'Eye Patch',
'Fire',
'Futuristic Glasses',
'Green Glasses',
'Hero',
'Metallic Gold Eyelash',
'Metallic Silver Eyelash',
'Party',
'Purple Glasses',
'Red Glasses',
'Red Laser',
'Sunglasses',
'Suspicious',
'Thoughtful',
'Void',
'Yellow Glasses'
];
bytes[] public Head = [
bytes(hex'4d000226028d0226190001260600012619000326028d0126'),
bytes(hex'ff00'),
bytes(hex'8f00028e1d00048e1b00018e018f018e018f018e018f1a00018e018f018e018f018e018f'),
bytes(hex'8c0008901700019008910190150001900391019005920190140001900391079015000190029101901d000290'),
bytes(hex'710001981e00019801941d00019802941c00019803941e000294'),
bytes(hex'890003931c000193028f01940195059315000193028f01940195079414000193018f0194019509941300018f0196010001970294070001941100018f01960200019701941e0001971f000197'),
bytes(hex'7100019b1e00019b019a1d00019b029a1c00019b039a1e00029a'),
bytes(hex'890003991c000199029a019b019c059915000199029a019b019c079a14000199019a019b019c099a1300019a019b0100019b029a0700019a1100019a019b0200019b019a1e00019b1f00019b'),
bytes(hex'cc00019d0100049d1b00069d1800029d'),
bytes(hex'8c0008a0170001a008a101a0150001a003a101a005a201a0140001a003a107a0150001a002a101a01d0002a0'),
bytes(hex'8b00069e1900019e072e1700019e022e079f1500019e022e029f079e1300019e022e029f019e0700019e1300012e029f019e1d00029f1f00019f'),
bytes(hex'710001a31e0001a301a41d0001a302a41c0001a303a41e0002a4'),
bytes(hex'890003a51c0001a502a401a301a605a5150001a502a401a301a607a4140001a501a401a301a609a4130001a401a3010001a302a4070001a4110001a401a3020001a301a41e0001a31f0001a3'),
bytes(hex'8e0004a71b0006a7190004a7020002a715000ba7'),
bytes(hex'ed0006a8'),
bytes(hex'6e000173020001731b00017304000173190002730400027318000273040002731800017306000173'),
bytes(hex'8e0004a91b0006a91a0006aa17000ca9'),
bytes(hex'8c0008ac170001ac08ad01ac150001ac03ad01ac05ae01ac140001ac03ad07ac150001ac02ad01ac1d0002ac'),
bytes(hex'cc0001ab010004ab1b0006ab180002ab'),
bytes(hex'900001791e000179012e01791e0001791c00037901000279'),
bytes(hex'ed0006af'),
bytes(hex'ab0001980594019318000198079401b016000198099401b0140001980494070001b01300019803941c00019802941d00019802941d00019802941d00019802941d00019802941d00019802941b0001980100019803941a0001980194019803941a0001980194019802941c0001980294'),
bytes(hex'ab00019b059a01991800019b079a01991600019b099a01991400019b049a070001991300019b039a1c00019b029a1d00019b029a1d00019b029a1d00019b029a1d00019b029a1d00019b029a1b00019b0100019b039a1a00019b019a019b039a1a00019b019a019b029a1c00019b029a'),
bytes(hex'ab0001a305a401a5180001a307a401a5160001a309a401a5140001a304a4070001a5130001a303a41c0001a302a41d0001a302a41d0001a302a41d0001a302a41d0001a302a41d0001a302a41b0001a3010001a303a41a0001a301a401a303a41a0001a301a401a302a41c0001a302a4'),
bytes(hex'ab0001b105b201b3180001b107b201b3160001b109b201b3140001b104b2070001b3130001b103b21c0001b102b21d0001b102b21d0001b102b21d0001b102b21d0001b102b21d0001b102b21b0001b1010001b103b21a0001b101b201b103b21a0001b101b201b102b21c0001b102b2'),
bytes(hex'ac0001b40494019319000198069401b017000198089401b0150001980394070001b01400019802941d00019801941e00019801941e00019801941e00019801941e00019801941e00019801941e00019802941d00019802941d00019802941d00019802941d00019802941d0001980194'),
bytes(hex'ac00019b049a01991900019b069a01991700019b089a01991500019b039a070001991400019b029a1d00019b019a1e00019b019a1e00019b019a1e00019b019a1e00019b019a1e00019b019a1e00019b029a1d00019b029a1d00019b029a1d00019b029a1d00019b029a1d00019b019a'),
bytes(hex'ac0001a304a401a5190001a306a401a5170001a308a401a5150001a303a4070001a5140001a302a41d0001a301a41e0001a301a41e0001a301a41e0001a301a41e0001a301a41e0001a301a41e0001a302a41d0001a302a41d0001a302a41d0001a302a41d0001a302a41d0001a301a4'),
bytes(hex'ac0001b104b201b3190001b106b201b3170001b108b201b3150001b103b2070001b3140001b102b21d0001b101b21e0001b101b21e0001b101b21e0001b101b21e0001b101b21e0001b101b21e0001b102b21d0001b102b21d0001b102b21d0001b102b21d0001b102b21d0001b101b2'),
bytes(hex'6d0001b5020001b602b5150002b5030001b5020001b6180001b6020001b701b601b801b602b8170001b6010001b701b801b601b802b502b8030002b5110001b601b703b801b605b8020001b6120001b701b602b8070002b8130001b702b81c0001b501b701b81e0001b501b61e0001b701b81e0001b701b81e0001b701b81b0002b5010001b701b81c0001b6010001b702b81b0001b601b801b702b81b0001b601b801b702b81c0001b702b8'),
bytes(hex'8f0002b91d0004b91b0001b901ba01b901ba01b901ba1a0001b901ba01b901ba01b901ba'),
bytes(hex'8f0002bb1d0004bb1b0001bb01bc01bb01bc01bb01bc1a0001bb01bc01bb01bc01bb01bc'),
bytes(hex'6d0003ab02bd1d0001011d0001be037901bf1a0002be037902bf1900070103c0'),
bytes(hex'900001791e00017901c101791e0001791c00037901000279'),
bytes(hex'cc00012e0100042e1b00062e1800022e'),
bytes(hex'8c0008c2170001c208c301c2150001c203c301c205c401c2140001c203c307c2150001c202c301c21d0002c2'),
bytes(hex'710001b11e0001b101b21d0001b102b21c0001b103b21e0002b2'),
bytes(hex'890003b31c0001b302b201b101c505b3150001b302b201b101c507b2140001b301b201b101c509b2130001b201b1010001b102b2070001b2110001b201b1020001b101b21e0001b11f0001b1'),
bytes(hex'cd0001980494019319000198069401931700019801940700019316000198'),
bytes(hex'cd00019b049a01991900019b069a01991700019b019a070001991600019b'),
bytes(hex'cd0001a304a401a5190001a306a401a5170001a301a4070001a5160001a3'),
bytes(hex'cd0001b104b201b3190001b106b201b3170001b101b2070001b3160001b1'),
bytes(hex'8e0003c601c71b0005c601c7160001c6020001c801c901ca01cb01cc01cd01ce01c8020001c713000ac602c7'),
bytes(hex'6d0006a71a0006a71a0006a71a00062e18000aa7'),
bytes(hex'6d0004cf1b0001cf010004cf1c0004cf1b00040101d0010118000acf'),
bytes(hex'6d0004d11b0001d1010004d11c0004d11b00040101d0010118000ad1'),
bytes(hex'ad0005a701d2190007a701d215000ba703d2')
];
string[] public Head_traits = [
'Angel',
'Bald',
'Black Beanie',
'Black Beret',
'Black Mohawk',
'Black Ponytail',
'Blonde Mohawk',
'Blonde Ponytail',
'Blue Bandana',
'Blue Beret',
'Boho',
'Brown Mohawk',
'Brown Ponytail',
'Cap Backward',
'Dark Headband',
'Devil',
'Founder Hat',
'Green Beret',
'Grey Bandana',
'King Crown',
'Light Headband',
'Long Curly Black',
'Long Curly Blonde',
'Long Curly Brown',
'Long Curly Red',
'Long Straight Black',
'Long Straight Blonde',
'Long Straight Brown',
'Long Straight Red',
'Medusa',
'Orange Beanie',
'Pink Beanie',
'Propeller',
'Queen Crown',
'Red Bandana',
'Red Beret',
'Red Mohawk',
'Red Ponytail',
'Short Black',
'Short Blonde',
'Short Brown',
'Short Red',
'Sombrero',
'Top Hat',
'Witch',
'Wizard',
'Zorro'
];
bytes[] public Mouth = [
bytes(hex'ff00ff00330003011d000173'),
bytes(hex'ff00ff0033000301'),
bytes(hex'ff00ff001200010120000301'),
bytes(hex'ff00ff0033000331'),
bytes(hex'ff00ff00330003d3'),
bytes(hex'ff00ff00330003011c000101'),
bytes(hex'ff00ff0012000101030001011c000301'),
bytes(hex'ff00ff00330003d4'),
bytes(hex'ff00ff00330003d5'),
bytes(hex'ff00ff00330003011c00010103000101'),
bytes(hex'ff00ff001200010101000101010001011a0001010100010101000101'),
bytes(hex'ff00ff00330003011d00010201000102')
];
string[] public Mouth_traits = [
'Bloody',
'Calm',
'Convinced',
'Diamond Grill',
'Gold Grill',
'Grumpy',
'Happy',
'Pink Lipstick',
'Red Lipstick',
'Sad',
'Sewn',
'Vampire'
];
}
文件 3 的 14:ChiliRenderer.sol
pragma solidity ^0.8.0;
import 'base64-sol/base64.sol';
import "./IChiliRenderer.sol";
import "./ChiliData.sol";
contract ChiliRenderer is IChiliRenderer, ChiliData {
struct CharacterData {
uint Background;
uint Skin;
uint Head;
uint Clothes;
uint Mouth;
uint Accessories;
uint Eyes;
}
string[] public bgPaletteColors = [
'cc9999',
'a1cc99',
'99a8cc',
'cc99bb',
'ccb399',
'ccc999',
'ccccff'
];
function getSVG(uint256 seed) external view override 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 32 32" shape-rendering="crispEdges" width="512" height="512">',
'<rect width="100%" height="100%" fill="#', bgPaletteColors[data.Background], '"/>',
_renderRects(Skin[data.Skin], fullPalettes),
_renderRects(Head[data.Head], fullPalettes),
_renderRects(Clothes[data.Clothes], fullPalettes),
_renderRects(Mouth[data.Mouth], fullPalettes),
_renderRects(Accessories[data.Accessories], fullPalettes),
_renderRects(Eyes[data.Eyes], fullPalettes),
'</svg>'
));
return image;
}
function getTraitsMetadata(uint256 seed) external override view returns (string memory) {
return _getTraitsMetadata(seed);
}
function _getTraitsMetadata(uint256 seed) internal view returns (string memory) {
CharacterData memory data = _generateCharacterData(seed);
string[17] memory lookup = [
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '10', '11', '12', '13', '14',
'15', '16'
];
string memory metadata = string(abi.encodePacked(
'{"trait_type":"Background", "value":"', lookup[data.Background+1], '"},'
'{"trait_type":"Skin", "value":"', Skin_traits[data.Skin], '"},',
'{"trait_type":"Head", "value":"', Head_traits[data.Head], '"},',
'{"trait_type":"Clothes", "value":"', Clothes_traits[data.Clothes], '"},',
'{"trait_type":"Mouth", "value":"', Mouth_traits[data.Mouth], '"},',
'{"trait_type":"Accessories", "value":"', Accessories_traits[data.Accessories], '"},',
'{"trait_type":"Eyes", "value":"', Eyes_traits[data.Eyes], '"},'
));
return metadata;
}
function _renderRects(bytes memory data, string[] memory palette) private pure returns (string memory) {
string[33] 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', '24', '25', '26', '27', '28', '29',
'30', '31', '32'
];
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 % 32);
uint8 y = uint8(drawIndex / 32);
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,
Skin: (seed/2) % Skin.length,
Head : (seed/3) % Head.length,
Clothes : (seed/4) % Clothes.length,
Mouth : (seed/5) % Mouth.length,
Accessories : (seed/6) % Accessories.length,
Eyes : (seed/7) % Eyes.length
});
}
}
文件 4 的 14: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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 5 的 14: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;
uint256 private _spotMinted;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector);
}
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
function _sequentialUpTo() internal view virtual returns (uint256) {
return type(uint256).max;
}
function _nextTokenId() internal view virtual returns (uint256) {
return _currentIndex;
}
function totalSupply() public view virtual override returns (uint256 result) {
unchecked {
result = _currentIndex - _burnCounter - _startTokenId();
if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
}
}
function _totalMinted() internal view virtual returns (uint256 result) {
unchecked {
result = _currentIndex - _startTokenId();
if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
}
}
function _totalBurned() internal view virtual returns (uint256) {
return _burnCounter;
}
function _totalSpotMinted() internal view virtual returns (uint256) {
return _spotMinted;
}
function balanceOf(address owner) public view virtual override returns (uint256) {
if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector);
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.selector);
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 _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) {
return _packedOwnerships[index] != 0;
}
function _initializeOwnershipAt(uint256 index) internal virtual {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
if (_startTokenId() <= tokenId) {
packed = _packedOwnerships[tokenId];
if (tokenId > _sequentialUpTo()) {
if (_packedOwnershipExists(packed)) return packed;
_revert(OwnerQueryForNonexistentToken.selector);
}
if (packed == 0) {
if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector);
for (;;) {
unchecked {
packed = _packedOwnerships[--tokenId];
}
if (packed == 0) continue;
if (packed & _BITMASK_BURNED == 0) return packed;
_revert(OwnerQueryForNonexistentToken.selector);
}
}
if (packed & _BITMASK_BURNED == 0) return packed;
}
_revert(OwnerQueryForNonexistentToken.selector);
}
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 payable virtual override {
_approve(to, tokenId, true);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector);
return _tokenApprovals[tokenId].value;
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_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 result) {
if (_startTokenId() <= tokenId) {
if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]);
if (tokenId < _currentIndex) {
uint256 packed;
while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId;
result = packed & _BITMASK_BURNED == 0;
}
}
}
function _packedOwnershipExists(uint256 packed) private pure returns (bool result) {
assembly {
result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED))
}
}
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 payable virtual override {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));
if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector);
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector);
_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;
}
}
}
}
uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
assembly {
log4(
0,
0,
_TRANSFER_EVENT_SIGNATURE,
from,
toMasked,
tokenId
)
}
if (toMasked == 0) _revert(TransferToZeroAddress.selector);
_afterTokenTransfers(from, to, tokenId, 1);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
safeTransferFrom(from, to, tokenId, '');
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public payable virtual override {
transferFrom(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
_revert(TransferToNonERC721ReceiverImplementer.selector);
}
}
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.selector);
}
assembly {
revert(add(32, reason), mload(reason))
}
}
}
function _mint(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (quantity == 0) _revert(MintZeroQuantity.selector);
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
if (toMasked == 0) _revert(MintToZeroAddress.selector);
uint256 end = startTokenId + quantity;
uint256 tokenId = startTokenId;
if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);
do {
assembly {
log4(
0,
0,
_TRANSFER_EVENT_SIGNATURE,
0,
toMasked,
tokenId
)
}
} while (++tokenId != end);
_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.selector);
if (quantity == 0) _revert(MintZeroQuantity.selector);
if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector);
_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)
);
if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);
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.selector);
}
} while (index < end);
if (_currentIndex != end) revert();
}
}
}
function _safeMint(address to, uint256 quantity) internal virtual {
_safeMint(to, quantity, '');
}
function _mintSpot(address to, uint256 tokenId) internal virtual {
if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector);
uint256 prevOwnershipPacked = _packedOwnerships[tokenId];
if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector);
_beforeTokenTransfers(address(0), to, tokenId, 1);
unchecked {
_packedOwnerships[tokenId] = _packOwnershipData(
to,
_nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked)
);
_packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1;
uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
if (toMasked == 0) _revert(MintToZeroAddress.selector);
assembly {
log4(
0,
0,
_TRANSFER_EVENT_SIGNATURE,
0,
toMasked,
tokenId
)
}
++_spotMinted;
}
_afterTokenTransfers(address(0), to, tokenId, 1);
}
function _safeMintSpot(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mintSpot(to, tokenId);
unchecked {
if (to.code.length != 0) {
uint256 currentSpotMinted = _spotMinted;
if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) {
_revert(TransferToNonERC721ReceiverImplementer.selector);
}
if (_spotMinted != currentSpotMinted) revert();
}
}
}
function _safeMintSpot(address to, uint256 tokenId) internal virtual {
_safeMintSpot(to, tokenId, '');
}
function _approve(address to, uint256 tokenId) internal virtual {
_approve(to, tokenId, false);
}
function _approve(
address to,
uint256 tokenId,
bool approvalCheck
) internal virtual {
address owner = ownerOf(tokenId);
if (approvalCheck && _msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
_revert(ApprovalCallerNotOwnerNorApproved.selector);
}
_tokenApprovals[tokenId].value = to;
emit Approval(owner, to, tokenId);
}
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.selector);
}
_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.selector);
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 {
let m := add(mload(0x40), 0xa0)
mstore(0x40, m)
str := sub(m, 0x20)
mstore(str, 0)
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)
}
}
function _revert(bytes4 errorSelector) internal pure {
assembly {
mstore(0x00, errorSelector)
revert(0x00, 0x04)
}
}
}
文件 6 的 14:IChiliRenderer.sol
pragma solidity ^0.8.0;
interface IChiliRenderer{
function getSVG(uint256 seed) external view returns (string memory);
function getTraitsMetadata(uint256 seed) external view returns (string memory);
}
文件 7 的 14:IERC721A.sol
pragma solidity ^0.8.4;
interface IERC721A {
error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();
error MintERC2309QuantityExceedsLimit();
error OwnershipNotInitializedForExtraData();
error SequentialUpToTooSmall();
error SequentialMintExceedsLimit();
error SpotMintTokenIdTooSmall();
error TokenAlreadyExists();
error NotCompatibleWithSpotMints();
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 payable;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
function approve(address to, uint256 tokenId) external payable;
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);
}
文件 8 的 14:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 9 的 14: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 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proofLen - 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) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
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 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
require(leavesLen + proofLen - 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) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
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)
}
}
}
文件 10 的 14: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);
}
}
文件 11 的 14:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 12 的 14:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 13 的 14:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
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] = _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);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 14 的 14: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/Chili.sol": "Chili"
},
"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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","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":"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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Accessories","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Accessories_traits","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Clothes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Clothes_traits","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Eyes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Eyes_traits","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Head","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Head_traits","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKEN_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Mouth","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Mouth_traits","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Skin","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"Skin_traits","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"allowListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","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":"","type":"uint256"}],"name":"bgPaletteColors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractRenderer","outputs":[{"internalType":"contract IChiliRenderer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"fullPalettes","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numToMint","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"getSVG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"getTraitsMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"maxTokensClaimableWhitelistOverall","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensClaimableWhitelistPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensOwnableInWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mintAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintStatus","outputs":[{"internalType":"enum Chili.MintStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numAlreadyMintedInAllowlist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"numberMinted","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":[{"internalType":"uint256","name":"numToMint","type":"uint256"}],"name":"publicMintChili","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numToMint","type":"uint256"}],"name":"reserveChili","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256","name":"numToMint","type":"uint256"}],"name":"reserveChiliMany","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":"payable","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":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"seeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setAllowlistMaxMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setAllowlistMaxMintsWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setContractRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxTokenSupply","type":"uint256"}],"name":"setMaxTokenSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_newMerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_status","type":"uint256"}],"name":"setMintStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setPricing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxTokens","type":"uint256"}],"name":"setTokenMaxPerWallet","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":"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":"result","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]