Address Contract Verified
Address
0x1c359d3954812E39489eb0D887757aDaBb12E6D8
Balance
0 ETH
Nonce
1
Code Size
4633 bytes
Creator
0x86711bab...137B at tx 0x90ee1dbe...429c06
Indexed Transactions
0
Contract Bytecode
4633 bytes
0x608060405234801561001057600080fd5b50600436106100df5760003560e01c80636e773eb81161008c578063c3c9f76f11610066578063c3c9f76f14610200578063cf517f6414610213578063e2c345e214610233578063f2fde38b1461024e57600080fd5b80636e773eb8146101c7578063715018a6146101da5780638da5cb5b146101e257600080fd5b8063482eea7b116100bd578063482eea7b1461017f578063517e809e1461019257806365771c61146101a757600080fd5b80632d47c3da146100e457806340a653dc1461010057806347ccca0214610133575b600080fd5b6100ed60025481565b6040519081526020015b60405180910390f35b61012361010e366004610bbb565b60036020526000908152604090205460ff1681565b60405190151581526020016100f7565b61015a7f000000000000000000000000960b7a6bcd451c9968473f7bbfd9be826efd549a81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f7565b6100ed61018d366004610bbb565b610261565b6101a56101a0366004610bfd565b610294565b005b60015461015a9073ffffffffffffffffffffffffffffffffffffffff1681565b6101a56101d5366004610c6b565b6102e3565b6101a56103bc565b60005473ffffffffffffffffffffffffffffffffffffffff1661015a565b6101a561020e366004610d9e565b6103d0565b610226610221366004610e52565b61042e565b6040516100f79190610e74565b61015a7327cb33476bf69e025927a07b6732cdfd8f7618e481565b6101a561025c366004610bfd565b610501565b60008181526003602052604081205460ff1661027f57506000919050565b61028e82640a7b451d40610ee7565b92915050565b61029c61056a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8860005b818110156103ae5761039e8c8c8381811061030457610304610efa565b905060200201358b8b8481811061031d5761031d610efa565b90506020020160208101906103329190610bfd565b8a8a8581811061034457610344610efa565b90506020028101906103569190610f29565b8a8a8781811061036857610368610efa565b905060200281019061037a9190610f29565b8a8a8981811061038c5761038c610efa565b905060200281019061020e9190610f29565b6103a781610f8e565b90506102e7565b505050505050505050505050565b6103c461056a565b6103ce60006105bd565b565b6103e08888888888888888610632565b610416576040517f41abc80100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610424888888888888610768565b5050505050505050565b600254606090600081900361045357505060408051600081526020810190915261028e565b60008167ffffffffffffffff81111561046e5761046e610fc6565b604051908082528060200260200182016040528015610497578160200160208202803683370190505b5090506000855b8581116104f65760008181526003602052604090205460ff16156104e657808383815181106104cf576104cf610efa565b60209081029190910101526104e382610f8e565b91505b6104ef81610f8e565b905061049e565b509095945050505050565b61050961056a565b73ffffffffffffffffffffffffffffffffffffffff811661055e576040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600060048201526024015b60405180910390fd5b610567816105bd565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ce576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610555565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000807f000000000000000000000000960b7a6bcd451c9968473f7bbfd9be826efd549a8a8a8a8a8a8a6040516020016106729796959493929190610ff5565b6040516020818303038152906040528051906020012090506000816040516020016106c991907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282526001548151602080840191909120601f8a018290048202860182019094528885529194506107599373ffffffffffffffffffffffffffffffffffffffff909116929189908990819084018382808284376000920191909152506108ab92505050565b9b9a5050505050505050505050565b600086815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600280549091906107af90610f8e565b909155506040517f42842e0e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8681166024830152604482018890527f000000000000000000000000960b7a6bcd451c9968473f7bbfd9be826efd549a16906342842e0e90606401600060405180830381600087803b15801561084957600080fd5b505af115801561085d573d6000803e3d6000fd5b50505050857fc05eba7c5eeb227a4a8f4cfa3302be3ec8ff2d5a33962794b2c80008e030d6b333878787878760405161089b969594939291906110a9565b60405180910390a2505050505050565b60008060006108ba8585610927565b50909250905060008160038111156108d4576108d4611103565b14801561090c57508573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b8061091d575061091d868686610974565b9695505050505050565b600080600083516041036109615760208401516040850151606086015160001a61095388828585610ac1565b95509550955050505061096d565b50508151600091506002905b9250925092565b60008060008573ffffffffffffffffffffffffffffffffffffffff1685856040516024016109a3929190611156565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1626ba7e0000000000000000000000000000000000000000000000000000000017905251610a2491906111ae565b600060405180830381855afa9150503d8060008114610a5f576040519150601f19603f3d011682016040523d82523d6000602084013e610a64565b606091505b5091509150818015610a7857506020815110155b801561091d575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090610ab690830160209081019084016111ca565b149695505050505050565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610afc5750600091506003905082610bb1565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610b50573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610ba757506000925060019150829050610bb1565b9250600091508190505b9450945094915050565b600060208284031215610bcd57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bf857600080fd5b919050565b600060208284031215610c0f57600080fd5b610c1882610bd4565b9392505050565b60008083601f840112610c3157600080fd5b50813567ffffffffffffffff811115610c4957600080fd5b6020830191508360208260051b8501011115610c6457600080fd5b9250929050565b60008060008060008060008060008060a08b8d031215610c8a57600080fd5b8a3567ffffffffffffffff80821115610ca257600080fd5b610cae8e838f01610c1f565b909c509a5060208d0135915080821115610cc757600080fd5b610cd38e838f01610c1f565b909a50985060408d0135915080821115610cec57600080fd5b610cf88e838f01610c1f565b909850965060608d0135915080821115610d1157600080fd5b610d1d8e838f01610c1f565b909650945060808d0135915080821115610d3657600080fd5b50610d438d828e01610c1f565b915080935050809150509295989b9194979a5092959850565b60008083601f840112610d6e57600080fd5b50813567ffffffffffffffff811115610d8657600080fd5b602083019150836020828501011115610c6457600080fd5b60008060008060008060008060a0898b031215610dba57600080fd5b88359750610dca60208a01610bd4565b9650604089013567ffffffffffffffff80821115610de757600080fd5b610df38c838d01610d5c565b909850965060608b0135915080821115610e0c57600080fd5b610e188c838d01610d5c565b909650945060808b0135915080821115610e3157600080fd5b50610e3e8b828c01610d5c565b999c989b5096995094979396929594505050565b60008060408385031215610e6557600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015610eac57835183529284019291840191600101610e90565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561028e5761028e610eb8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610f5e57600080fd5b83018035915067ffffffffffffffff821115610f7957600080fd5b602001915036819003821315610c6457600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fbf57610fbf610eb8565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808a60601b168352886014840152808860601b166034840152508486604884013784820160488101600081528486823750600093016048019283525090979650505050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352808816602084015250608060408301526110e3608083018688611060565b82810360608401526110f6818587611060565b9998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60005b8381101561114d578181015183820152602001611135565b50506000910152565b828152604060208201526000825180604084015261117b816060850160208701611132565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b600082516111c0818460208701611132565b9190910192915050565b6000602082840312156111dc57600080fd5b505191905056fea26469706673582212200094b011080e86e4ed7c11b689fc331a466356481348f92b1476177c03dcbb6164736f6c63430008150033
Verified Source Code Full Match
Compiler: v0.8.21+commit.d9974bed
EVM: paris
Optimization: Yes (9999999 runs)
BTCTeleburn.sol 101 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
abstract contract BTCTeleburn is Ownable {
IERC721 public immutable nft;
address public teleburnSigner;
uint256 public teleburnedCount = 0;
mapping(uint256 tokenId => bool) public isTokenTeleburned;
event Teleburn(
uint256 indexed tokenId, address sender, address teleburnAddress, string btcAddress, string inscriptionId
);
error InvalidRequest();
constructor(address nft_, address teleburnSigner_) Ownable(msg.sender) {
nft = IERC721(nft_);
teleburnSigner = teleburnSigner_;
}
function teleburnedTokens(uint256 startTokenId, uint256 endTokenId) external view returns (uint256[] memory) {
uint256 count = teleburnedCount;
if (count == 0) return new uint256[](0);
uint256[] memory tokens = new uint256[](count);
uint256 index;
for (uint256 i = startTokenId; i <= endTokenId; ++i) {
if (isTokenTeleburned[i]) {
tokens[index] = i;
++index;
}
}
return tokens;
}
function getTokenSatNumber(uint256 tokenId) external view returns (uint256) {
if (!isTokenTeleburned[tokenId]) return 0;
return 45017800000 + tokenId;
}
function teleburnMultipleTokens(
uint256[] calldata tokenIds,
address[] calldata teleburnAddresses,
string[] calldata btcAddresses,
string[] calldata inscriptionIds,
bytes[] calldata data
) external {
uint256 count = tokenIds.length;
for (uint256 i; i < count; ++i) {
teleburnToken(tokenIds[i], teleburnAddresses[i], btcAddresses[i], inscriptionIds[i], data[i]);
}
}
function teleburnToken(
uint256 tokenId,
address teleburnAddress,
string calldata btcAddress,
string calldata inscriptionId,
bytes calldata data
) public {
if (!_isValidRequest(tokenId, teleburnAddress, btcAddress, inscriptionId, data)) {
revert InvalidRequest();
}
_teleburn(tokenId, teleburnAddress, btcAddress, inscriptionId);
}
function updateTeleburnSigner(address newTeleburnSigner) external onlyOwner {
teleburnSigner = newTeleburnSigner;
}
function _teleburn(
uint256 tokenId,
address teleburnAddress,
string calldata btcAddress,
string calldata inscriptionId
) private {
isTokenTeleburned[tokenId] = true;
++teleburnedCount;
nft.safeTransferFrom(msg.sender, teleburnAddress, tokenId);
emit Teleburn(tokenId, msg.sender, teleburnAddress, btcAddress, inscriptionId);
}
/// @dev args: tokenId, teleburnAddress, btcAddress, inscriptionId, data
function _isValidRequest(uint256, address, string calldata, string calldata, bytes calldata)
internal
view
virtual
returns (bool)
{
return true;
}
}
GenesisTeleburn.sol 29 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;
import {BTCTeleburn} from "./BTCTeleburn.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
contract GenesisTeleburn is BTCTeleburn {
address public constant originalContract = 0x27Cb33476bf69E025927a07b6732Cdfd8f7618E4;
constructor(address nft, address teleburnSigner_) BTCTeleburn(nft, teleburnSigner_) {
teleburnedCount = 3;
isTokenTeleburned[1003] = true;
isTokenTeleburned[1543] = true;
isTokenTeleburned[1589] = true;
}
function _isValidRequest(
uint256 tokenId,
address burnAddress,
string calldata btcAddress,
string calldata inscriptionId,
bytes calldata signature
) internal view override returns (bool) {
bytes32 message = keccak256(abi.encodePacked(nft, tokenId, burnAddress, btcAddress, inscriptionId));
bytes memory prefixedMessage = abi.encodePacked("\x19Ethereum Signed Message:\n32", message);
return SignatureChecker.isValidSignatureNow(teleburnSigner, keccak256(prefixedMessage), signature);
}
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
IERC1271.sol 17 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*/
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
IERC721.sol 135 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
ECDSA.sol 174 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*/
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError, bytes32) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
SignatureChecker.sol 48 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/SignatureChecker.sol)
pragma solidity ^0.8.20;
import {ECDSA} from "./ECDSA.sol";
import {IERC1271} from "../../interfaces/IERC1271.sol";
/**
* @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA
* signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like
* Argent and Safe Wallet (previously Gnosis Safe).
*/
library SignatureChecker {
/**
* @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
* signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.
*
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
* change through time. It could return true at block N and false at block N+1 (or the opposite).
*/
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
(address recovered, ECDSA.RecoverError error, ) = ECDSA.tryRecover(hash, signature);
return
(error == ECDSA.RecoverError.NoError && recovered == signer) ||
isValidERC1271SignatureNow(signer, hash, signature);
}
/**
* @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
* against the signer smart contract using ERC1271.
*
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
* change through time. It could return true at block N and false at block N+1 (or the opposite).
*/
function isValidERC1271SignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(bool success, bytes memory result) = signer.staticcall(
abi.encodeCall(IERC1271.isValidSignature, (hash, signature))
);
return (success &&
result.length >= 32 &&
abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));
}
}
Read Contract
getTokenSatNumber 0x482eea7b → uint256
isTokenTeleburned 0x40a653dc → bool
nft 0x47ccca02 → address
originalContract 0xe2c345e2 → address
owner 0x8da5cb5b → address
teleburnSigner 0x65771c61 → address
teleburnedCount 0x2d47c3da → uint256
teleburnedTokens 0xcf517f64 → uint256[]
Write Contract 5 functions
These functions modify contract state and require a wallet transaction to execute.
renounceOwnership 0x715018a6
No parameters
teleburnMultipleTokens 0x6e773eb8
uint256[] tokenIds
address[] teleburnAddresses
string[] btcAddresses
string[] inscriptionIds
bytes[] data
teleburnToken 0xc3c9f76f
uint256 tokenId
address teleburnAddress
string btcAddress
string inscriptionId
bytes data
transferOwnership 0xf2fde38b
address newOwner
updateTeleburnSigner 0x517e809e
address newTeleburnSigner
Recent Transactions
No transactions found for this address