├── .gitignore ├── README.md ├── hh ├── .gitignore ├── README.md ├── contracts │ └── Dev.sol ├── hardhat.config.js ├── package.json ├── scripts │ └── deploy.js ├── test │ └── sample-test.js └── yarn.lock └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The deployed contract address on Ethereum mainnet is here: [0x25ed58c027921E14D86380eA2646E3a1B5C55A8b](https://etherscan.io/address/0x25ed58c027921e14d86380ea2646e3a1b5c55a8b) 2 | 3 | The OpenSea page for the collection is here: [https://opensea.io/collection/devs-for-revolution](https://opensea.io/collection/devs-for-revolution) -------------------------------------------------------------------------------- /hh/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | 4 | #Hardhat files 5 | cache 6 | artifacts 7 | -------------------------------------------------------------------------------- /hh/README.md: -------------------------------------------------------------------------------- 1 | # Basic Sample Hardhat Project 2 | 3 | This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts. 4 | 5 | Try running some of the following tasks: 6 | 7 | ```shell 8 | npx hardhat accounts 9 | npx hardhat compile 10 | npx hardhat clean 11 | npx hardhat test 12 | npx hardhat node 13 | node scripts/sample-script.js 14 | npx hardhat help 15 | ``` 16 | -------------------------------------------------------------------------------- /hh/contracts/Dev.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2021-08-27 3 | */ 4 | 5 | // SPDX-License-Identifier: MIT 6 | 7 | pragma solidity ^0.8.0; 8 | 9 | /** 10 | * @dev Interface of the ERC165 standard, as defined in the 11 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 12 | * 13 | * Implementers can declare support of contract interfaces, which can then be 14 | * queried by others ({ERC165Checker}). 15 | * 16 | * For an implementation, see {ERC165}. 17 | */ 18 | interface IERC165 { 19 | /** 20 | * @dev Returns true if this contract implements the interface defined by 21 | * `interfaceId`. See the corresponding 22 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 23 | * to learn more about how these ids are created. 24 | * 25 | * This function call must use less than 30 000 gas. 26 | */ 27 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 28 | } 29 | 30 | 31 | 32 | 33 | 34 | 35 | /** 36 | * @dev Required interface of an ERC721 compliant contract. 37 | */ 38 | interface IERC721 is IERC165 { 39 | /** 40 | * @dev Emitted when `tokenId` token is transferred from `from` to `to`. 41 | */ 42 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 43 | 44 | /** 45 | * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. 46 | */ 47 | event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); 48 | 49 | /** 50 | * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. 51 | */ 52 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 53 | 54 | /** 55 | * @dev Returns the number of tokens in ``owner``'s account. 56 | */ 57 | function balanceOf(address owner) external view returns (uint256 balance); 58 | 59 | /** 60 | * @dev Returns the owner of the `tokenId` token. 61 | * 62 | * Requirements: 63 | * 64 | * - `tokenId` must exist. 65 | */ 66 | function ownerOf(uint256 tokenId) external view returns (address owner); 67 | 68 | /** 69 | * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients 70 | * are aware of the ERC721 protocol to prevent tokens from being forever locked. 71 | * 72 | * Requirements: 73 | * 74 | * - `from` cannot be the zero address. 75 | * - `to` cannot be the zero address. 76 | * - `tokenId` token must exist and be owned by `from`. 77 | * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. 78 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 79 | * 80 | * Emits a {Transfer} event. 81 | */ 82 | function safeTransferFrom( 83 | address from, 84 | address to, 85 | uint256 tokenId 86 | ) external; 87 | 88 | /** 89 | * @dev Transfers `tokenId` token from `from` to `to`. 90 | * 91 | * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. 92 | * 93 | * Requirements: 94 | * 95 | * - `from` cannot be the zero address. 96 | * - `to` cannot be the zero address. 97 | * - `tokenId` token must be owned by `from`. 98 | * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 99 | * 100 | * Emits a {Transfer} event. 101 | */ 102 | function transferFrom( 103 | address from, 104 | address to, 105 | uint256 tokenId 106 | ) external; 107 | 108 | /** 109 | * @dev Gives permission to `to` to transfer `tokenId` token to another account. 110 | * The approval is cleared when the token is transferred. 111 | * 112 | * Only a single account can be approved at a time, so approving the zero address clears previous approvals. 113 | * 114 | * Requirements: 115 | * 116 | * - The caller must own the token or be an approved operator. 117 | * - `tokenId` must exist. 118 | * 119 | * Emits an {Approval} event. 120 | */ 121 | function approve(address to, uint256 tokenId) external; 122 | 123 | /** 124 | * @dev Returns the account approved for `tokenId` token. 125 | * 126 | * Requirements: 127 | * 128 | * - `tokenId` must exist. 129 | */ 130 | function getApproved(uint256 tokenId) external view returns (address operator); 131 | 132 | /** 133 | * @dev Approve or remove `operator` as an operator for the caller. 134 | * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. 135 | * 136 | * Requirements: 137 | * 138 | * - The `operator` cannot be the caller. 139 | * 140 | * Emits an {ApprovalForAll} event. 141 | */ 142 | function setApprovalForAll(address operator, bool _approved) external; 143 | 144 | /** 145 | * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. 146 | * 147 | * See {setApprovalForAll} 148 | */ 149 | function isApprovedForAll(address owner, address operator) external view returns (bool); 150 | 151 | /** 152 | * @dev Safely transfers `tokenId` token from `from` to `to`. 153 | * 154 | * Requirements: 155 | * 156 | * - `from` cannot be the zero address. 157 | * - `to` cannot be the zero address. 158 | * - `tokenId` token must exist and be owned by `from`. 159 | * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. 160 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 161 | * 162 | * Emits a {Transfer} event. 163 | */ 164 | function safeTransferFrom( 165 | address from, 166 | address to, 167 | uint256 tokenId, 168 | bytes calldata data 169 | ) external; 170 | } 171 | 172 | 173 | 174 | 175 | /** 176 | * @dev String operations. 177 | */ 178 | library Strings { 179 | bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; 180 | 181 | /** 182 | * @dev Converts a `uint256` to its ASCII `string` decimal representation. 183 | */ 184 | function toString(uint256 value) internal pure returns (string memory) { 185 | // Inspired by OraclizeAPI's implementation - MIT licence 186 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 187 | 188 | if (value == 0) { 189 | return "0"; 190 | } 191 | uint256 temp = value; 192 | uint256 digits; 193 | while (temp != 0) { 194 | digits++; 195 | temp /= 10; 196 | } 197 | bytes memory buffer = new bytes(digits); 198 | while (value != 0) { 199 | digits -= 1; 200 | buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); 201 | value /= 10; 202 | } 203 | return string(buffer); 204 | } 205 | 206 | /** 207 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. 208 | */ 209 | function toHexString(uint256 value) internal pure returns (string memory) { 210 | if (value == 0) { 211 | return "0x00"; 212 | } 213 | uint256 temp = value; 214 | uint256 length = 0; 215 | while (temp != 0) { 216 | length++; 217 | temp >>= 8; 218 | } 219 | return toHexString(value, length); 220 | } 221 | 222 | /** 223 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. 224 | */ 225 | function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 226 | bytes memory buffer = new bytes(2 * length + 2); 227 | buffer[0] = "0"; 228 | buffer[1] = "x"; 229 | for (uint256 i = 2 * length + 1; i > 1; --i) { 230 | buffer[i] = _HEX_SYMBOLS[value & 0xf]; 231 | value >>= 4; 232 | } 233 | require(value == 0, "Strings: hex length insufficient"); 234 | return string(buffer); 235 | } 236 | } 237 | 238 | 239 | 240 | 241 | /* 242 | * @dev Provides information about the current execution context, including the 243 | * sender of the transaction and its data. While these are generally available 244 | * via msg.sender and msg.data, they should not be accessed in such a direct 245 | * manner, since when dealing with meta-transactions the account sending and 246 | * paying for execution may not be the actual sender (as far as an application 247 | * is concerned). 248 | * 249 | * This contract is only required for intermediate, library-like contracts. 250 | */ 251 | abstract contract Context { 252 | function _msgSender() internal view virtual returns (address) { 253 | return msg.sender; 254 | } 255 | 256 | function _msgData() internal view virtual returns (bytes calldata) { 257 | return msg.data; 258 | } 259 | } 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | /** 270 | * @dev Contract module which provides a basic access control mechanism, where 271 | * there is an account (an owner) that can be granted exclusive access to 272 | * specific functions. 273 | * 274 | * By default, the owner account will be the one that deploys the contract. This 275 | * can later be changed with {transferOwnership}. 276 | * 277 | * This module is used through inheritance. It will make available the modifier 278 | * `onlyOwner`, which can be applied to your functions to restrict their use to 279 | * the owner. 280 | */ 281 | abstract contract Ownable is Context { 282 | address private _owner; 283 | 284 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 285 | 286 | /** 287 | * @dev Initializes the contract setting the deployer as the initial owner. 288 | */ 289 | constructor() { 290 | _setOwner(_msgSender()); 291 | } 292 | 293 | /** 294 | * @dev Returns the address of the current owner. 295 | */ 296 | function owner() public view virtual returns (address) { 297 | return _owner; 298 | } 299 | 300 | /** 301 | * @dev Throws if called by any account other than the owner. 302 | */ 303 | modifier onlyOwner() { 304 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 305 | _; 306 | } 307 | 308 | /** 309 | * @dev Leaves the contract without owner. It will not be possible to call 310 | * `onlyOwner` functions anymore. Can only be called by the current owner. 311 | * 312 | * NOTE: Renouncing ownership will leave the contract without an owner, 313 | * thereby removing any functionality that is only available to the owner. 314 | */ 315 | function renounceOwnership() public virtual onlyOwner { 316 | _setOwner(address(0)); 317 | } 318 | 319 | /** 320 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 321 | * Can only be called by the current owner. 322 | */ 323 | function transferOwnership(address newOwner) public virtual onlyOwner { 324 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 325 | _setOwner(newOwner); 326 | } 327 | 328 | function _setOwner(address newOwner) private { 329 | address oldOwner = _owner; 330 | _owner = newOwner; 331 | emit OwnershipTransferred(oldOwner, newOwner); 332 | } 333 | } 334 | 335 | 336 | 337 | 338 | 339 | /** 340 | * @dev Contract module that helps prevent reentrant calls to a function. 341 | * 342 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 343 | * available, which can be applied to functions to make sure there are no nested 344 | * (reentrant) calls to them. 345 | * 346 | * Note that because there is a single `nonReentrant` guard, functions marked as 347 | * `nonReentrant` may not call one another. This can be worked around by making 348 | * those functions `private`, and then adding `external` `nonReentrant` entry 349 | * points to them. 350 | * 351 | * TIP: If you would like to learn more about reentrancy and alternative ways 352 | * to protect against it, check out our blog post 353 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 354 | */ 355 | abstract contract ReentrancyGuard { 356 | // Booleans are more expensive than uint256 or any type that takes up a full 357 | // word because each write operation emits an extra SLOAD to first read the 358 | // slot's contents, replace the bits taken up by the boolean, and then write 359 | // back. This is the compiler's defense against contract upgrades and 360 | // pointer aliasing, and it cannot be disabled. 361 | 362 | // The values being non-zero value makes deployment a bit more expensive, 363 | // but in exchange the refund on every call to nonReentrant will be lower in 364 | // amount. Since refunds are capped to a percentage of the total 365 | // transaction's gas, it is best to keep them low in cases like this one, to 366 | // increase the likelihood of the full refund coming into effect. 367 | uint256 private constant _NOT_ENTERED = 1; 368 | uint256 private constant _ENTERED = 2; 369 | 370 | uint256 private _status; 371 | 372 | constructor() { 373 | _status = _NOT_ENTERED; 374 | } 375 | 376 | /** 377 | * @dev Prevents a contract from calling itself, directly or indirectly. 378 | * Calling a `nonReentrant` function from another `nonReentrant` 379 | * function is not supported. It is possible to prevent this from happening 380 | * by making the `nonReentrant` function external, and make it call a 381 | * `private` function that does the actual work. 382 | */ 383 | modifier nonReentrant() { 384 | // On the first call to nonReentrant, _notEntered will be true 385 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 386 | 387 | // Any calls to nonReentrant after this point will fail 388 | _status = _ENTERED; 389 | 390 | _; 391 | 392 | // By storing the original value once again, a refund is triggered (see 393 | // https://eips.ethereum.org/EIPS/eip-2200) 394 | _status = _NOT_ENTERED; 395 | } 396 | } 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | /** 412 | * @title ERC721 token receiver interface 413 | * @dev Interface for any contract that wants to support safeTransfers 414 | * from ERC721 asset contracts. 415 | */ 416 | interface IERC721Receiver { 417 | /** 418 | * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} 419 | * by `operator` from `from`, this function is called. 420 | * 421 | * It must return its Solidity selector to confirm the token transfer. 422 | * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. 423 | * 424 | * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. 425 | */ 426 | function onERC721Received( 427 | address operator, 428 | address from, 429 | uint256 tokenId, 430 | bytes calldata data 431 | ) external returns (bytes4); 432 | } 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | /** 441 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension 442 | * @dev See https://eips.ethereum.org/EIPS/eip-721 443 | */ 444 | interface IERC721Metadata is IERC721 { 445 | /** 446 | * @dev Returns the token collection name. 447 | */ 448 | function name() external view returns (string memory); 449 | 450 | /** 451 | * @dev Returns the token collection symbol. 452 | */ 453 | function symbol() external view returns (string memory); 454 | 455 | /** 456 | * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. 457 | */ 458 | function tokenURI(uint256 tokenId) external view returns (string memory); 459 | } 460 | 461 | 462 | 463 | 464 | 465 | /** 466 | * @dev Collection of functions related to the address type 467 | */ 468 | library Address { 469 | /** 470 | * @dev Returns true if `account` is a contract. 471 | * 472 | * [IMPORTANT] 473 | * ==== 474 | * It is unsafe to assume that an address for which this function returns 475 | * false is an externally-owned account (EOA) and not a contract. 476 | * 477 | * Among others, `isContract` will return false for the following 478 | * types of addresses: 479 | * 480 | * - an externally-owned account 481 | * - a contract in construction 482 | * - an address where a contract will be created 483 | * - an address where a contract lived, but was destroyed 484 | * ==== 485 | */ 486 | function isContract(address account) internal view returns (bool) { 487 | // This method relies on extcodesize, which returns 0 for contracts in 488 | // construction, since the code is only stored at the end of the 489 | // constructor execution. 490 | 491 | uint256 size; 492 | assembly { 493 | size := extcodesize(account) 494 | } 495 | return size > 0; 496 | } 497 | 498 | /** 499 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 500 | * `recipient`, forwarding all available gas and reverting on errors. 501 | * 502 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 503 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 504 | * imposed by `transfer`, making them unable to receive funds via 505 | * `transfer`. {sendValue} removes this limitation. 506 | * 507 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 508 | * 509 | * IMPORTANT: because control is transferred to `recipient`, care must be 510 | * taken to not create reentrancy vulnerabilities. Consider using 511 | * {ReentrancyGuard} or the 512 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 513 | */ 514 | function sendValue(address payable recipient, uint256 amount) internal { 515 | require(address(this).balance >= amount, "Address: insufficient balance"); 516 | 517 | (bool success, ) = recipient.call{value: amount}(""); 518 | require(success, "Address: unable to send value, recipient may have reverted"); 519 | } 520 | 521 | /** 522 | * @dev Performs a Solidity function call using a low level `call`. A 523 | * plain `call` is an unsafe replacement for a function call: use this 524 | * function instead. 525 | * 526 | * If `target` reverts with a revert reason, it is bubbled up by this 527 | * function (like regular Solidity function calls). 528 | * 529 | * Returns the raw returned data. To convert to the expected return value, 530 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 531 | * 532 | * Requirements: 533 | * 534 | * - `target` must be a contract. 535 | * - calling `target` with `data` must not revert. 536 | * 537 | * _Available since v3.1._ 538 | */ 539 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 540 | return functionCall(target, data, "Address: low-level call failed"); 541 | } 542 | 543 | /** 544 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 545 | * `errorMessage` as a fallback revert reason when `target` reverts. 546 | * 547 | * _Available since v3.1._ 548 | */ 549 | function functionCall( 550 | address target, 551 | bytes memory data, 552 | string memory errorMessage 553 | ) internal returns (bytes memory) { 554 | return functionCallWithValue(target, data, 0, errorMessage); 555 | } 556 | 557 | /** 558 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 559 | * but also transferring `value` wei to `target`. 560 | * 561 | * Requirements: 562 | * 563 | * - the calling contract must have an ETH balance of at least `value`. 564 | * - the called Solidity function must be `payable`. 565 | * 566 | * _Available since v3.1._ 567 | */ 568 | function functionCallWithValue( 569 | address target, 570 | bytes memory data, 571 | uint256 value 572 | ) internal returns (bytes memory) { 573 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 574 | } 575 | 576 | /** 577 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 578 | * with `errorMessage` as a fallback revert reason when `target` reverts. 579 | * 580 | * _Available since v3.1._ 581 | */ 582 | function functionCallWithValue( 583 | address target, 584 | bytes memory data, 585 | uint256 value, 586 | string memory errorMessage 587 | ) internal returns (bytes memory) { 588 | require(address(this).balance >= value, "Address: insufficient balance for call"); 589 | require(isContract(target), "Address: call to non-contract"); 590 | 591 | (bool success, bytes memory returndata) = target.call{value: value}(data); 592 | return _verifyCallResult(success, returndata, errorMessage); 593 | } 594 | 595 | /** 596 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 597 | * but performing a static call. 598 | * 599 | * _Available since v3.3._ 600 | */ 601 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 602 | return functionStaticCall(target, data, "Address: low-level static call failed"); 603 | } 604 | 605 | /** 606 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 607 | * but performing a static call. 608 | * 609 | * _Available since v3.3._ 610 | */ 611 | function functionStaticCall( 612 | address target, 613 | bytes memory data, 614 | string memory errorMessage 615 | ) internal view returns (bytes memory) { 616 | require(isContract(target), "Address: static call to non-contract"); 617 | 618 | (bool success, bytes memory returndata) = target.staticcall(data); 619 | return _verifyCallResult(success, returndata, errorMessage); 620 | } 621 | 622 | /** 623 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 624 | * but performing a delegate call. 625 | * 626 | * _Available since v3.4._ 627 | */ 628 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 629 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 630 | } 631 | 632 | /** 633 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 634 | * but performing a delegate call. 635 | * 636 | * _Available since v3.4._ 637 | */ 638 | function functionDelegateCall( 639 | address target, 640 | bytes memory data, 641 | string memory errorMessage 642 | ) internal returns (bytes memory) { 643 | require(isContract(target), "Address: delegate call to non-contract"); 644 | 645 | (bool success, bytes memory returndata) = target.delegatecall(data); 646 | return _verifyCallResult(success, returndata, errorMessage); 647 | } 648 | 649 | function _verifyCallResult( 650 | bool success, 651 | bytes memory returndata, 652 | string memory errorMessage 653 | ) private pure returns (bytes memory) { 654 | if (success) { 655 | return returndata; 656 | } else { 657 | // Look for revert reason and bubble it up if present 658 | if (returndata.length > 0) { 659 | // The easiest way to bubble the revert reason is using memory via assembly 660 | 661 | assembly { 662 | let returndata_size := mload(returndata) 663 | revert(add(32, returndata), returndata_size) 664 | } 665 | } else { 666 | revert(errorMessage); 667 | } 668 | } 669 | } 670 | } 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | /** 681 | * @dev Implementation of the {IERC165} interface. 682 | * 683 | * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check 684 | * for the additional interface id that will be supported. For example: 685 | * 686 | * ```solidity 687 | * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 688 | * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); 689 | * } 690 | * ``` 691 | * 692 | * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. 693 | */ 694 | abstract contract ERC165 is IERC165 { 695 | /** 696 | * @dev See {IERC165-supportsInterface}. 697 | */ 698 | function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 699 | return interfaceId == type(IERC165).interfaceId; 700 | } 701 | } 702 | 703 | 704 | /** 705 | * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including 706 | * the Metadata extension, but not including the Enumerable extension, which is available separately as 707 | * {ERC721Enumerable}. 708 | */ 709 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { 710 | using Address for address; 711 | using Strings for uint256; 712 | 713 | // Token name 714 | string private _name; 715 | 716 | // Token symbol 717 | string private _symbol; 718 | 719 | // Mapping from token ID to owner address 720 | mapping(uint256 => address) private _owners; 721 | 722 | // Mapping owner address to token count 723 | mapping(address => uint256) private _balances; 724 | 725 | // Mapping from token ID to approved address 726 | mapping(uint256 => address) private _tokenApprovals; 727 | 728 | // Mapping from owner to operator approvals 729 | mapping(address => mapping(address => bool)) private _operatorApprovals; 730 | 731 | /** 732 | * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. 733 | */ 734 | constructor(string memory name_, string memory symbol_) { 735 | _name = name_; 736 | _symbol = symbol_; 737 | } 738 | 739 | /** 740 | * @dev See {IERC165-supportsInterface}. 741 | */ 742 | function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { 743 | return 744 | interfaceId == type(IERC721).interfaceId || 745 | interfaceId == type(IERC721Metadata).interfaceId || 746 | super.supportsInterface(interfaceId); 747 | } 748 | 749 | /** 750 | * @dev See {IERC721-balanceOf}. 751 | */ 752 | function balanceOf(address owner) public view virtual override returns (uint256) { 753 | require(owner != address(0), "ERC721: balance query for the zero address"); 754 | return _balances[owner]; 755 | } 756 | 757 | /** 758 | * @dev See {IERC721-ownerOf}. 759 | */ 760 | function ownerOf(uint256 tokenId) public view virtual override returns (address) { 761 | address owner = _owners[tokenId]; 762 | require(owner != address(0), "ERC721: owner query for nonexistent token"); 763 | return owner; 764 | } 765 | 766 | /** 767 | * @dev See {IERC721Metadata-name}. 768 | */ 769 | function name() public view virtual override returns (string memory) { 770 | return _name; 771 | } 772 | 773 | /** 774 | * @dev See {IERC721Metadata-symbol}. 775 | */ 776 | function symbol() public view virtual override returns (string memory) { 777 | return _symbol; 778 | } 779 | 780 | /** 781 | * @dev See {IERC721Metadata-tokenURI}. 782 | */ 783 | function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { 784 | require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); 785 | 786 | string memory baseURI = _baseURI(); 787 | return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; 788 | } 789 | 790 | /** 791 | * @dev Base URI for computing {f& 792 | }. If set, the resulting URI for each 793 | * token will be the concatenation of the `baseURI` and the `tokenId`. Empty 794 | * by default, can be overriden in child contracts. 795 | */ 796 | function _baseURI() internal view virtual returns (string memory) { 797 | return ""; 798 | } 799 | 800 | /** 801 | * @dev See {IERC721-approve}. 802 | */ 803 | function approve(address to, uint256 tokenId) public virtual override { 804 | address owner = ERC721.ownerOf(tokenId); 805 | require(to != owner, "ERC721: approval to current owner"); 806 | 807 | require( 808 | _msgSender() == owner || isApprovedForAll(owner, _msgSender()), 809 | "ERC721: approve caller is not owner nor approved for all" 810 | ); 811 | 812 | _approve(to, tokenId); 813 | } 814 | 815 | /** 816 | * @dev See {IERC721-getApproved}. 817 | */ 818 | function getApproved(uint256 tokenId) public view virtual override returns (address) { 819 | require(_exists(tokenId), "ERC721: approved query for nonexistent token"); 820 | 821 | return _tokenApprovals[tokenId]; 822 | } 823 | 824 | /** 825 | * @dev See {IERC721-setApprovalForAll}. 826 | */ 827 | function setApprovalForAll(address operator, bool approved) public virtual override { 828 | require(operator != _msgSender(), "ERC721: approve to caller"); 829 | 830 | _operatorApprovals[_msgSender()][operator] = approved; 831 | emit ApprovalForAll(_msgSender(), operator, approved); 832 | } 833 | 834 | /** 835 | * @dev See {IERC721-isApprovedForAll}. 836 | */ 837 | function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { 838 | return _operatorApprovals[owner][operator]; 839 | } 840 | 841 | /** 842 | * @dev See {IERC721-transferFrom}. 843 | */ 844 | function transferFrom( 845 | address from, 846 | address to, 847 | uint256 tokenId 848 | ) public virtual override { 849 | //solhint-disable-next-line max-line-length 850 | require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); 851 | 852 | _transfer(from, to, tokenId); 853 | } 854 | 855 | /** 856 | * @dev See {IERC721-safeTransferFrom}. 857 | */ 858 | function safeTransferFrom( 859 | address from, 860 | address to, 861 | uint256 tokenId 862 | ) public virtual override { 863 | safeTransferFrom(from, to, tokenId, ""); 864 | } 865 | 866 | /** 867 | * @dev See {IERC721-safeTransferFrom}. 868 | */ 869 | function safeTransferFrom( 870 | address from, 871 | address to, 872 | uint256 tokenId, 873 | bytes memory _data 874 | ) public virtual override { 875 | require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); 876 | _safeTransfer(from, to, tokenId, _data); 877 | } 878 | 879 | /** 880 | * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients 881 | * are aware of the ERC721 protocol to prevent tokens from being forever locked. 882 | * 883 | * `_data` is additional data, it has no specified format and it is sent in call to `to`. 884 | * 885 | * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. 886 | * implement alternative mechanisms to perform token transfer, such as signature-based. 887 | * 888 | * Requirements: 889 | * 890 | * - `from` cannot be the zero address. 891 | * - `to` cannot be the zero address. 892 | * - `tokenId` token must exist and be owned by `from`. 893 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 894 | * 895 | * Emits a {Transfer} event. 896 | */ 897 | function _safeTransfer( 898 | address from, 899 | address to, 900 | uint256 tokenId, 901 | bytes memory _data 902 | ) internal virtual { 903 | _transfer(from, to, tokenId); 904 | require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); 905 | } 906 | 907 | /** 908 | * @dev Returns whether `tokenId` exists. 909 | * 910 | * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. 911 | * 912 | * Tokens start existing when they are minted (`_mint`), 913 | * and stop existing when they are burned (`_burn`). 914 | */ 915 | function _exists(uint256 tokenId) internal view virtual returns (bool) { 916 | return _owners[tokenId] != address(0); 917 | } 918 | 919 | /** 920 | * @dev Returns whether `spender` is allowed to manage `tokenId`. 921 | * 922 | * Requirements: 923 | * 924 | * - `tokenId` must exist. 925 | */ 926 | function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { 927 | require(_exists(tokenId), "ERC721: operator query for nonexistent token"); 928 | address owner = ERC721.ownerOf(tokenId); 929 | return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); 930 | } 931 | 932 | /** 933 | * @dev Safely mints `tokenId` and transfers it to `to`. 934 | * 935 | * Requirements: 936 | * 937 | * - `tokenId` must not exist. 938 | * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. 939 | * 940 | * Emits a {Transfer} event. 941 | */ 942 | function _safeMint(address to, uint256 tokenId) internal virtual { 943 | _safeMint(to, tokenId, ""); 944 | } 945 | 946 | /** 947 | * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is 948 | * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. 949 | */ 950 | function _safeMint( 951 | address to, 952 | uint256 tokenId, 953 | bytes memory _data 954 | ) internal virtual { 955 | _mint(to, tokenId); 956 | require( 957 | _checkOnERC721Received(address(0), to, tokenId, _data), 958 | "ERC721: transfer to non ERC721Receiver implementer" 959 | ); 960 | } 961 | 962 | /** 963 | * @dev Mints `tokenId` and transfers it to `to`. 964 | * 965 | * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible 966 | * 967 | * Requirements: 968 | * 969 | * - `tokenId` must not exist. 970 | * - `to` cannot be the zero address. 971 | * 972 | * Emits a {Transfer} event. 973 | */ 974 | function _mint(address to, uint256 tokenId) internal virtual { 975 | require(to != address(0), "ERC721: mint to the zero address"); 976 | require(!_exists(tokenId), "ERC721: token already minted"); 977 | 978 | _beforeTokenTransfer(address(0), to, tokenId); 979 | 980 | _balances[to] += 1; 981 | _owners[tokenId] = to; 982 | 983 | emit Transfer(address(0), to, tokenId); 984 | } 985 | 986 | /** 987 | * @dev Destroys `tokenId`. 988 | * The approval is cleared when the token is burned. 989 | * 990 | * Requirements: 991 | * 992 | * - `tokenId` must exist. 993 | * 994 | * Emits a {Transfer} event. 995 | */ 996 | function _burn(uint256 tokenId) internal virtual { 997 | address owner = ERC721.ownerOf(tokenId); 998 | 999 | _beforeTokenTransfer(owner, address(0), tokenId); 1000 | 1001 | // Clear approvals 1002 | _approve(address(0), tokenId); 1003 | 1004 | _balances[owner] -= 1; 1005 | delete _owners[tokenId]; 1006 | 1007 | emit Transfer(owner, address(0), tokenId); 1008 | } 1009 | 1010 | /** 1011 | * @dev Transfers `tokenId` from `from` to `to`. 1012 | * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. 1013 | * 1014 | * Requirements: 1015 | * 1016 | * - `to` cannot be the zero address. 1017 | * - `tokenId` token must be owned by `from`. 1018 | * 1019 | * Emits a {Transfer} event. 1020 | */ 1021 | function _transfer( 1022 | address from, 1023 | address to, 1024 | uint256 tokenId 1025 | ) internal virtual { 1026 | require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); 1027 | require(to != address(0), "ERC721: transfer to the zero address"); 1028 | 1029 | _beforeTokenTransfer(from, to, tokenId); 1030 | 1031 | // Clear approvals from the previous owner 1032 | _approve(address(0), tokenId); 1033 | 1034 | _balances[from] -= 1; 1035 | _balances[to] += 1; 1036 | _owners[tokenId] = to; 1037 | 1038 | emit Transfer(from, to, tokenId); 1039 | } 1040 | 1041 | /** 1042 | * @dev Approve `to` to operate on `tokenId` 1043 | * 1044 | * Emits a {Approval} event. 1045 | */ 1046 | function _approve(address to, uint256 tokenId) internal virtual { 1047 | _tokenApprovals[tokenId] = to; 1048 | emit Approval(ERC721.ownerOf(tokenId), to, tokenId); 1049 | } 1050 | 1051 | /** 1052 | * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. 1053 | * The call is not executed if the target address is not a contract. 1054 | * 1055 | * @param from address representing the previous owner of the given token ID 1056 | * @param to target address that will receive the tokens 1057 | * @param tokenId uint256 ID of the token to be transferred 1058 | * @param _data bytes optional data to send along with the call 1059 | * @return bool whether the call correctly returned the expected magic value 1060 | */ 1061 | function _checkOnERC721Received( 1062 | address from, 1063 | address to, 1064 | uint256 tokenId, 1065 | bytes memory _data 1066 | ) private returns (bool) { 1067 | if (to.isContract()) { 1068 | try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { 1069 | return retval == IERC721Receiver(to).onERC721Received.selector; 1070 | } catch (bytes memory reason) { 1071 | if (reason.length == 0) { 1072 | revert("ERC721: transfer to non ERC721Receiver implementer"); 1073 | } else { 1074 | assembly { 1075 | revert(add(32, reason), mload(reason)) 1076 | } 1077 | } 1078 | } 1079 | } else { 1080 | return true; 1081 | } 1082 | } 1083 | 1084 | /** 1085 | * @dev Hook that is called before any token transfer. This includes minting 1086 | * and burning. 1087 | * 1088 | * Calling conditions: 1089 | * 1090 | * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be 1091 | * transferred to `to`. 1092 | * - When `from` is zero, `tokenId` will be minted for `to`. 1093 | * - When `to` is zero, ``from``'s `tokenId` will be burned. 1094 | * - `from` and `to` are never both zero. 1095 | * 1096 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 1097 | */ 1098 | function _beforeTokenTransfer( 1099 | address from, 1100 | address to, 1101 | uint256 tokenId 1102 | ) internal virtual {} 1103 | } 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | /** 1112 | * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension 1113 | * @dev See https://eips.ethereum.org/EIPS/eip-721 1114 | */ 1115 | interface IERC721Enumerable is IERC721 { 1116 | /** 1117 | * @dev Returns the total amount of tokens stored by the contract. 1118 | */ 1119 | function totalSupply() external view returns (uint256); 1120 | 1121 | /** 1122 | * @dev Returns a token ID owned by `owner` at a given `index` of its token list. 1123 | * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. 1124 | */ 1125 | function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); 1126 | 1127 | /** 1128 | * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. 1129 | * Use along with {totalSupply} to enumerate all tokens. 1130 | */ 1131 | function tokenByIndex(uint256 index) external view returns (uint256); 1132 | } 1133 | 1134 | 1135 | /** 1136 | * @dev This implements an optional extension of {ERC721} defined in the EIP that adds 1137 | * enumerability of all the token ids in the contract as well as all token ids owned by each 1138 | * account. 1139 | */ 1140 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { 1141 | // Mapping from owner to list of owned token IDs 1142 | mapping(address => mapping(uint256 => uint256)) private _ownedTokens; 1143 | 1144 | // Mapping from token ID to index of the owner tokens list 1145 | mapping(uint256 => uint256) private _ownedTokensIndex; 1146 | 1147 | // Array with all token ids, used for enumeration 1148 | uint256[] private _allTokens; 1149 | 1150 | // Mapping from token id to position in the allTokens array 1151 | mapping(uint256 => uint256) private _allTokensIndex; 1152 | 1153 | /** 1154 | * @dev See {IERC165-supportsInterface}. 1155 | */ 1156 | function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { 1157 | return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); 1158 | } 1159 | 1160 | /** 1161 | * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. 1162 | */ 1163 | function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { 1164 | require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); 1165 | return _ownedTokens[owner][index]; 1166 | } 1167 | 1168 | /** 1169 | * @dev See {IERC721Enumerable-totalSupply}. 1170 | */ 1171 | function totalSupply() public view virtual override returns (uint256) { 1172 | return _allTokens.length; 1173 | } 1174 | 1175 | /** 1176 | * @dev See {IERC721Enumerable-tokenByIndex}. 1177 | */ 1178 | function tokenByIndex(uint256 index) public view virtual override returns (uint256) { 1179 | require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); 1180 | return _allTokens[index]; 1181 | } 1182 | 1183 | /** 1184 | * @dev Hook that is called before any token transfer. This includes minting 1185 | * and burning. 1186 | * 1187 | * Calling conditions: 1188 | * 1189 | * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be 1190 | * transferred to `to`. 1191 | * - When `from` is zero, `tokenId` will be minted for `to`. 1192 | * - When `to` is zero, ``from``'s `tokenId` will be burned. 1193 | * - `from` cannot be the zero address. 1194 | * - `to` cannot be the zero address. 1195 | * 1196 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 1197 | */ 1198 | function _beforeTokenTransfer( 1199 | address from, 1200 | address to, 1201 | uint256 tokenId 1202 | ) internal virtual override { 1203 | super._beforeTokenTransfer(from, to, tokenId); 1204 | 1205 | if (from == address(0)) { 1206 | _addTokenToAllTokensEnumeration(tokenId); 1207 | } else if (from != to) { 1208 | _removeTokenFromOwnerEnumeration(from, tokenId); 1209 | } 1210 | if (to == address(0)) { 1211 | _removeTokenFromAllTokensEnumeration(tokenId); 1212 | } else if (to != from) { 1213 | _addTokenToOwnerEnumeration(to, tokenId); 1214 | } 1215 | } 1216 | 1217 | /** 1218 | * @dev Private function to add a token to this extension's ownership-tracking data structures. 1219 | * @param to address representing the new owner of the given token ID 1220 | * @param tokenId uint256 ID of the token to be added to the tokens list of the given address 1221 | */ 1222 | function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { 1223 | uint256 length = ERC721.balanceOf(to); 1224 | _ownedTokens[to][length] = tokenId; 1225 | _ownedTokensIndex[tokenId] = length; 1226 | } 1227 | 1228 | /** 1229 | * @dev Private function to add a token to this extension's token tracking data structures. 1230 | * @param tokenId uint256 ID of the token to be added to the tokens list 1231 | */ 1232 | function _addTokenToAllTokensEnumeration(uint256 tokenId) private { 1233 | _allTokensIndex[tokenId] = _allTokens.length; 1234 | _allTokens.push(tokenId); 1235 | } 1236 | 1237 | /** 1238 | * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that 1239 | * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for 1240 | * gas optimizations e.g. when performing a transfer operation (avoiding double writes). 1241 | * This has O(1) time complexity, but alters the order of the _ownedTokens array. 1242 | * @param from address representing the previous owner of the given token ID 1243 | * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address 1244 | */ 1245 | function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { 1246 | // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and 1247 | // then delete the last slot (swap and pop). 1248 | 1249 | uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; 1250 | uint256 tokenIndex = _ownedTokensIndex[tokenId]; 1251 | 1252 | // When the token to delete is the last token, the swap operation is unnecessary 1253 | if (tokenIndex != lastTokenIndex) { 1254 | uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; 1255 | 1256 | _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token 1257 | _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index 1258 | } 1259 | 1260 | // This also deletes the contents at the last position of the array 1261 | delete _ownedTokensIndex[tokenId]; 1262 | delete _ownedTokens[from][lastTokenIndex]; 1263 | } 1264 | 1265 | /** 1266 | * @dev Private function to remove a token from this extension's token tracking data structures. 1267 | * This has O(1) time complexity, but alters the order of the _allTokens array. 1268 | * @param tokenId uint256 ID of the token to be removed from the tokens list 1269 | */ 1270 | function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { 1271 | // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and 1272 | // then delete the last slot (swap and pop). 1273 | 1274 | uint256 lastTokenIndex = _allTokens.length - 1; 1275 | uint256 tokenIndex = _allTokensIndex[tokenId]; 1276 | 1277 | // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so 1278 | // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding 1279 | // an 'if' statement (like in _removeTokenFromOwnerEnumeration) 1280 | uint256 lastTokenId = _allTokens[lastTokenIndex]; 1281 | 1282 | _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token 1283 | _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index 1284 | 1285 | // This also deletes the contents at the last position of the array 1286 | delete _allTokensIndex[tokenId]; 1287 | _allTokens.pop(); 1288 | } 1289 | } 1290 | 1291 | 1292 | contract Dev is ERC721Enumerable, ReentrancyGuard, Ownable { 1293 | 1294 | string[] private osses = [ 1295 | "Kali Linux", 1296 | "Ubuntu", 1297 | "Windows 1.0", 1298 | "Android Marshmallow", 1299 | "Windows 95", 1300 | "FreeBSD", 1301 | "Slackware Linux", 1302 | "Chromium OS", 1303 | "Windows Vista", 1304 | "Google Chrome OS", 1305 | "macOS", 1306 | "DOS", 1307 | "Linux Mint", 1308 | "GM-NAA I/O" 1309 | ]; 1310 | 1311 | string[] private texteditors = [ 1312 | "VS Code", 1313 | "Brackets", 1314 | "VIM", 1315 | "Emacs", 1316 | "Brackets", 1317 | "Atom", 1318 | "Notepad++", 1319 | "Pen and Paper", 1320 | "Visual Studio", 1321 | "Sand and Stick", 1322 | "Mental Telepathy", 1323 | "Bluefish", 1324 | "Sublime Text", 1325 | "Dreamweaver", 1326 | "Coda" 1327 | ]; 1328 | 1329 | string[] private clothing = [ 1330 | "Black Hoodie", 1331 | "White Tanktop", 1332 | "Patagonia Vest", 1333 | "Conference T", 1334 | "Blacked Out", 1335 | "Bulls Jersey", 1336 | "Pink Hoodie", 1337 | "Purple Turtleneck", 1338 | "Bra", 1339 | "Navy Suit", 1340 | "Purple Dress", 1341 | "Platinum Trenchcoat", 1342 | "Bubble Gum Wrapper", 1343 | "Sweat" 1344 | ]; 1345 | 1346 | string[] private languages = [ 1347 | "TypeScript", 1348 | "JavaScript", 1349 | "Python", 1350 | "Fortran", 1351 | "COBOL", 1352 | "Go", 1353 | "Rust", 1354 | "Swift", 1355 | "PHP", 1356 | "Haskell", 1357 | "Scala", 1358 | "Dart", 1359 | "Java", 1360 | "Julia", 1361 | "C", 1362 | "Kotlin", 1363 | "Velato", 1364 | "ArnoldC", 1365 | "Shakespeare", 1366 | "Piet", 1367 | "Brainfuck", 1368 | "Chicken", 1369 | "Legit", 1370 | "Whitespace" 1371 | ]; 1372 | 1373 | string[] private industries = [ 1374 | "Government", 1375 | "Black Hat", 1376 | "White Hat", 1377 | "Nonprofit", 1378 | "Money Laundering", 1379 | "Crypto", 1380 | "FAANG", 1381 | "AI Startup", 1382 | "VR", 1383 | "Traveling Consultant", 1384 | "Undercover", 1385 | "Farming", 1386 | "Environmental", 1387 | "Hollywood", 1388 | "Influencer" 1389 | ]; 1390 | 1391 | string[] private locations = [ 1392 | "Bucharest", 1393 | "Hong Kong", 1394 | "Jackson", 1395 | "Budapest", 1396 | "Sao Paulo", 1397 | "Lagos", 1398 | "Omaha", 1399 | "Gold Coast", 1400 | "Paris", 1401 | "Tokyo", 1402 | "Shenzhen", 1403 | "Saint Petersburg", 1404 | "Buenos Aires", 1405 | "Kisumu", 1406 | "Ramallah", 1407 | "Goa", 1408 | "London", 1409 | "Pyongyang" 1410 | ]; 1411 | 1412 | string[] private minds = [ 1413 | "Abstract", 1414 | "Analytical", 1415 | "Creative", 1416 | "Concrete", 1417 | "Critical", 1418 | "Convergent", 1419 | "Divergent", 1420 | "Anarchist" 1421 | ]; 1422 | 1423 | string[] private vibes = [ 1424 | "Optimist", 1425 | "Cosmic", 1426 | "Chill", 1427 | "Hyper", 1428 | "Kind", 1429 | "Hater", 1430 | "Phobia", 1431 | "Generous", 1432 | "JonGold" 1433 | ]; 1434 | 1435 | function random(string memory input) internal pure returns (uint256) { 1436 | return uint256(keccak256(abi.encodePacked(input))); 1437 | } 1438 | 1439 | function getOS(uint256 tokenId) public view returns (string memory) { 1440 | return pluck(tokenId, "OS", osses); 1441 | } 1442 | 1443 | function getTextEditor(uint256 tokenId) public view returns (string memory) { 1444 | return pluck(tokenId, "TEXTEDITOR", texteditors); 1445 | } 1446 | 1447 | function getClothing(uint256 tokenId) public view returns (string memory) { 1448 | return pluck(tokenId, "CLOTHING", clothing); 1449 | } 1450 | 1451 | function getLanguage(uint256 tokenId) public view returns (string memory) { 1452 | return pluck(tokenId, "LANGUAGE", languages); 1453 | } 1454 | 1455 | function getIndustry(uint256 tokenId) public view returns (string memory) { 1456 | return pluck(tokenId, "INDUSTRY", industries); 1457 | } 1458 | 1459 | function getLocation(uint256 tokenId) public view returns (string memory) { 1460 | return pluck(tokenId, "LOCATION", locations); 1461 | } 1462 | 1463 | function getMind(uint256 tokenId) public view returns (string memory) { 1464 | return pluck(tokenId, "MIND", minds); 1465 | } 1466 | 1467 | function getVibe(uint256 tokenId) public view returns (string memory) { 1468 | return pluck(tokenId, "VIBE", vibes); 1469 | } 1470 | 1471 | function pluck(uint256 tokenId, string memory keyPrefix, string[] memory sourceArray) internal pure returns (string memory) { 1472 | uint256 rand = random(string(abi.encodePacked(keyPrefix, toString(tokenId)))); 1473 | string memory output = sourceArray[rand % sourceArray.length]; 1474 | return output; 1475 | } 1476 | 1477 | function tokenURI(uint256 tokenId) override public view returns (string memory) { 1478 | string[19] memory parts; 1479 | parts[0] = ''; 1480 | 1481 | parts[1] = getOS(tokenId); 1482 | 1483 | parts[2] = ''; 1484 | 1485 | parts[3] = getTextEditor(tokenId); 1486 | 1487 | parts[4] = ''; 1488 | 1489 | parts[5] = getClothing(tokenId); 1490 | 1491 | parts[6] = ''; 1492 | 1493 | parts[7] = getLanguage(tokenId); 1494 | 1495 | parts[8] = ''; 1496 | 1497 | parts[9] = getIndustry(tokenId); 1498 | 1499 | parts[10] = ''; 1500 | 1501 | parts[11] = getLocation(tokenId); 1502 | 1503 | parts[14] = ''; 1504 | 1505 | parts[15] = getMind(tokenId); 1506 | 1507 | parts[16] = ''; 1508 | 1509 | parts[17] = getVibe(tokenId); 1510 | 1511 | parts[18] = ''; 1512 | 1513 | string memory output = string(abi.encodePacked(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8])); 1514 | output = string(abi.encodePacked(output, parts[9], parts[10], parts[11], parts[12], parts[13], parts[14], parts[15], parts[16], parts[17], parts[18])); 1515 | 1516 | string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Dev #', toString(tokenId), '", "description": "Developers around the world are tired of working and contributing their time and effort to enrich the top 1%. Join the movement that is community owned, building the future from the bottom up.", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}')))); 1517 | output = string(abi.encodePacked('data:application/json;base64,', json)); 1518 | 1519 | return output; 1520 | } 1521 | 1522 | function claim(uint256 tokenId) public nonReentrant { 1523 | require(tokenId > 0 && tokenId < 7778, "Token ID invalid"); 1524 | _safeMint(_msgSender(), tokenId); 1525 | } 1526 | 1527 | function ownerClaim(uint256 tokenId) public nonReentrant onlyOwner { 1528 | require(tokenId > 7777 && tokenId < 8001, "Token ID invalid"); 1529 | _safeMint(owner(), tokenId); 1530 | } 1531 | 1532 | function toString(uint256 value) internal pure returns (string memory) { 1533 | // Inspired by OraclizeAPI's implementation - MIT license 1534 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 1535 | 1536 | if (value == 0) { 1537 | return "0"; 1538 | } 1539 | uint256 temp = value; 1540 | uint256 digits; 1541 | while (temp != 0) { 1542 | digits++; 1543 | temp /= 10; 1544 | } 1545 | bytes memory buffer = new bytes(digits); 1546 | while (value != 0) { 1547 | digits -= 1; 1548 | buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); 1549 | value /= 10; 1550 | } 1551 | return string(buffer); 1552 | } 1553 | 1554 | constructor() ERC721("Devs for Revolution", "DEVS") Ownable() {} 1555 | } 1556 | 1557 | /// [MIT License] 1558 | /// @title Base64 1559 | /// @notice Provides a function for encoding some bytes in base64 1560 | /// @author Brecht Devos 1561 | library Base64 { 1562 | bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 1563 | 1564 | /// @notice Encodes some bytes to the base64 representation 1565 | function encode(bytes memory data) internal pure returns (string memory) { 1566 | uint256 len = data.length; 1567 | if (len == 0) return ""; 1568 | 1569 | // multiply by 4/3 rounded up 1570 | uint256 encodedLen = 4 * ((len + 2) / 3); 1571 | 1572 | // Add some extra buffer at the end 1573 | bytes memory result = new bytes(encodedLen + 32); 1574 | 1575 | bytes memory table = TABLE; 1576 | 1577 | assembly { 1578 | let tablePtr := add(table, 1) 1579 | let resultPtr := add(result, 32) 1580 | 1581 | for { 1582 | let i := 0 1583 | } lt(i, len) { 1584 | 1585 | } { 1586 | i := add(i, 3) 1587 | let input := and(mload(add(data, i)), 0xffffff) 1588 | 1589 | let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) 1590 | out := shl(8, out) 1591 | out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)) 1592 | out := shl(8, out) 1593 | out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)) 1594 | out := shl(8, out) 1595 | out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)) 1596 | out := shl(224, out) 1597 | 1598 | mstore(resultPtr, out) 1599 | 1600 | resultPtr := add(resultPtr, 4) 1601 | } 1602 | 1603 | switch mod(len, 3) 1604 | case 1 { 1605 | mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) 1606 | } 1607 | case 2 { 1608 | mstore(sub(resultPtr, 1), shl(248, 0x3d)) 1609 | } 1610 | 1611 | mstore(result, encodedLen) 1612 | } 1613 | 1614 | return string(result); 1615 | } 1616 | } -------------------------------------------------------------------------------- /hh/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | // This is a sample Hardhat task. To learn how to create your own go to 4 | // https://hardhat.org/guides/create-task.html 5 | task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { 6 | const accounts = await hre.ethers.getSigners(); 7 | for (const account of accounts) { 8 | console.log(account.address); 9 | } 10 | }); 11 | 12 | // You need to export an object to set up your config 13 | // Go to https://hardhat.org/config/ to learn more 14 | 15 | const pk = process.env.dapk 16 | 17 | module.exports = { 18 | solidity: "0.8.4", 19 | networks: { 20 | hardhat: {}, 21 | rinkeby: { 22 | url: "https://rinkeby.infura.io/v3/7228b494adf94a63bab07ea737183033", 23 | accounts: [`0x${pk}`] 24 | }, 25 | mainnet: { 26 | url: "https://mainnet.infura.io/v3/7228b494adf94a63bab07ea737183033", 27 | accounts: [`0x${pk}`] 28 | } 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /hh/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hh", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@nomiclabs/hardhat-ethers": "^2.0.2", 14 | "@nomiclabs/hardhat-waffle": "^2.0.1", 15 | "chai": "^4.3.4", 16 | "ethereum-waffle": "^3.4.0", 17 | "ethers": "^5.4.6", 18 | "hardhat": "^2.6.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /hh/scripts/deploy.js: -------------------------------------------------------------------------------- 1 | // We require the Hardhat Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node