Skip to content

Instantly share code, notes, and snippets.

@lukebyrne
Created October 13, 2021 08:10
Show Gist options
  • Save lukebyrne/f4806f52268eb8eeb5f3229a7453b7e2 to your computer and use it in GitHub Desktop.
Save lukebyrne/f4806f52268eb8eeb5f3229a7453b7e2 to your computer and use it in GitHub Desktop.
// 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