编译器
0.8.20+commit.a1b79de6
文件 1 的 9:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 9:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 3 的 9:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/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, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 4 的 9:ITheChainCollection.sol
pragma solidity 0.8.20;
interface ITheChainCollection {
struct HashData {
bytes32 previousHash;
address creator;
uint96 tokenId;
string uri;
}
function mint(
uint256 tokenId,
address creator,
address transferTo,
bytes32 currentHash,
bytes32 previousHash,
string calldata uri
) external;
}
文件 5 的 9:ITheChainSales.sol
pragma solidity 0.8.20;
interface ITheChainSales {
event NewOrder(uint256 orderId, address creator, uint256 tokenId, uint256 price, uint256 startsAt);
event OrderClosed(uint256 orderId, address operator, bool canceled);
struct Order {
address creator;
uint96 price;
uint128 tokenId;
uint128 startsAt;
}
function getOrders(uint256[] calldata orderIds) external view returns (Order[] memory);
function fulfillOrder(uint256 orderId) external payable;
function createOrder(address creator, uint96 price, uint128 tokenId, uint128 startsAt) external;
}
文件 6 的 9: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);
}
}
文件 7 的 9:OwnableOperators.sol
pragma solidity 0.8.20;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {WithOperators} from "./WithOperators.sol";
abstract contract OwnableOperators is Ownable, WithOperators {
modifier onlyOperator() virtual override {
if (msg.sender != owner()) {
if (!operators[msg.sender]) {
revert NotAuthorized();
}
}
_;
}
function setOperators(address[] memory operatorsList, bool isOperator) public onlyOwner {
_setOperators(operatorsList, isOperator);
}
}
文件 8 的 9:TheChainSales.sol
pragma solidity 0.8.20;
import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol";
import {OwnableOperators} from "./utils/OwnableOperators.sol";
import {ITheChainCollection} from "./interfaces/ITheChainCollection.sol";
import {ITheChainSales} from "./interfaces/ITheChainSales.sol";
contract TheChainSales is ITheChainSales, OwnableOperators {
error InvalidOrder();
error TooEarly();
error InvalidPayment();
error FailedPayment();
error TokenNotEscrowed();
error UnknownOrder();
error OrderExpired();
struct ShareHolder {
address account;
uint96 share;
}
address public immutable THE_CHAIN;
mapping(uint256 => Order) public orders;
ShareHolder public theChainShare;
uint256 private _lastOrderId;
uint256 public startsAt;
constructor(address theChain, ShareHolder memory initShare) {
THE_CHAIN = theChain;
theChainShare = initShare;
}
function getOrders(uint256[] calldata orderIds) external view override returns (Order[] memory) {
uint256 length = orderIds.length;
Order[] memory results = new Order[](length);
for (uint i; i < length; i++) {
results[i] = orders[orderIds[i]];
}
return results;
}
function fulfillOrder(uint256 orderId) external payable override {
Order memory order = _requireOrderExists(orderId);
if (order.startsAt > block.timestamp || startsAt > block.timestamp) {
revert TooEarly();
}
if (msg.value != order.price) {
revert InvalidPayment();
}
delete orders[orderId];
emit OrderClosed(orderId, msg.sender, false);
ShareHolder memory theChainShare_ = theChainShare;
uint256 share = (msg.value * theChainShare_.share) / 10000;
if (share > 0) {
_transferValue(theChainShare_.account, share);
}
_transferValue(order.creator, msg.value - share);
IERC721(THE_CHAIN).transferFrom(address(this), msg.sender, order.tokenId);
}
function createOrder(address creator, uint96 price, uint128 tokenId, uint128 saleStartsAt) external onlyOperator {
_requireEscrowed(tokenId);
uint256 orderId = ++_lastOrderId;
orders[orderId] = Order(creator, price, tokenId, saleStartsAt);
emit NewOrder(orderId, creator, tokenId, price, saleStartsAt);
}
function cancelOrder(uint256 orderId, address recipient) external {
if (msg.sender != owner()) {
if (msg.sender != orders[orderId].creator) {
revert NotAuthorized();
}
}
_cancelOrder(orderId, recipient);
}
function cancelOrders(uint256[] memory orderIds, address recipient) external onlyOwner {
uint256 length = orderIds.length;
for (uint256 i; i < length; i++) {
_cancelOrder(orderIds[i], recipient);
}
}
function editTheChainShares(ShareHolder calldata newShares) external onlyOwner {
theChainShare = newShares;
}
function setStartsAt(uint256 newStartsAt) external onlyOwner {
startsAt = newStartsAt;
}
function _transferValue(address payee, uint256 value) internal {
(bool success, ) = payee.call{value: value, gas: 30_000}("");
if (!success) {
revert FailedPayment();
}
}
function _requireOrderExists(uint256 orderId) internal view returns (Order memory) {
Order memory order = orders[orderId];
if (order.creator == address(0)) {
if (orderId <= _lastOrderId) {
revert OrderExpired();
} else {
revert UnknownOrder();
}
}
_requireEscrowed(order.tokenId);
return order;
}
function _requireEscrowed(uint256 tokenId) internal view {
if (IERC721(THE_CHAIN).ownerOf(tokenId) != address(this)) {
revert TokenNotEscrowed();
}
}
function _cancelOrder(uint256 orderId, address recipient) internal {
Order memory order = _requireOrderExists(orderId);
delete orders[orderId];
emit OrderClosed(orderId, msg.sender, true);
IERC721(THE_CHAIN).transferFrom(address(this), recipient, order.tokenId);
}
}
文件 9 的 9:WithOperators.sol
pragma solidity 0.8.20;
abstract contract WithOperators {
error NotAuthorized();
mapping(address => bool) public operators;
modifier onlyOperator() virtual {
if (!operators[msg.sender]) {
revert NotAuthorized();
}
_;
}
function _setOperators(address[] memory operatorsList, bool isOperator) internal virtual {
uint256 length = operatorsList.length;
for (uint256 i; i < length; i++) {
operators[operatorsList[i]] = isOperator;
}
}
}
{
"compilationTarget": {
"src/TheChainSales.sol": "TheChainSales"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 2000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"theChain","type":"address"},{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint96","name":"share","type":"uint96"}],"internalType":"struct TheChainSales.ShareHolder","name":"initShare","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FailedPayment","type":"error"},{"inputs":[],"name":"InvalidOrder","type":"error"},{"inputs":[],"name":"InvalidPayment","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"OrderExpired","type":"error"},{"inputs":[],"name":"TokenNotEscrowed","type":"error"},{"inputs":[],"name":"TooEarly","type":"error"},{"inputs":[],"name":"UnknownOrder","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startsAt","type":"uint256"}],"name":"NewOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"canceled","type":"bool"}],"name":"OrderClosed","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"},{"inputs":[],"name":"THE_CHAIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"orderIds","type":"uint256[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"cancelOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint128","name":"tokenId","type":"uint128"},{"internalType":"uint128","name":"saleStartsAt","type":"uint128"}],"name":"createOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint96","name":"share","type":"uint96"}],"internalType":"struct TheChainSales.ShareHolder","name":"newShares","type":"tuple"}],"name":"editTheChainShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"fulfillOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"orderIds","type":"uint256[]"}],"name":"getOrders","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint128","name":"tokenId","type":"uint128"},{"internalType":"uint128","name":"startsAt","type":"uint128"}],"internalType":"struct ITheChainSales.Order[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"operators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"orders","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint128","name":"tokenId","type":"uint128"},{"internalType":"uint128","name":"startsAt","type":"uint128"}],"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":"address[]","name":"operatorsList","type":"address[]"},{"internalType":"bool","name":"isOperator","type":"bool"}],"name":"setOperators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newStartsAt","type":"uint256"}],"name":"setStartsAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startsAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"theChainShare","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint96","name":"share","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]