OpepenhoodSeaDrop
0x6bd4d575f3b832d19d1acd48dc17de4a821e6ff3
Verification
Verified
v0.8.17+commit.8df45f5f
Type
Contract
16,884 bytes
ABI entries
94
22 read · 29 write
License
none
Contract information
- Address
- 0x6bd4d575f3b832d19d1acd48dc17de4a821e6ff3
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.17+commit.8df45f5f
- Optimization
- Enabled
- Creator
- 0xCB43078C32…B5faE217F9
- Creation tx
- 0x404633cc44…8e78a5d549
Token
- Name
- Opepenhood
- Symbol
- OPHOOD
- Decimals
- —
- Holders
- 358
- Market
- View token page →
Read contract (22)
balanceOf(address) → uint256
baseURI() → string
contractURI() → string
getApproved(uint256) → address
getMintStats(address) → uint256, uint256, uint256
getTransferValidationFunction() → bytes4, bool
getTransferValidator() → address
isApprovedForAll(address, address) → bool
maxSupply() → uint256
name() → string
owner() → address
ownerOf(uint256) → address
provenanceHash() → bytes32
renderer() → address
royaltyAddress() → address
royaltyBasisPoints() → uint256
royaltyInfo(uint256, uint256) → address, uint256
seedOf(uint256) → uint256
supportsInterface(bytes4) → bool
symbol() → string
tokenURI(uint256) → string
totalSupply() → uint256
Events (15)
AllowedSeaDropUpdatedApprovalApprovalForAllBatchMetadataUpdateConsecutiveTransferContractURIUpdatedMaxSupplyUpdatedOwnershipTransferredPotentialOwnerUpdatedProvenanceHashUpdatedRendererSetRoyaltyInfoUpdatedSeaDropTokenDeployedTransferTransferValidatorUpdated
ABI
[
{
"inputs": [
{
"internalType": "string",
"name": "name_",
"type": "string"
},
{
"internalType": "string",
"name": "symbol_",
"type": "string"
},
{
"internalType": "address[]",
"name": "allowedSeaDrop_",
"type": "address[]"
},
{
"internalType": "address",
"name": "renderer_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyInitialized",
"type": "error"
},
{
"inputs": [],
"name": "ApprovalCallerNotOwnerNorApproved",
"type": "error"
},
{
"inputs": [],
"name": "ApprovalQueryForNonexistentToken",
"type": "error"
},
{
"inputs": [],
"name": "BalanceQueryForZeroAddress",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newMaxSupply",
"type": "uint256"
}
],
"name": "CannotExceedMaxSupplyOfUint64",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "basisPoints",
"type": "uint256"
}
],
"name": "InvalidRoyaltyBasisPoints",
"type": "error"
},
{
"inputs": [],
"name": "MintERC2309QuantityExceedsLimit",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "total",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxSupply",
"type": "uint256"
}
],
"name": "MintQuantityExceedsMaxSupply",
"type": "error"
},
{
"inputs": [],
"name": "MintToZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "MintZeroQuantity",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "got",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalMinted",
"type": "uint256"
}
],
"name": "NewMaxSupplyCannotBeLessThenTotalMinted",
"type": "error"
},
{
"inputs": [],
"name": "NewOwnerIsZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "NotNextOwner",
"type": "error"
},
{
"inputs": [],
"name": "OnlyAllowedSeaDrop",
"type": "error"
},
{
"inputs": [],
"name": "OnlyOwner",
"type": "error"
},
{
"inputs": [],
"name": "OwnerQueryForNonexistentToken",
"type": "error"
},
{
"inputs": [],
"name": "OwnershipNotInitializedForExtraData",
"type": "error"
},
{
"inputs": [],
"name": "ProvenanceHashCannotBeSetAfterMintStarted",
"type": "error"
},
{
"inputs": [],
"name": "RoyaltyAddressCannotBeZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "SameTransferValidator",
"type": "error"
},
{
"inputs": [],
"name": "SignersMismatch",
"type": "error"
},
{
"inputs": [],
"name": "TokenGatedMismatch",
"type": "error"
},
{
"inputs": [],
"name": "TransferCallerNotOwnerNorApproved",
"type": "error"
},
{
"inputs": [],
"name": "TransferFromIncorrectOwner",
"type": "error"
},
{
"inputs": [],
"name": "TransferToNonERC721ReceiverImplementer",
"type": "error"
},
{
"inputs": [],
"name": "TransferToZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "URIQueryForNonexistentToken",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address[]",
"name": "allowedSeaDrop",
"type": "address[]"
}
],
"name": "AllowedSeaDropUpdated",
"type": "event"
},
{
"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": false,
"internalType": "uint256",
"name": "_fromTokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_toTokenId",
"type": "uint256"
}
],
"name": "BatchMetadataUpdate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "fromTokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "toTokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "ConsecutiveTransfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "newContractURI",
"type": "string"
}
],
"name": "ContractURIUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "newMaxSupply",
"type": "uint256"
}
],
"name": "MaxSupplyUpdated",
"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": false,
"internalType": "address",
"name": "newPotentialAdministrator",
"type": "address"
}
],
"name": "PotentialOwnerUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes32",
"name": "previousHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "newHash",
"type": "bytes32"
}
],
"name": "ProvenanceHashUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "renderer",
"type": "address"
}
],
"name": "RendererSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bps",
"type": "uint256"
}
],
"name": "RoyaltyInfoUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "SeaDropTokenDeployed",
"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"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "oldValidator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "newValidator",
"type": "address"
}
],
"name": "TransferValidatorUpdated",
"type": "event"
},
{
"inputs": [],
"name": "acceptOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"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": "baseURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "cancelOwnershipTransfer",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "contractURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "fromTokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "toTokenId",
"type": "uint256"
}
],
"name": "emitBatchMetadataUpdate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "minter",
"type": "address"
}
],
"name": "getMintStats",
"outputs": [
{
"internalType": "uint256",
"name": "minterNumMinted",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "currentTotalSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxSupply",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getTransferValidationFunction",
"outputs": [
{
"internalType": "bytes4",
"name": "functionSignature",
"type": "bytes4"
},
{
"internalType": "bool",
"name": "isViewFunction",
"type": "bool"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "getTransferValidator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"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": "maxSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "minter",
"type": "address"
},
{
"internalType": "uint256",
"name": "quantity",
"type": "uint256"
}
],
"name": "mintSeaDrop",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint256",
"name": "maxSupply",
"type": "uint256"
},
{
"internalType": "string",
"name": "baseURI",
"type": "string"
},
{
"internalType": "string",
"name": "contractURI",
"type": "string"
},
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"components": [
{
"internalType": "uint80",
"name": "mintPrice",
"type": "uint80"
},
{
"internalType": "uint48",
"name": "startTime",
"type": "uint48"
},
{
"internalType": "uint48",
"name": "endTime",
"type": "uint48"
},
{
"internalType": "uint16",
"name": "maxTotalMintableByWallet",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "feeBps",
"type": "uint16"
},
{
"internalType": "bool",
"name": "restrictFeeRecipients",
"type": "bool"
}
],
"internalType": "struct PublicDrop",
"name": "publicDrop",
"type": "tuple"
},
{
"internalType": "string",
"name": "dropURI",
"type": "string"
},
{
"components": [
{
"internalType": "bytes32",
"name": "merkleRoot",
"type": "bytes32"
},
{
"internalType": "string[]",
"name": "publicKeyURIs",
"type": "string[]"
},
{
"internalType": "string",
"name": "allowListURI",
"type": "string"
}
],
"internalType": "struct AllowListData",
"name": "allowListData",
"type": "tuple"
},
{
"internalType": "address",
"name": "creatorPayoutAddress",
"type": "address"
},
{
"internalType": "bytes32",
"name": "provenanceHash",
"type": "bytes32"
},
{
"internalType": "address[]",
"name": "allowedFeeRecipients",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "disallowedFeeRecipients",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "allowedPayers",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "disallowedPayers",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "tokenGatedAllowedNftTokens",
"type": "address[]"
},
{
"components": [
{
"internalType": "uint80",
"name": "mintPrice",
"type": "uint80"
},
{
"internalType": "uint16",
"name": "maxTotalMintableByWallet",
"type": "uint16"
},
{
"internalType": "uint48",
"name": "startTime",
"type": "uint48"
},
{
"internalType": "uint48",
"name": "endTime",
"type": "uint48"
},
{
"internalType": "uint8",
"name": "dropStageIndex",
"type": "uint8"
},
{
"internalType": "uint32",
"name": "maxTokenSupplyForStage",
"type": "uint32"
},
{
"internalType": "uint16",
"name": "feeBps",
"type": "uint16"
},
{
"internalType": "bool",
"name": "restrictFeeRecipients",
"type": "bool"
}
],
"internalType": "struct TokenGatedDropStage[]",
"name": "tokenGatedDropStages",
"type": "tuple[]"
},
{
"internalType": "address[]",
"name": "disallowedTokenGatedAllowedNftTokens",
"type": "address[]"
},
{
"internalType": "address[]",
"name": "signers",
"type": "address[]"
},
{
"components": [
{
"internalType": "uint80",
"name": "minMintPrice",
"type": "uint80"
},
{
"internalType": "uint24",
"name": "maxMaxTotalMintableByWallet",
"type": "uint24"
},
{
"internalType": "uint40",
"name": "minStartTime",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "maxEndTime",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "maxMaxTokenSupplyForStage",
"type": "uint40"
},
{
"internalType": "uint16",
"name": "minFeeBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "maxFeeBps",
"type": "uint16"
}
],
"internalType": "struct SignedMintValidationParams[]",
"name": "signedMintValidationParams",
"type": "tuple[]"
},
{
"internalType": "address[]",
"name": "disallowedSigners",
"type": "address[]"
}
],
"internalType": "struct ERC721SeaDropStructsErrorsAndEvents.MultiConfigureStruct",
"name": "config",
"type": "tuple"
}
],
"name": "multiConfigure",
"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": [],
"name": "provenanceHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renderer",
"outputs": [
{
"internalType": "contract IRenderer",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "royaltyAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "royaltyBasisPoints",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_salePrice",
"type": "uint256"
}
],
"name": "royaltyInfo",
"outputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint256",
"name": "royaltyAmount",
"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": "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": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "seedOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "newBaseURI",
"type": "string"
}
],
"name": "setBaseURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "newContractURI",
"type": "string"
}
],
"name": "setContractURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newMaxSupply",
"type": "uint256"
}
],
"name": "setMaxSupply",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "newProvenanceHash",
"type": "bytes32"
}
],
"name": "setProvenanceHash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "renderer_",
"type": "address"
}
],
"name": "setRenderer",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "royaltyAddress",
"type": "address"
},
{
"internalType": "uint96",
"name": "royaltyBps",
"type": "uint96"
}
],
"internalType": "struct ISeaDropTokenContractMetadata.RoyaltyInfo",
"name": "newInfo",
"type": "tuple"
}
],
"name": "setRoyaltyInfo",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newValidator",
"type": "address"
}
],
"name": "setTransferValidator",
"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"
},
{
"inputs": [
{
"internalType": "address",
"name": "newPotentialOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"components": [
{
"internalType": "bytes32",
"name": "merkleRoot",
"type": "bytes32"
},
{
"internalType": "string[]",
"name": "publicKeyURIs",
"type": "string[]"
},
{
"internalType": "string",
"name": "allowListURI",
"type": "string"
}
],
"internalType": "struct AllowListData",
"name": "allowListData",
"type": "tuple"
}
],
"name": "updateAllowList",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"internalType": "address",
"name": "feeRecipient",
"type": "address"
},
{
"internalType": "bool",
"name": "allowed",
"type": "bool"
}
],
"name": "updateAllowedFeeRecipient",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "allowedSeaDrop",
"type": "address[]"
}
],
"name": "updateAllowedSeaDrop",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"internalType": "address",
"name": "payoutAddress",
"type": "address"
}
],
"name": "updateCreatorPayoutAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"internalType": "string",
"name": "dropURI",
"type": "string"
}
],
"name": "updateDropURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"internalType": "address",
"name": "payer",
"type": "address"
},
{
"internalType": "bool",
"name": "allowed",
"type": "bool"
}
],
"name": "updatePayer",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"components": [
{
"internalType": "uint80",
"name": "mintPrice",
"type": "uint80"
},
{
"internalType": "uint48",
"name": "startTime",
"type": "uint48"
},
{
"internalType": "uint48",
"name": "endTime",
"type": "uint48"
},
{
"internalType": "uint16",
"name": "maxTotalMintableByWallet",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "feeBps",
"type": "uint16"
},
{
"internalType": "bool",
"name": "restrictFeeRecipients",
"type": "bool"
}
],
"internalType": "struct PublicDrop",
"name": "publicDrop",
"type": "tuple"
}
],
"name": "updatePublicDrop",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"internalType": "address",
"name": "signer",
"type": "address"
},
{
"components": [
{
"internalType": "uint80",
"name": "minMintPrice",
"type": "uint80"
},
{
"internalType": "uint24",
"name": "maxMaxTotalMintableByWallet",
"type": "uint24"
},
{
"internalType": "uint40",
"name": "minStartTime",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "maxEndTime",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "maxMaxTokenSupplyForStage",
"type": "uint40"
},
{
"internalType": "uint16",
"name": "minFeeBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "maxFeeBps",
"type": "uint16"
}
],
"internalType": "struct SignedMintValidationParams",
"name": "signedMintValidationParams",
"type": "tuple"
}
],
"name": "updateSignedMintValidationParams",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "seaDropImpl",
"type": "address"
},
{
"internalType": "address",
"name": "allowedNftToken",
"type": "address"
},
{
"components": [
{
"internalType": "uint80",
"name": "mintPrice",
"type": "uint80"
},
{
"internalType": "uint16",
"name": "maxTotalMintableByWallet",
"type": "uint16"
},
{
"internalType": "uint48",
"name": "startTime",
"type": "uint48"
},
{
"internalType": "uint48",
"name": "endTime",
"type": "uint48"
},
{
"internalType": "uint8",
"name": "dropStageIndex",
"type": "uint8"
},
{
"internalType": "uint32",
"name": "maxTokenSupplyForStage",
"type": "uint32"
},
{
"internalType": "uint16",
"name": "feeBps",
"type": "uint16"
},
{
"internalType": "bool",
"name": "restrictFeeRecipients",
"type": "bool"
}
],
"internalType": "struct TokenGatedDropStage",
"name": "dropStage",
"type": "tuple"
}
],
"name": "updateTokenGatedDrop",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import { ERC721SeaDrop } from "seadrop/ERC721SeaDrop.sol";
interface IRenderer {
function tokenURI(uint256 tokenId, uint256 seed) external view returns (string memory);
}
/// @title Opepenhood
/// @notice ERC721SeaDrop token whose metadata is rendered 100% on-chain by an
/// external renderer. SeaDrop owns the sale (price, per-wallet limit, fees)
/// so the drop surfaces on OpenSea; this contract owns ownership + metadata.
/// It captures per-mint blockhash entropy in _beforeTokenTransfers so a
/// token's traits are fixed at mint and unknowable beforehand (see seedOf).
/// The renderer is owner-swappable (metadata is intentionally not locked).
contract OpepenhoodSeaDrop is ERC721SeaDrop {
IRenderer public renderer;
/// Per-mint-batch entropy captured at mint (batch first tokenId => seed base).
/// Traits derive from keccak(batchSeed, tokenId), so a token's art is unknowable
/// until it is minted — mint-block entropy no bot can predict at submit time.
mapping(uint256 => uint256) private _batchSeed;
event RendererSet(address indexed renderer);
constructor(
string memory name_,
string memory symbol_,
address[] memory allowedSeaDrop_,
address renderer_
) ERC721SeaDrop(name_, symbol_, allowedSeaDrop_) {
renderer = IRenderer(renderer_);
emit RendererSet(renderer_);
}
/// @dev Capture mint-block entropy per batch. Fires inside ERC721A `_mint`
/// (SeaDrop mints flow through here); no change to the SeaDrop contract.
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual override {
if (from == address(0)) {
_batchSeed[startTokenId] = uint256(
keccak256(abi.encodePacked(blockhash(block.number - 1), block.number, startTokenId))
);
}
super._beforeTokenTransfers(from, to, startTokenId, quantity);
}
/// @notice Deterministic render seed for a token = keccak(batch entropy, tokenId).
/// Walks down to the token's batch start (batches are small: <= per-wallet cap).
function seedOf(uint256 tokenId) public view returns (uint256) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
uint256 id = tokenId;
while (_batchSeed[id] == 0) {
unchecked {
--id;
}
}
return uint256(keccak256(abi.encodePacked(_batchSeed[id], tokenId)));
}
/// @dev On-chain metadata via the external renderer (replaces baseURI behavior).
function tokenURI(uint256 tokenId) public view override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
return renderer.tokenURI(tokenId, seedOf(tokenId));
}
/// @notice Repoint the renderer (metadata is intentionally not locked, so art can
/// be fixed or upgraded post-mint). Passing address(0) reverts tokenURI.
function setRenderer(address renderer_) external onlyOwner {
renderer = IRenderer(renderer_);
emit RendererSet(renderer_);
}
}
Chain explorer2008msChain node81ms