Created
October 13, 2021 08:10
-
-
Save lukebyrne/f4806f52268eb8eeb5f3229a7453b7e2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.7; | |
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol"; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
import "@openzeppelin/contracts/utils/Counters.sol"; | |
contract Foo is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable, ChainlinkClient { | |
using Chainlink for Chainlink.Request; | |
bytes32 private constant UUID = ""; | |
bytes32 public uuid; | |
address private oracle; | |
bytes32 private jobId; | |
uint256 private fee; | |
event RequestUUIDFulfilled( | |
bytes32 indexed requestId, | |
bytes32 indexed uuid | |
); | |
using Counters for Counters.Counter; | |
Counters.Counter private _tokenIdCounter; | |
uint public constant MAX_SUPPLY = 1000; | |
constructor(address _oracle, string memory _jobId, uint256 _fee, address _link) ERC721("FOO", "FOO") public { | |
if (_link == address(0)) { | |
setPublicChainlinkToken(); | |
} else { | |
setChainlinkToken(_link); | |
} | |
oracle = _oracle; | |
jobId = stringToBytes32(_jobId); | |
fee = _fee; | |
} | |
/** | |
* CHAINLINK START | |
*/ | |
function _requestUUID(string memory _path) public returns (bytes32 requestId) { | |
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this._fulfillUUID.selector); | |
request.add("get", _mappingsURI()); | |
request.add("path", _path); | |
// Sends the request | |
return sendChainlinkRequestTo(oracle, request, fee); | |
} | |
function _fulfillUUID(bytes32 _requestId, bytes32 _uuid) public recordChainlinkFulfillment(_requestId) { | |
emit RequestUUIDFulfilled(_requestId, _uuid); | |
uuid = _uuid; | |
} | |
/** | |
* CHAINLINK START | |
*/ | |
/** | |
* ERC721 START | |
*/ | |
function _baseURI() internal pure override returns (string memory) { | |
return "https://example.com/"; | |
} | |
function _mappingsURI() public returns (string memory) { | |
return string(abi.encodePacked(_baseURI(), "uuids.json")); | |
} | |
function _setUUID(string memory _path) private { | |
_requestUUID(_path); | |
require( | |
uuid != UUID, | |
"ERC721: _path not found in mappings.json" | |
); | |
} | |
function safeMint(string memory _path) public { | |
_setUUID(_path); | |
} | |
function _approvedForToken(uint256 tokenId) private { | |
require( | |
_isApprovedOrOwner(_msgSender(), tokenId), | |
"ERC721: transfer caller is not owner nor approved" | |
); | |
} | |
function safeBurn(uint256 tokenId) public { | |
_approvedForToken(tokenId); | |
_burn(tokenId); | |
} | |
// The following functions are overrides required by Solidity. | |
function _beforeTokenTransfer(address from, address to, uint256 tokenId) | |
internal | |
override(ERC721, ERC721Enumerable) | |
{ | |
super._beforeTokenTransfer(from, to, tokenId); | |
} | |
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { | |
super._burn(tokenId); | |
} | |
function tokenURI(uint256 tokenId) | |
public | |
view | |
override(ERC721, ERC721URIStorage) | |
returns (string memory) | |
{ | |
return super.tokenURI(tokenId); | |
} | |
function supportsInterface(bytes4 interfaceId) | |
public | |
view | |
override(ERC721, ERC721Enumerable) | |
returns (bool) | |
{ | |
return super.supportsInterface(interfaceId); | |
} | |
/** | |
* ERC721 END | |
*/ | |
/** | |
* UTILS START | |
*/ | |
function stringToBytes32(string memory source) public pure returns (bytes32 result) { | |
bytes memory tempEmptyStringTest = bytes(source); | |
if (tempEmptyStringTest.length == 0) { | |
return 0x0; | |
} | |
assembly { | |
result := mload(add(source, 32)) | |
} | |
} | |
function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) { | |
uint8 i = 0; | |
while(i < 32 && _bytes32[i] != 0) { | |
i++; | |
} | |
bytes memory bytesArray = new bytes(i); | |
for (i = 0; i < 32 && _bytes32[i] != 0; i++) { | |
bytesArray[i] = _bytes32[i]; | |
} | |
return string(bytesArray); | |
} | |
function withdrawLink() public onlyOwner { | |
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress()); | |
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer"); | |
} | |
/** | |
* UTILS END | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment