编译器
0.8.24+commit.e11b9ed9
文件 1 的 9:Base64.sol
pragma solidity ^0.8.17;
library Base64 {
string internal constant TABLE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678"
"9+/";
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return "";
string memory table = TABLE;
uint256 encodedLength = ((data.length + 2) / 3) << 2;
string memory result = new string(encodedLength + 0x20);
assembly {
mstore(result, encodedLength)
let tablePtr := add(table, 1)
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
let resultPtr := add(result, 0x20)
for {
} lt(dataPtr, endPtr) {
} {
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
mstore(
resultPtr,
shl(0xF8, mload(add(tablePtr, and(shr(0x12, input), 0x3F))))
)
resultPtr := add(resultPtr, 1)
mstore(
resultPtr,
shl(0xF8, mload(add(tablePtr, and(shr(0xC, input), 0x3F))))
)
resultPtr := add(resultPtr, 1)
mstore(
resultPtr,
shl(0xF8, mload(add(tablePtr, and(shr(6, input), 0x3F))))
)
resultPtr := add(resultPtr, 1)
mstore(
resultPtr,
shl(0xF8, mload(add(tablePtr, and(input, 0x3F))))
)
resultPtr := add(resultPtr, 1)
}
switch mod(mload(data), 3)
case 1 {
mstore(sub(resultPtr, 2), shl(0xF0, 0x3D3D))
}
case 2 {
mstore(sub(resultPtr, 1), shl(0xF8, 0x3D))
}
}
return result;
}
}
文件 2 的 9:ColormapDataConstants.sol
pragma solidity ^0.8.21;
bytes8 constant GNUPLOT_COLORMAP_HASH = 0xfd29b65966772202;
string constant GNUPLOT_NAME = "gnuplot";
bool constant GNUPLOT_IS_DARK = true;
bytes8 constant CMRMAP_COLORMAP_HASH = 0x850ce48e7291439b;
string constant CMRMAP_NAME = "CMRmap";
bool constant CMRMAP_IS_DARK = true;
bytes8 constant WISTIA_COLORMAP_HASH = 0x4f5e8ea8862eff31;
string constant WISTIA_NAME = "Wistia";
bool constant WISTIA_IS_DARK = false;
bytes8 constant AUTUMN_COLORMAP_HASH = 0xf2e92189cb6903b9;
string constant AUTUMN_NAME = "autumn";
bool constant AUTUMN_IS_DARK = false;
bytes8 constant BINARY_COLORMAP_HASH = 0xa33e6c7c5627ecab;
string constant BINARY_NAME = "binary";
bool constant BINARY_IS_DARK = false;
bytes8 constant BONE_COLORMAP_HASH = 0xaa84b30df806b46f;
string constant BONE_NAME = "bone";
bool constant BONE_IS_DARK = true;
bytes8 constant COOL_COLORMAP_HASH = 0x864a6ee98b9b21ac;
string constant COOL_NAME = "cool";
bool constant COOL_IS_DARK = false;
bytes8 constant COPPER_COLORMAP_HASH = 0xfd60cd3811f00281;
string constant COPPER_NAME = "copper";
bool constant COPPER_IS_DARK = true;
bytes8 constant GIST_RAINBOW_COLORMAP_HASH = 0xa8309447f8bd3b5e;
string constant GIST_RAINBOW_NAME = "gist_rainbow";
bool constant GIST_RAINBOW_IS_DARK = false;
bytes8 constant GIST_STERN_COLORMAP_HASH = 0x3be719b0c3427972;
string constant GIST_STERN_NAME = "gist_stern";
bool constant GIST_STERN_IS_DARK = true;
bytes8 constant GRAY_COLORMAP_HASH = 0xca0da6b6309ed211;
string constant GRAY_NAME = "gray";
bool constant GRAY_IS_DARK = true;
bytes8 constant HOT_COLORMAP_HASH = 0x5ccb29670bb9de0e;
string constant HOT_NAME = "hot";
bool constant HOT_IS_DARK = true;
bytes8 constant HSV_COLORMAP_HASH = 0x3de8f27f386dab3d;
string constant HSV_NAME = "hsv";
bool constant HSV_IS_DARK = false;
bytes8 constant JET_COLORMAP_HASH = 0x026736ef8439ebcf;
string constant JET_NAME = "jet";
bool constant JET_IS_DARK = true;
bytes8 constant SPRING_COLORMAP_HASH = 0xc1806ea961848ac0;
string constant SPRING_NAME = "spring";
bool constant SPRING_IS_DARK = false;
bytes8 constant SUMMER_COLORMAP_HASH = 0x87970b686eb72675;
string constant SUMMER_NAME = "summer";
bool constant SUMMER_IS_DARK = false;
bytes8 constant TERRAIN_COLORMAP_HASH = 0xaa6277ab923279cf;
string constant TERRAIN_NAME = "terrain";
bool constant TERRAIN_IS_DARK = true;
bytes8 constant WINTER_COLORMAP_HASH = 0xdc1cecffc00e2f31;
string constant WINTER_NAME = "winter";
bool constant WINTER_IS_DARK = true;
文件 3 的 9:ERC721.sol
pragma solidity >=0.8.0;
abstract contract ERC721 {
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
string public name;
string public symbol;
function tokenURI(uint256 id) public view virtual returns (string memory);
mapping(uint256 => address) internal _ownerOf;
mapping(address => uint256) internal _balanceOf;
function ownerOf(uint256 id) public view virtual returns (address owner) {
require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
}
function balanceOf(address owner) public view virtual returns (uint256) {
require(owner != address(0), "ZERO_ADDRESS");
return _balanceOf[owner];
}
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
function approve(address spender, uint256 id) public virtual {
address owner = _ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == _ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
"NOT_AUTHORIZED"
);
unchecked {
_balanceOf[from]--;
_balanceOf[to]++;
}
_ownerOf[id] = to;
delete getApproved[id];
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes calldata data
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f;
}
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(_ownerOf[id] == address(0), "ALREADY_MINTED");
unchecked {
_balanceOf[to]++;
}
_ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = _ownerOf[id];
require(owner != address(0), "NOT_MINTED");
unchecked {
_balanceOf[owner]--;
}
delete _ownerOf[id];
delete getApproved[id];
emit Transfer(owner, address(0), id);
}
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
abstract contract ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
}
文件 4 的 9:IColormapRegistry.sol
pragma solidity ^0.8.21;
import {IPaletteGenerator} from "@/contracts/interfaces/IPaletteGenerator.sol";
interface IColormapRegistry {
error ColormapAlreadyExists(bytes8 _hash);
error ColormapDoesNotExist(bytes8 _hash);
error SegmentDataInvalid(uint256 _segmentData);
struct SegmentData {
uint256 r;
uint256 g;
uint256 b;
}
event RegisterColormap(bytes8 _hash, IPaletteGenerator _paletteGenerator);
event RegisterColormap(bytes8 _hash, SegmentData _segmentData);
function paletteGenerators(
bytes8 _hash
) external view returns (IPaletteGenerator);
function segments(
bytes8 _hash
) external view returns (uint256, uint256, uint256);
function batchRegister(
IPaletteGenerator[] memory _paletteGenerators
) external;
function batchRegister(SegmentData[] memory _segmentDataArray) external;
function register(IPaletteGenerator _paletteGenerator) external;
function register(SegmentData memory _segmentData) external;
function getValue(
bytes8 _hash,
uint256 _position
) external view returns (uint256, uint256, uint256);
function getValueAsHexString(
bytes8 _hash,
uint8 _position
) external view returns (string memory);
function getValueAsUint8(
bytes8 _hash,
uint8 _position
) external view returns (uint8, uint8, uint8);
}
文件 5 的 9:IPaletteGenerator.sol
pragma solidity ^0.8.21;
interface IPaletteGenerator {
error InvalidPosition(uint256 _position);
function r(uint256 _position) external pure returns (uint256);
function g(uint256 _position) external pure returns (uint256);
function b(uint256 _position) external pure returns (uint256);
}
文件 6 的 9:LibString.sol
pragma solidity >=0.8.0;
library LibString {
function toString(int256 value) internal pure returns (string memory str) {
if (value >= 0) return toString(uint256(value));
unchecked {
str = toString(uint256(-value));
assembly {
let length := mload(str)
mstore(str, 45)
str := sub(str, 1)
mstore(str, add(length, 1))
}
}
}
function toString(uint256 value) internal pure returns (string memory str) {
assembly {
let newFreeMemoryPointer := add(mload(0x40), 160)
mstore(0x40, newFreeMemoryPointer)
str := sub(newFreeMemoryPointer, 32)
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, 32)
mstore(str, length)
}
}
}
文件 7 的 9:Owned.sol
pragma solidity >=0.8.0;
abstract contract Owned {
event OwnershipTransferred(address indexed user, address indexed newOwner);
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}
文件 8 的 9:Shapes.sol
pragma solidity ^0.8.21;
contract Shape {
function circle() public pure returns (string memory) {
return '<circle r="10" fill="#';
}
function square() public pure returns (string memory) {
return '<rect x="-10" y="-10" width="20" height="20" fill="#';
}
function triangle() public pure returns (string memory) {
return '<polygon points="0,-10 10,0 0,10 -10,0" fill="#';
}
function hexagon() public pure returns (string memory) {
return '<polygon points="-8.66,-5 0,-10 8.66,-5 8.66,5 0,10 -8.66,5" fill="#';
}
function star() public pure returns (string memory) {
return '<polygon points="0,-12 4,-4 12,0 4,4 0,12 -4,4 -12,0 -4,-4" fill="#';
}
function cross() public pure returns (string memory) {
return '<path d="M-10,-10 L10,10 M-10,10 L10,-10" stroke="#';
}
}
文件 9 的 9:ShapesOnGrid.sol
pragma solidity ^0.8.21;
import {Owned} from "solmate/auth/Owned.sol";
import {ERC721} from "solmate/tokens/ERC721.sol";
import {LibString} from "solmate/utils/LibString.sol";
import "@/contracts/utils/ColormapDataConstants.sol";
import {IColormapRegistry} from "@/contracts/interfaces/IColormapRegistry.sol";
import {Base64} from "@/contracts/utils/Base64.sol";
import "@/contracts/utils/Shapes.sol";
contract Shapes is ERC721, Owned {
bytes32 constant SALT = bytes32("Shapes");
address constant OWNER_ADDRESS = 0xb95963833048892D6E3193D0e20D48Beea892fF2;
IColormapRegistry immutable colormapRegistry;
uint256 public totalSupply;
Shape shape = new Shape();
constructor() ERC721("Shapes", "SHP") Owned(OWNER_ADDRESS) {
colormapRegistry = IColormapRegistry(0x00000000A84FcdF3E9C165e6955945E87dA2cB0D);
for (uint256 i = 1; i < 6;) {
_mint(OWNER_ADDRESS, i);
unchecked {
++i;
}
}
totalSupply = 5;
}
function mint() external {
require(totalSupply < 590 && balanceOf(msg.sender) < 1, "Ineligible Mint");
unchecked {
_mint(msg.sender, ++totalSupply);
}
}
function withdraw() external onlyOwner {
(bool success,) = payable(owner).call{value: address(this).balance}("");
require(success);
}
function tokenURI(uint256 _tokenId) public view override returns (string memory) {
require(_ownerOf[_tokenId] != address(0), "NOT_MINTED");
uint256 seed = uint256(keccak256(abi.encodePacked(_tokenId, SALT)));
(bytes8 colormapHash, string memory colormapName, bool isDark) = _getColormap(seed % 18);
return string.concat(
"data:application/json;base64,",
Base64.encode(
abi.encodePacked(
'{"name":"Shapes #',
LibString.toString(_tokenId),
'","description":"On-chain shapes grid, inspired by fiveoutofnine.",',
'"image_data":"data:image/svg+xml;base64,',
Base64.encode(abi.encodePacked(_renderSvg(seed, colormapHash, isDark))),
'","attributes":[{"trait_type":"Colormap","value":"',
colormapName,
'"}]}'
)
)
);
}
function _renderSvg(uint256 _seed, bytes8 _colormapHash, bool _isDark) internal view returns (string memory) {
string memory svgContents;
uint256 i;
while (_seed != 0 && i < 80) {
uint8 position = uint8(1 << (_seed & 7));
string memory color = colormapRegistry.getValueAsHexString(_colormapHash, position);
unchecked {
{
svgContents = string.concat(
svgContents,
'<g transform="translate(',
LibString.toString(uint256(196 + (i & 7) * 40)),
" ",
LibString.toString(uint256(160 + (i / 8) * 40)),
')"><rect x="-20" y="-20" width="40" height="40" stroke="#',
_isDark ? "E6E6E6" : "191919",
'" fill="#',
_isDark ? "F5F5F5" : "111111",
'"/>',
((_seed >> (i % 8)) & 6 == 0)
? shape.square()
: ((_seed >> (i % 8)) & 6 == 1)
? shape.circle()
: ((_seed >> (i % 8)) & 6 == 2)
? shape.triangle()
: ((_seed >> (i % 8)) & 6 == 3)
? shape.cross()
: ((_seed >> (i % 8)) & 6 == 4) ? shape.star() : shape.hexagon(),
color,
'"/></g>'
);
}
_seed >>= 3;
++i;
}
}
return string.concat(
'<svg width="680" height="680" viewBox="0 0 680 680" fill="none" xmlns="http://www.w3.org/2000/svg">',
'<path xmlns="http://www.w3.org/2000/svg" d="M680 0H0V680H680V0Z" fill="',
_isDark ? "white" : "black",
'"/>',
svgContents,
"</svg>"
);
}
function _getColormap(uint256 _index) internal pure returns (bytes8, string memory, bool) {
if (_index < 9) {
if (_index < 4) {
if (_index < 2) {
if (_index == 0) {
return (GNUPLOT_COLORMAP_HASH, GNUPLOT_NAME, GNUPLOT_IS_DARK);
}
return (CMRMAP_COLORMAP_HASH, CMRMAP_NAME, CMRMAP_IS_DARK);
}
if (_index == 2) {
return (WISTIA_COLORMAP_HASH, WISTIA_NAME, WISTIA_IS_DARK);
}
return (AUTUMN_COLORMAP_HASH, AUTUMN_NAME, AUTUMN_IS_DARK);
}
if (_index < 6) {
if (_index == 4) {
return (BINARY_COLORMAP_HASH, BINARY_NAME, BINARY_IS_DARK);
}
return (BONE_COLORMAP_HASH, BONE_NAME, BONE_IS_DARK);
}
if (_index < 7) {
if (_index == 6) {
return (COOL_COLORMAP_HASH, COOL_NAME, COOL_IS_DARK);
}
return (COPPER_COLORMAP_HASH, COPPER_NAME, COPPER_IS_DARK);
}
return (GIST_RAINBOW_COLORMAP_HASH, GIST_RAINBOW_NAME, GIST_RAINBOW_IS_DARK);
}
if (_index < 13) {
if (_index < 11) {
if (_index == 9) {
return (GIST_STERN_COLORMAP_HASH, GIST_STERN_NAME, GIST_STERN_IS_DARK);
}
return (GRAY_COLORMAP_HASH, GRAY_NAME, GRAY_IS_DARK);
}
if (_index == 11) {
return (HOT_COLORMAP_HASH, HOT_NAME, HOT_IS_DARK);
}
return (HSV_COLORMAP_HASH, HSV_NAME, HSV_IS_DARK);
}
if (_index < 15) {
if (_index == 13) {
return (JET_COLORMAP_HASH, JET_NAME, JET_IS_DARK);
}
return (SPRING_COLORMAP_HASH, SPRING_NAME, SPRING_IS_DARK);
}
if (_index < 17) {
if (_index == 15) {
return (SUMMER_COLORMAP_HASH, SUMMER_NAME, SUMMER_IS_DARK);
}
return (TERRAIN_COLORMAP_HASH, TERRAIN_NAME, TERRAIN_IS_DARK);
}
return (WINTER_COLORMAP_HASH, WINTER_NAME, WINTER_IS_DARK);
}
receive() external payable {}
}
{
"compilationTarget": {
"src/ShapesOnGrid.sol": "Shapes"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@/contracts/=src/",
":forge-std/=lib/forge-std/src/",
":solmate/=lib/solmate/src/"
]
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","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":"user","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":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","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":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","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":"id","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":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]