编译器
0.8.19+commit.7dd6d404
文件 1 的 8: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 的 8:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 3 的 8:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 4 的 8:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 5 的 8:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 6 的 8:Minimal1155SBT.sol
pragma solidity 0.8.19;
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
contract Minimal1155SBT is IERC1155, IERC1155MetadataURI, ERC165 {
uint256 public constant TOKEN_ID = 1;
uint256 public constant START_BALANCES_SLOT = uint256(keccak256('1155sbt.start_balances')) - 1;
error TokenIsSoulbound();
string private _uri;
constructor(string memory uri_) {
_setURI(uri_);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155).interfaceId || interfaceId == type(IERC1155MetadataURI).interfaceId
|| super.supportsInterface(interfaceId);
}
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
require(id == TOKEN_ID, "ERC1155: invalid token ID");
return 0;
}
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
function setApprovalForAll(address, bool ) public pure override {
revert TokenIsSoulbound();
}
function isApprovedForAll(address, address ) public pure override returns (bool) {
return false;
}
function safeTransferFrom(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override {
revert TokenIsSoulbound();
}
function safeBatchTransferFrom(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override {
revert TokenIsSoulbound();
}
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
emit URI(newuri, TOKEN_ID);
}
}
文件 7 的 8:MoonlingsSBT.sol
pragma solidity 0.8.19;
import "./Minimal1155SBT.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MoonlingsSBT is Minimal1155SBT, Ownable {
bool public canAirdrop = true;
uint256 public supply = 0;
string public name = "GMoonling to You - Moonpass";
string public symbol = "GMLING";
uint256 private _storageCounter = START_BALANCES_SLOT;
uint256 private _storageUpto = 0;
constructor(string memory uri_) Minimal1155SBT(uri_) {}
function airdrop(bytes calldata addresses) external onlyOwner {
require(canAirdrop, "Airdrop has been disabled");
require(addresses.length % 20 == 0, "Invalid addresses length");
uint256 _storageCounterVal = _storageCounter;
uint256 _storageUptoVal = _storageUpto;
supply += addresses.length / 20;
assembly {
let sz := div(addresses.length, 20)
let storageCounter := _storageCounterVal
let currentStoreAcc := sload(_storageCounterVal)
let upto := _storageUptoVal
let operator := caller()
let zeroAddress := 0
let signature := 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62
mstore(0x40, 1)
mstore(0x60, 1)
for {
let i := 0
} lt(i, sz) {
i := add(i, 1)
} {
let offset := mul(i, 20)
let toAirdropTo := shr(96, calldataload(add(addresses.offset, offset)))
log4(0x40, 0x40, signature, operator, zeroAddress, toAirdropTo)
switch gt(upto, 11)
case 0 {
currentStoreAcc := or(currentStoreAcc, shl(sub(96, mul(upto, 8)), toAirdropTo))
upto := add(upto, 20)
}
default {
let overlap := sub(upto, 12)
let toStore := or(currentStoreAcc, shr(mul(overlap, 8), toAirdropTo))
sstore(storageCounter, toStore)
storageCounter := add(storageCounter, 1)
currentStoreAcc := shl(sub(256, mul(overlap, 8)), toAirdropTo)
upto := overlap
}
}
if gt(upto, 0) {
sstore(storageCounter, currentStoreAcc)
}
_storageCounterVal := storageCounter
_storageUptoVal := upto
}
_storageCounter = _storageCounterVal;
_storageUpto = _storageUptoVal;
}
function getAddressIndexed(uint256 index) public view returns (address toReturn) {
uint256 startBalancesSlot = START_BALANCES_SLOT;
assembly {
toReturn := 0
let storageCounter := startBalancesSlot
let slotIn := div(mul(20, index), 32)
let indexIn := mod(mul(20, index), 32)
let slot := sload(add(storageCounter, slotIn))
toReturn := shl(mul(indexIn, 8), slot)
switch gt(indexIn, 12)
case 0 {
toReturn := shr(96, toReturn)
}
default {
let overlap := sub(indexIn, 12)
toReturn := shl(mul(overlap, 8), shr(add(96, mul(overlap, 8)), toReturn))
let slot2 := sload(add(storageCounter, add(slotIn, 1)))
toReturn := or(toReturn, shr(sub(256, mul(overlap, 8)), slot2))
}
}
}
function _isAddressIncluded(address toFind, uint256 begin, uint256 end) internal view returns (bool ret) {
uint160 toFindInt = uint160(toFind);
uint256 len = end - begin;
if (len == 0) {
return false;
} else if (len == 1) {
return toFind == getAddressIndexed(begin);
}
uint256 mid = begin + len / 2;
uint160 midAddr = uint160(getAddressIndexed(mid));
if (uint160(midAddr) > toFindInt) {
return _isAddressIncluded(toFind, begin, mid);
} else if (uint160(midAddr) < toFindInt) {
return _isAddressIncluded(toFind, mid, end);
}
return true;
}
function balanceOf(address account, uint256 id) public view override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
require(id == TOKEN_ID, "ERC1155: invalid token ID");
return _isAddressIncluded(account, 0, supply) ? 1 : 0;
}
function setURI(string memory uri_) external onlyOwner {
_setURI(uri_);
}
function renounceAirdropRights() external onlyOwner {
canAirdrop = false;
}
}
文件 8 的 8: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);
}
}
{
"compilationTarget": {
"contracts/MoonlingsSBT.sol": "MoonlingsSBT"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"TokenIsSoulbound","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"START_BALANCES_SLOT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"addresses","type":"bytes"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canAirdrop","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getAddressIndexed","outputs":[{"internalType":"address","name":"toReturn","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":"pure","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":[],"name":"renounceAirdropRights","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"uri_","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]