文件 1 的 7:Bytecode.sol
pragma solidity ^0.8.0;
library Bytecode {
error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);
function creationCodeFor(bytes memory _code) internal pure returns (bytes memory) {
return abi.encodePacked(
hex"63",
uint32(_code.length),
hex"80_60_0E_60_00_39_60_00_F3",
_code
);
}
function codeSize(address _addr) internal view returns (uint256 size) {
assembly { size := extcodesize(_addr) }
}
function codeAt(address _addr, uint256 _start, uint256 _end) internal view returns (bytes memory oCode) {
uint256 csize = codeSize(_addr);
if (csize == 0) return bytes("");
if (_start > csize) return bytes("");
if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end);
unchecked {
uint256 reqSize = _end - _start;
uint256 maxSize = csize - _start;
uint256 size = maxSize < reqSize ? maxSize : reqSize;
assembly {
oCode := mload(0x40)
mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(oCode, size)
extcodecopy(_addr, add(oCode, 0x20), _start, size)
}
}
}
}
文件 2 的 7: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;
}
}
文件 3 的 7:Create3.sol
pragma solidity ^0.8.0;
library Create3 {
error ErrorCreatingProxy();
error ErrorCreatingContract();
error TargetAlreadyExists();
bytes internal constant PROXY_CHILD_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3";
bytes32 internal constant KECCAK256_PROXY_CHILD_BYTECODE = 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f;
function codeSize(address _addr) internal view returns (uint256 size) {
assembly { size := extcodesize(_addr) }
}
function create3(bytes32 _salt, bytes memory _creationCode) internal returns (address addr) {
return create3(_salt, _creationCode, 0);
}
function create3(bytes32 _salt, bytes memory _creationCode, uint256 _value) internal returns (address addr) {
bytes memory creationCode = PROXY_CHILD_BYTECODE;
addr = addressOf(_salt);
if (codeSize(addr) != 0) revert TargetAlreadyExists();
address proxy; assembly { proxy := create2(0, add(creationCode, 32), mload(creationCode), _salt)}
if (proxy == address(0)) revert ErrorCreatingProxy();
(bool success,) = proxy.call{ value: _value }(_creationCode);
if (!success || codeSize(addr) == 0) revert ErrorCreatingContract();
}
function addressOf(bytes32 _salt) internal view returns (address) {
address proxy = address(
uint160(
uint256(
keccak256(
abi.encodePacked(
hex'ff',
address(this),
_salt,
KECCAK256_PROXY_CHILD_BYTECODE
)
)
)
)
);
return address(
uint160(
uint256(
keccak256(
abi.encodePacked(
hex"d6_94",
proxy,
hex"01"
)
)
)
)
);
}
}
文件 4 的 7: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);
}
}
文件 5 的 7:SSTORE2Map.sol
pragma solidity ^0.8.0;
import "./Create3.sol";
import "./Bytecode.sol";
library SSTORE2Map {
error WriteError();
bytes32 private constant SLOT_KEY_PREFIX = 0xd351a9253491dfef66f53115e9e3afda3b5fdef08a1de6937da91188ec553be5;
function internalKey(bytes32 _key) internal pure returns (bytes32) {
return keccak256(abi.encode(SLOT_KEY_PREFIX, _key));
}
function write(string memory _key, bytes memory _data) internal returns (address pointer) {
return write(keccak256(bytes(_key)), _data);
}
function write(bytes32 _key, bytes memory _data) internal returns (address pointer) {
bytes memory code = Bytecode.creationCodeFor(
abi.encodePacked(
hex'00',
_data
)
);
pointer = Create3.create3(internalKey(_key), code);
}
function read(string memory _key) internal view returns (bytes memory) {
return read(keccak256(bytes(_key)));
}
function read(string memory _key, uint256 _start) internal view returns (bytes memory) {
return read(keccak256(bytes(_key)), _start);
}
function read(string memory _key, uint256 _start, uint256 _end) internal view returns (bytes memory) {
return read(keccak256(bytes(_key)), _start, _end);
}
function read(bytes32 _key) internal view returns (bytes memory) {
return Bytecode.codeAt(Create3.addressOf(internalKey(_key)), 1, type(uint256).max);
}
function read(bytes32 _key, uint256 _start) internal view returns (bytes memory) {
return Bytecode.codeAt(Create3.addressOf(internalKey(_key)), _start + 1, type(uint256).max);
}
function read(bytes32 _key, uint256 _start, uint256 _end) internal view returns (bytes memory) {
return Bytecode.codeAt(Create3.addressOf(internalKey(_key)), _start + 1, _end + 1);
}
}
文件 6 的 7:potted_data.sol
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./SSTORE2Map.sol";
import "./potted_types.sol";
contract PPData is Ownable {
PottedTypes.Potted[] private potteds;
PottedTypes.Branch[] private branches;
PottedTypes.Blossom[] private blossoms;
PottedTypes.Bg[] private bgs;
string constant bg = "bg";
string constant pottedA = "PottedA";
string constant pottedB = "PottedB";
string constant pottedC = "PottedC";
string constant branchA = "branchA";
string constant branchB = "branchB";
string constant branchC = "branchC";
string constant blossomA = "blossomA";
string constant blossomB = "blossomB";
string constant blossomC = "blossomC";
string constant unreveal = "unreveal";
function getAllPotted() external view returns (PottedTypes.Potted[] memory) {
return potteds;
}
function getAllBranch() external view returns (PottedTypes.Branch[] memory) {
return branches;
}
function getAllBlossom() external view returns (PottedTypes.Blossom[] memory) {
return blossoms;
}
function getAllBg() external view returns (PottedTypes.Bg[] memory) {
return bgs;
}
function updatePotted(uint index, PottedTypes.Potted memory newData) external onlyOwner {
potteds[index] = newData;
}
function updateBranch(uint index, PottedTypes.Branch memory newData) external onlyOwner {
branches[index] = newData;
}
function updateBlossom(uint index, PottedTypes.Blossom memory newData) external onlyOwner {
blossoms[index] = newData;
}
function setPotteds(PottedTypes.Potted[] calldata _potted) external onlyOwner {
for (uint i; i < _potted.length; i++) {
potteds.push(_potted[i]);
}
}
function setBranches(PottedTypes.Branch[] calldata _branch) external onlyOwner {
for (uint i; i < _branch.length; i++) {
branches.push(_branch[i]);
}
}
function setBlossoms(PottedTypes.Blossom[] calldata _blossom) external onlyOwner {
for (uint i; i < _blossom.length; i++) {
blossoms.push(_blossom[i]);
}
}
function setBgs(PottedTypes.Bg[] calldata _bg) external onlyOwner {
for (uint i; i < _bg.length; i++) {
bgs.push(_bg[i]);
}
}
function setPottedAImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(pottedA, abi.encode(_hashes));
}
function setPottedBImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(pottedB, abi.encode(_hashes));
}
function setPottedCImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(pottedC, abi.encode(_hashes));
}
function getPottedImages() external view returns (bytes[] memory) {
bytes[] memory dataA = abi.decode(SSTORE2Map.read(pottedA), (bytes[]));
bytes[] memory dataB = abi.decode(SSTORE2Map.read(pottedB), (bytes[]));
bytes[] memory dataC = abi.decode(SSTORE2Map.read(pottedC), (bytes[]));
bytes[] memory hashes = new bytes[](dataA.length + dataB.length + dataC.length);
for (uint i = 0; i < dataA.length; i++) {
hashes[i] = dataA[i];
}
for (uint i = 0; i < dataB.length; i++) {
hashes[i + dataA.length] = dataB[i];
}
for (uint i = 0; i < dataC.length; i++) {
hashes[i + dataA.length + dataB.length] = dataC[i];
}
return hashes;
}
function setBranchAImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(branchA, abi.encode(_hashes));
}
function setBranchBImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(branchB, abi.encode(_hashes));
}
function setBranchCImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(branchC, abi.encode(_hashes));
}
function getBranchImages() external view returns (bytes[] memory) {
bytes[] memory dataA = abi.decode(SSTORE2Map.read(branchA), (bytes[]));
bytes[] memory dataB = abi.decode(SSTORE2Map.read(branchB), (bytes[]));
bytes[] memory dataC = abi.decode(SSTORE2Map.read(branchC), (bytes[]));
bytes[] memory hashes = new bytes[](dataA.length + dataB.length + dataC.length);
for (uint i = 0; i < dataA.length; i++) {
hashes[i] = dataA[i];
}
for (uint i = 0; i < dataB.length; i++) {
hashes[i + dataA.length] = dataB[i];
}
for (uint i = 0; i < dataC.length; i++) {
hashes[i + dataA.length + dataB.length] = dataC[i];
}
return hashes;
}
function setBlossomAImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(blossomA, abi.encode(_hashes));
}
function setBlossomBImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(blossomB, abi.encode(_hashes));
}
function setBlossomCImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(blossomC, abi.encode(_hashes));
}
function getBlossomImages() external view returns (bytes[] memory) {
bytes[] memory dataA = abi.decode(SSTORE2Map.read(blossomA), (bytes[]));
bytes[] memory dataB = abi.decode(SSTORE2Map.read(blossomB), (bytes[]));
bytes[] memory dataC = abi.decode(SSTORE2Map.read(blossomC), (bytes[]));
bytes[] memory hashes = new bytes[](dataA.length + dataB.length + dataC.length);
for (uint i = 0; i < dataA.length; i++) {
hashes[i] = dataA[i];
}
for (uint i = 0; i < dataB.length; i++) {
hashes[i + dataA.length] = dataB[i];
}
for (uint i = 0; i < dataC.length; i++) {
hashes[i + dataA.length + dataB.length] = dataC[i];
}
return hashes;
}
function setBgImages(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(bg, abi.encode(_hashes));
}
function getBgImages() external view returns (bytes[] memory) {
return abi.decode(SSTORE2Map.read(bg), (bytes[]));
}
function setUnreveal(bytes[] calldata _hashes) external onlyOwner {
SSTORE2Map.write(unreveal, abi.encode(_hashes));
}
function getUnreveal() external view returns (bytes[] memory) {
return abi.decode(SSTORE2Map.read(unreveal), (bytes[]));
}
}
文件 7 的 7:potted_types.sol
pragma solidity ^0.8.7;
interface PottedTypes {
struct Gene {
uint dna;
uint revealNum;
bool isReroll;
}
struct MyPotted {
Potted potted;
Branch branch;
Blossom blossom;
Bg bg;
}
struct Potted {
string traitName;
uint width;
uint height;
uint x;
uint y;
uint id;
}
struct Branch {
string traitName;
uint width;
uint height;
uint unique;
uint x;
uint y;
uint[] pointX;
uint[] pointY;
uint id;
}
struct Blossom {
string traitName;
uint[] width;
uint[] height;
uint[] childs;
uint id;
}
struct Bg {
string traitName;
uint id;
}
}
{
"compilationTarget": {
"contracts/potted_data.sol": "PPData"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"name":"ErrorCreatingContract","type":"error"},{"inputs":[],"name":"ErrorCreatingProxy","type":"error"},{"inputs":[{"internalType":"uint256","name":"_size","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"InvalidCodeAtRange","type":"error"},{"inputs":[],"name":"TargetAlreadyExists","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"getAllBg","outputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Bg[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllBlossom","outputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256[]","name":"width","type":"uint256[]"},{"internalType":"uint256[]","name":"height","type":"uint256[]"},{"internalType":"uint256[]","name":"childs","type":"uint256[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Blossom[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllBranch","outputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"uint256","name":"unique","type":"uint256"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256[]","name":"pointX","type":"uint256[]"},{"internalType":"uint256[]","name":"pointY","type":"uint256[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Branch[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllPotted","outputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Potted[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBgImages","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlossomImages","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBranchImages","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPottedImages","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnreveal","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBgImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Bg[]","name":"_bg","type":"tuple[]"}],"name":"setBgs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBlossomAImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBlossomBImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBlossomCImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256[]","name":"width","type":"uint256[]"},{"internalType":"uint256[]","name":"height","type":"uint256[]"},{"internalType":"uint256[]","name":"childs","type":"uint256[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Blossom[]","name":"_blossom","type":"tuple[]"}],"name":"setBlossoms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBranchAImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBranchBImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setBranchCImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"uint256","name":"unique","type":"uint256"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256[]","name":"pointX","type":"uint256[]"},{"internalType":"uint256[]","name":"pointY","type":"uint256[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Branch[]","name":"_branch","type":"tuple[]"}],"name":"setBranches","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setPottedAImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setPottedBImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setPottedCImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Potted[]","name":"_potted","type":"tuple[]"}],"name":"setPotteds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"_hashes","type":"bytes[]"}],"name":"setUnreveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256[]","name":"width","type":"uint256[]"},{"internalType":"uint256[]","name":"height","type":"uint256[]"},{"internalType":"uint256[]","name":"childs","type":"uint256[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Blossom","name":"newData","type":"tuple"}],"name":"updateBlossom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"uint256","name":"unique","type":"uint256"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256[]","name":"pointX","type":"uint256[]"},{"internalType":"uint256[]","name":"pointY","type":"uint256[]"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Branch","name":"newData","type":"tuple"}],"name":"updateBranch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"uint256","name":"width","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"},{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"}],"internalType":"struct PottedTypes.Potted","name":"newData","type":"tuple"}],"name":"updatePotted","outputs":[],"stateMutability":"nonpayable","type":"function"}]