编译器
0.8.12+commit.f00d7308
文件 1 的 14:Address.sol
pragma solidity ^0.8.9;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 14:Base64.sol
pragma solidity ^0.8.9;
library Base64 {
string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return '';
string memory table = TABLE;
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)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
resultPtr := add(resultPtr, 1)
mstore(resultPtr, shl(248, 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;
}
}
文件 3 的 14:Collection.sol
pragma solidity ^0.8.9;
import "./ERC721.sol";
import "./utils/Base64.sol";
import "./utils/MerkleProof.sol";
import "./CollectionDescriptor.sol";
contract Collection is ERC721 {
address public owner = 0xaF69610ea9ddc95883f97a6a3171d52165b69B03;
CollectionDescriptor public descriptor;
mapping (uint256 => bytes) public hashes;
uint256 public totalSupply = 0;
constructor (string memory name_, string memory symbol_) ERC721(name_, symbol_) {
descriptor = new CollectionDescriptor();
_createNFT(owner);
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
bytes memory hash = hashes[tokenId];
string memory name = descriptor.generateName(tokenId);
string memory description = "The Room of Infinite Paintings: a simulated mind's infinite attempt for meaning.";
string memory image = generateBase64Image(hash, tokenId);
string memory attributes = generateTraits(hash, tokenId);
return string(
abi.encodePacked(
'data:application/json;base64,',
Base64.encode(
bytes(
abi.encodePacked(
'{"name":"',
name,
'", "description":"',
description,
'", "image": "',
'data:image/svg+xml;base64,',
image,'",',
attributes,
'}'
)
)
)
)
);
}
function generateBase64Image(bytes memory hash, uint256 tokenId) public view returns (string memory) {
bytes memory img = bytes(generateImage(hash, tokenId));
return Base64.encode(img);
}
function generateImageFromTokenID(uint256 tokenId) public view returns (string memory) {
bytes memory hash = hashes[tokenId];
return descriptor.generateImage(hash, tokenId);
}
function generateImage(bytes memory hash, uint256 tokenId) public view returns (string memory) {
return descriptor.generateImage(hash, tokenId);
}
function generateTraits(bytes memory hash, uint256 tokenId) public view returns (string memory) {
return descriptor.generateTraits(hash, tokenId);
}
function mint() public {
_mint(msg.sender);
}
function _mint(address _owner) internal {
_createNFT(_owner);
}
function _createNFT(address _owner) internal {
totalSupply+=1;
bytes memory hash = abi.encodePacked(keccak256(abi.encodePacked(totalSupply, block.timestamp, _owner)));
hashes[totalSupply] = hash;
super._mint(_owner, totalSupply);
}
}
文件 4 的 14:CollectionDescriptor.sol
pragma solidity ^0.8.11;
import './SVG.sol';
import './Utils.sol';
contract Renderer {
function render(bytes memory hash, uint256 _tokenId) public pure returns (string memory) {
uint256 midPoint = uint256(toUint8(hash,0))*300/256;
uint256 midPoint2 = uint256(toUint8(hash,1))*300/256;
uint256 gap = 10 + uint256(toUint8(hash,2))/4;
uint256 shiftTopY = 300 - midPoint;
uint256 shiftBottomY = 300 + midPoint;
return
string.concat(
'<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" style="background:#000">',
definitions(hash, _tokenId),
room(shiftTopY, shiftBottomY),
gradientRects(shiftTopY, shiftBottomY),
stars(shiftTopY, shiftBottomY),
polygons(gap, midPoint, midPoint2),
'</svg>'
);
}
function definitions(bytes memory hash, uint256 _tokenId) public pure returns (string memory) {
return string.concat(gradients(), filters(hash, _tokenId));
}
function gradients() public pure returns (string memory) {
return string.concat(
svg.linearGradient(
string.concat(svg.prop('id', 'topGradient'),svg.prop('gradientTransform', 'rotate(90)')),
string.concat(svg.gradientStop(80, 'white',svg.prop('stop-opacity', '0')),svg.gradientStop(100, 'white', svg.prop('stop-opacity', '1')))
)
);
}
function filters(bytes memory hash, uint256 _tokenId) public pure returns (string memory) {
string memory roomBF = generateBaseFrequency(hash, 3, 4, ['0.0', '0.00', '0.000']);
string memory starsBF = generateBaseFrequency(hash, 5, 6, ['0.', '0.0', '0.00']);
string memory starsOctaves = utils.uint2str(1 + uint256(toUint8(hash,7))*4/256);
string memory roomSeed = utils.uint2str(uint256(toUint8(hash,8))*uint256(toUint8(hash,9))*uint256(toUint8(hash,10)));
string memory starSeed = utils.uint2str(uint256(toUint8(hash,11))*uint256(toUint8(hash,12))*uint256(toUint8(hash,13)));
return string.concat(
svg.filter(
svg.prop('id','room'),
string.concat(
svg.el('feTurbulence', string.concat(svg.prop('baseFrequency', roomBF),svg.prop('seed', roomSeed), svg.prop('result', 'turb'))),
svg.el('feColorMatrix', svg.prop('values', generateColorMatrix(hash, _tokenId)))
)
),
svg.filter(
svg.prop('id', 'stars'),
string.concat(
svg.el('feTurbulence', string.concat(svg.prop('type', 'fractalNoise'), svg.prop('numOctaves', starsOctaves), svg.prop('baseFrequency', starsBF), svg.prop('seed', starSeed), svg.prop('result', 'turb'))),
svg.el('feColorMatrix', svg.prop('values', '15 0 0 0 0 0 15 0 0 0 0 0 15 0 0 0 0 0 -15 5'))
)
)
);
}
function generateBaseFrequency(bytes memory hash, uint256 index1, uint index2, string[3] memory decimalStrings) public pure returns (string memory) {
string memory strNr = utils.uint2str(1 + uint256(toUint8(hash,index1))*1000/256);
uint256 dec = uint256(toUint8(hash, index2))*3/256;
string memory bf = string.concat(decimalStrings[dec], strNr);
return bf;
}
function room(uint256 shiftTopY, uint256 shiftBottomY) public pure returns (string memory) {
string memory rectProps = string.concat(
svg.prop('width', '300'),
svg.prop('height', '300'),
svg.prop('filter', 'url(#room)')
);
string memory topTranslate = string.concat('translate(0,-',utils.uint2str(shiftTopY+30),')');
string memory bottomTranslate = string.concat('translate(0,', utils.uint2str(shiftBottomY+30),') scale(-1,1) rotate(180)');
return string.concat(
svg.rect(
string.concat(
rectProps,
svg.prop('transform', topTranslate)
)
),
svg.rect(
string.concat(
rectProps,
svg.prop('transform', bottomTranslate)
)
)
);
}
function generateColorMatrix(bytes memory hash, uint256 _tokenId) public pure returns (string memory) {
string memory strMatrix;
for(uint i = 0; i<20; i+=1) {
uint matrixOffset = uint256(toUint8(hash, i))/4;
uint negOrPos = toUint8(hash, i);
if(i == 18) {
uint256 diff = generateMinimalismFactor(hash, i, _tokenId);
string memory modStr;
if (diff > 64) {
modStr = string.concat("-", utils.uint2str(diff-64), ' ');
} else {
modStr = string.concat(utils.uint2str(64-diff), ' ');
}
strMatrix = string.concat(strMatrix, modStr);
} else if(i==4 || i == 9 || i== 14 || i == 19) {
strMatrix = string.concat(strMatrix, '1 ');
} else if(negOrPos < 128) {
strMatrix = string.concat(strMatrix, utils.uint2str(matrixOffset), ' ');
} else {
strMatrix = string.concat(strMatrix, '-', utils.uint2str(matrixOffset), ' ');
}
}
return strMatrix;
}
function generateMinimalismFactor(bytes memory hash, uint256 index, uint256 _tokenId) public pure returns (uint256) {
uint256 rnr = uint256(toUint8(hash, index))/2 + 1;
uint256 diff;
if(_tokenId > 1000000) {
diff = rnr;
} else {
diff = _tokenId*rnr/1000000;
}
return diff;
}
function stars(uint256 shiftTopY, uint256 shiftBottomY) public pure returns (string memory) {
string memory rectProps = string.concat(
svg.prop('width', '300'),
svg.prop('height', '300'),
svg.prop('filter', 'url(#stars)')
);
string memory topTranslate = string.concat('translate(0,-',utils.uint2str(shiftTopY+30),')');
string memory bottomTranslate = string.concat('translate(0,', utils.uint2str(shiftBottomY+30),') scale(-1,1) rotate(180)');
return string.concat(
svg.rect(
string.concat(
rectProps,
svg.prop('transform', topTranslate)
)
),
svg.rect(
string.concat(
rectProps,
svg.prop('transform', bottomTranslate)
)
)
);
}
function gradientRects(uint256 shiftTopY, uint256 shiftBottomY) public pure returns (string memory) {
return string.concat(
svg.rect(string.concat(svg.prop('width', '300'), svg.prop('height', '300'), svg.prop('fill', 'url(#topGradient)'), svg.prop('transform', string.concat('translate(0,-',utils.uint2str(shiftTopY),')')))),
svg.rect(string.concat(svg.prop('width', '300'), svg.prop('height', '300'), svg.prop('fill', 'url(#topGradient)'), svg.prop('transform', string.concat('translate(0,', utils.uint2str(shiftBottomY),') scale(-1,1) rotate(180)'))))
);
}
function polygons(uint256 gap, uint256 midPoint, uint256 midPoint2) public pure returns (string memory) {
uint256[8] memory polyPoints1 = [gap, 0, 0, 0, 0, gap, midPoint2, midPoint];
uint256[8] memory polyPoints2 = [0, 300-gap, 0, 300, gap, 300, midPoint2, midPoint];
uint256[8] memory polyPoints3 = [300-gap, 0, 300, 0, 300, gap, midPoint2, midPoint];
uint256[8] memory polyPoints4 = [300, 300-gap, 300, 300, 300-gap, 300, midPoint2, midPoint];
return string.concat(
polygon(polyPoints1),
polygon(polyPoints2),
polygon(polyPoints3),
polygon(polyPoints4)
);
}
function polygon(uint256[8] memory points) public pure returns (string memory) {
string memory poly = string.concat(utils.uint2str(points[0]),',',utils.uint2str(points[1]),' ',utils.uint2str(points[2]),',',utils.uint2str(points[3]),' ',utils.uint2str(points[4]),',',utils.uint2str(points[5]),' ',utils.uint2str(points[6]),',',utils.uint2str(points[7]));
return svg.el('polygon',
string.concat(
svg.prop('points', poly),
svg.prop('fill', 'none'),
svg.prop('stroke', 'white')
)
);
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
require(_start + 1 >= _start, "toUint8_overflow");
require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
}
contract CollectionDescriptor {
Renderer public renderer;
constructor() {
renderer = new Renderer();
}
function generateName(uint nr) public pure returns (string memory) {
return string(abi.encodePacked('Infinite Painting #', utils.uint2str(nr)));
}
function generateTraits(bytes memory hash, uint256 tokenId) public view returns (string memory) {
uint256 minimalFactor = renderer.generateMinimalismFactor(hash, 18, tokenId);
string memory traitType = '{"trait_type": "Minimalism Factor", "value":';
string memory traitValue = string.concat('"', utils.uint2str(minimalFactor), '"}');
return string(abi.encodePacked(
'"attributes": [',
traitType,
traitValue,
']'
));
}
function generateImage(bytes memory hash, uint256 tokenId) public view returns (string memory) {
return renderer.render(hash, tokenId);
}
}
文件 5 的 14:ERC165.sol
pragma solidity ^0.8.9;
import "./interfaces/IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 14:ERC721.sol
pragma solidity ^0.8.9;
import "./interfaces/IERC721.sol";
import "./interfaces/IERC721Receiver.sol";
import "./interfaces/IERC721Metadata.sol";
import "./utils/Address.sol";
import "./utils/Strings.sol";
import "./ERC165.sol";
contract ERC721 is ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping (uint256 => address) private _owners;
mapping (address => uint256) private _balances;
mapping (uint256 => address) private _tokenApprovals;
mapping (address => mapping (address => bool)) private _operatorApprovals;
constructor (string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC721).interfaceId
|| interfaceId == type(IERC721Metadata).interfaceId
|| super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
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) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0
? string(abi.encodePacked(baseURI, tokenId.toString()))
: '';
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != msg.sender, "ERC721: approve to caller");
_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
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 {
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool)
{
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
}
文件 7 的 14:IERC165.sol
pragma solidity ^0.8.9;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 8 的 14:IERC721.sol
pragma solidity ^0.8.9;
import "./IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}
文件 9 的 14:IERC721Metadata.sol
pragma solidity ^0.8.9;
import "./IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 10 的 14:IERC721Receiver.sol
pragma solidity ^0.8.9;
interface IERC721Receiver {
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}
文件 11 的 14:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal view returns (bool) {
return processProof(proof, leaf) == root;
}
function processProof(bytes32[] memory proof, bytes32 leaf) internal view returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
computedHash = keccak256(
abi.encodePacked(computedHash, proofElement)
);
} else {
computedHash = keccak256(
abi.encodePacked(proofElement, computedHash)
);
}
}
return computedHash;
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
文件 12 的 14:SVG.sol
pragma solidity ^0.8.12;
import './Utils.sol';
library svg {
function rect(string memory _props, string memory _children)
internal
pure
returns (string memory)
{
return el('rect', _props, _children);
}
function rect(string memory _props)
internal
pure
returns (string memory)
{
return el('rect', _props);
}
function filter(string memory _props, string memory _children)
internal
pure
returns (string memory)
{
return el('filter', _props, _children);
}
function linearGradient(string memory _props, string memory _children)
internal
pure
returns (string memory)
{
return el('linearGradient', _props, _children);
}
function gradientStop(
uint256 offset,
string memory stopColor,
string memory _props
) internal pure returns (string memory) {
return
el(
'stop',
string.concat(
prop('stop-color', stopColor),
' ',
prop('offset', string.concat(utils.uint2str(offset), '%')),
' ',
_props
)
);
}
function el(
string memory _tag,
string memory _props,
string memory _children
) internal pure returns (string memory) {
return
string.concat(
'<',
_tag,
' ',
_props,
'>',
_children,
'</',
_tag,
'>'
);
}
function el(
string memory _tag,
string memory _props
) internal pure returns (string memory) {
return
string.concat(
'<',
_tag,
' ',
_props,
'/>'
);
}
function prop(string memory _key, string memory _val)
internal
pure
returns (string memory)
{
return string.concat(_key, '=', '"', _val, '" ');
}
}
文件 13 的 14:Strings.sol
pragma solidity ^0.8.9;
library Strings {
bytes16 private constant alphabet = "0123456789abcdef";
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] = alphabet[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
文件 14 的 14:Utils.sol
pragma solidity ^0.8.12;
library utils {
function uint2str(uint256 _i)
internal
pure
returns (string memory _uintAsString)
{
if (_i == 0) {
return '0';
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
}
{
"compilationTarget": {
"contracts/Collection.sol": "Collection"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"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":"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":[],"name":"descriptor","outputs":[{"internalType":"contract CollectionDescriptor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"hash","type":"bytes"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateBase64Image","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"hash","type":"bytes"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateImage","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateImageFromTokenID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"hash","type":"bytes"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateTraits","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hashes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"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":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"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":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","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":[],"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"}]