Contracts
Returns the contract Application Binary Interface ( ABI ) of a verified smart contract.
https://api-testnet.polygonscan.com/api
?module=contract
&action=getabi
&address=0xD08E331Ba5Da695d8FB298231868D039Ba3211D6
&apikey=YourApiKeyToken
Request
Response
Query Parameters
Parameter | Description |
---|---|
address | the contract address that has a verified source code |
Sample Response
{
"status":"1",
"message":"OK",
"result":"[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTreeLevel\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"friend\",\"type\":\"address\"}],\"name\":\"gift\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"level\",\"type\":\"uint256\"}],\"name\":\"levelXml\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxViewLevel\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"plant\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"price\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxViewLevel\",\"type\":\"uint256\"}],\"name\":\"setMaxViewLevel\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newPrice\",\"type\":\"uint256\"}],\"name\":\"setPrice\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenByIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"tokenOfOwnerByIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treeCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wEthAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"withdrawToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
}
A simple sample for retrieving the contractABI using Web3.js and Jquery to interact with a contract.
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider());
var version = web3.version.api;
$.getJSON('https://api-testnet.polygonscan.com/api?module=contract&action=getabi&address=0x0000000000000000000000000000000000001004&apikey=YourApiKeyToken', function (data) {
var contractABI = "";
contractABI = JSON.parse(data.result);
if (contractABI != '') {
var MyContract = web3.eth.contract(contractABI);
var myContractInstance = MyContract.at("0x0000000000000000000000000000000000001004");
var result = myContractInstance.memberId("0xfe8ad7dd2f564a877cc23feea6c0a9cc2e783715");
console.log("result1 : " + result);
var result = myContractInstance.members(1);
console.log("result2 : " + result);
} else {
console.log("Error");
}
});
Returns the Solidity source code of a verified smart contract.
Tip : You can also download a CSV list of Verified Contract Addresses of which the code publishers have provided a corresponding Open Source license for redistribution.
📩
https://api-testnet.polygonscan.com/api
?module=contract
&action=getsourcecode
&address=0x2A18cE70E697fF39B8Ce8E9eC19b5E6c0688C843
&apikey=YourApiKeyToken
Request
Response
Query Parameters
Parameter | Description |
---|---|
address | the contract address that has a verified source code |
Sample Response
{
"status":"1",
"message":"OK",
"result":[
{
"SourceCode":"{{\r\n \"language\": \"Solidity\",\r\n \"sources\": {\r\n \"contracts/polygon/raffle/Raffle.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"@chainlink/contracts/src/v0.8/VRFConsumerBase.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.\\n * PLEASE DO NOT USE THIS CODE IN PRODUCTION.\\n */\\ncontract Raffle is VRFConsumerBase, Ownable {\\n using SafeERC20 for IERC20;\\n\\n struct RaffleInfo {\\n uint32 total;\\n uint32 n;\\n string filePath;\\n }\\n\\n bytes32 internal keyHash;\\n uint256 internal fee;\\n\\n uint32 public nextRaffleId;\\n\\n bytes32 public lastRequestId;\\n\\n mapping(address => bool) public approvedOperators;\\n\\n mapping(bytes32 => uint32) public requestIdToRaffleId;\\n\\n mapping(uint32 => uint256) public raffleIdToRandomness;\\n\\n // position => value\\n mapping(uint32 => uint32) private randomMatrix;\\n\\n mapping(uint32 => RaffleInfo) public raffleInfos;\\n\\n event RaffleResult(uint32 indexed raffleId, uint32 total, uint32 n, string filePath, uint32[] result);\\n event RandomnessFulfilled(uint32 indexed raffleId, uint256 randomness);\\n\\n modifier onlyOperator() {\\n require(owner() == _msgSender() || approvedOperators[_msgSender()], \\\"not operator\\\");\\n _;\\n }\\n\\n /**\\n * Constructor inherits VRFConsumerBase\\n */\\n constructor(\\n address _vrfCoordinator,\\n address _link,\\n bytes32 _keyHash,\\n uint256 _fee\\n )\\n VRFConsumerBase(\\n _vrfCoordinator, // VRF Coordinator\\n _link // LINK Token\\n )\\n {\\n keyHash = _keyHash;\\n fee = _fee;\\n nextRaffleId = 1;\\n }\\n\\n /**\\n * Requests randomness for raffle\\n */\\n function startRaffle(\\n uint32 _total,\\n uint32 _n,\\n string calldata _filePath\\n ) public onlyOperator returns (uint32 raffleId) {\\n require(LINK.balanceOf(address(this)) >= fee, \\\"Not enough LINK\\\");\\n lastRequestId = requestRandomness(keyHash, fee);\\n raffleId = _getAndIncreaseRaffleId();\\n requestIdToRaffleId[lastRequestId] = raffleId;\\n RaffleInfo storage info = raffleInfos[raffleId];\\n info.total = _total;\\n info.n = _n;\\n info.filePath = _filePath;\\n }\\n\\n /**\\n * Callback function used by VRF Coordinator\\n */\\n function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {\\n uint32 raffleId = requestIdToRaffleId[requestId];\\n require(raffleId > 0, \\\"no raffleId for this requestId\\\");\\n raffleIdToRandomness[raffleId] = randomness;\\n emit RandomnessFulfilled(raffleId, randomness);\\n }\\n\\n /**\\n * @notice if total is larger than 30,000, this function is more gas efficient.\\n * check RaffleResult event of raffleId first, do not calculate twice\\n */\\n function calculateRaffleResultForLargeTotal(uint32 raffleId) public {\\n require(raffleIdToRandomness[raffleId] > 0, \\\"randomness not fulfilled\\\");\\n _doRaffleWithStorageMatrix(raffleId);\\n }\\n\\n /**\\n * @notice if total is less than 30,000, this function is more gas efficient.\\n * check RaffleResult event of raffleId first, do not calculate twice\\n */\\n function calculateRaffleResultForSmallTotal(uint32 raffleId) public {\\n require(raffleIdToRandomness[raffleId] > 0, \\\"randomness not fulfilled\\\");\\n _doRaffleWithMemoryMatrix(raffleId);\\n }\\n\\n function _doRaffleWithStorageMatrix(uint32 raffleId) internal {\\n RaffleInfo storage info = raffleInfos[raffleId];\\n uint32 total = info.total;\\n uint32 n = info.n;\\n uint256 randomness = raffleIdToRandomness[raffleId];\\n uint32[] memory res = new uint32[](n);\\n // a variety of Fisher-Yates Shuffle: https://bost.ocks.org/mike/shuffle/\\n // imagine we have a array of *total* numbers, from 0 to *total - 1*.\\n // initially, each index and it's value are the same, meaning index 0 is 0, index 1 is 1, and so on.\\n // each shuffle iteration swaps a random number with the tail of the array, changing one of the mapping relationship of index to value.\\n // randomMatrix is a mapping to record the relationship of index to value.\\n for (uint32 i = 0; i < n; i++) {\\n // 1. maxIndex shrinks every iteration,\\n uint32 maxIndex = total - i - 1;\\n // 2. get a random index in the range of [0, maxIndex]\\n uint32 randomIndex = uint32(uint256(keccak256(abi.encode(randomness, i)))) % (maxIndex + 1);\\n\\n // the random value we need at the randomIndex\\n uint32 pick = randomMatrix[randomIndex];\\n // check if the random index is selected before\\n if (pick == 0) {\\n // 3. if the random index is not selected, the value at this position is the same as the position index itself\\n pick = randomIndex;\\n }\\n // 4. swap the value at randomIndex with the value at tail of the shrunk array.\\n // if maxIndex is selected before, use the value at maxIndex's position.\\n uint32 tailValue = randomMatrix[maxIndex];\\n // if maxIndex is not selected, the value is maxIndex it self\\n if (tailValue == 0) {\\n tailValue = maxIndex;\\n }\\n // because we record the random value in res, we do not care about the tail of the array.\\n // so only move the tail to randomIndex, not need to move the pick value to tail.\\n randomMatrix[randomIndex] = tailValue;\\n // use readable index rather than array index, thus + 1;\\n res[i] = pick + 1;\\n }\\n\\n // clear the matrix\\n for (uint32 i = 0; i < n; i++) {\\n delete randomMatrix[res[i] - 1];\\n }\\n emit RaffleResult(raffleId, total, n, info.filePath, res);\\n }\\n\\n function _doRaffleWithMemoryMatrix(uint32 raffleId) internal {\\n RaffleInfo storage info = raffleInfos[raffleId];\\n uint32 total = info.total;\\n uint32 n = info.n;\\n uint256 randomness = raffleIdToRandomness[raffleId];\\n uint32[] memory res = new uint32[](n);\\n uint32[] memory memoryMatrix = new uint32[](total);\\n\\n // a variety of Fisher-Yates Shuffle: https://bost.ocks.org/mike/shuffle/\\n // imagine we have a array of *total* numbers, from 0 to *total - 1*.\\n // initially, each index and it's value are the same, meaning index 0 is 0, index 1 is 1, and so on.\\n // each shuffle iteration swaps a random number with the tail of the array, changing one of the mapping relationship of index to value.\\n // memoryMatrix is an array to record the relationship of index to value.\\n for (uint32 i = 0; i < n; i++) {\\n // 1. maxIndex shrinks every iteration,\\n uint32 maxIndex = total - i - 1;\\n // 2. get a random index in the range of [0, maxIndex]\\n uint32 randomIndex = uint32(uint256(keccak256(abi.encode(randomness, i)))) % (maxIndex + 1);\\n\\n // the random value we need at the randomIndex\\n uint32 pick = memoryMatrix[randomIndex];\\n // check if the random index is selected before\\n if (pick == 0) {\\n // 3. if the random index is not selected, the value at this position is the same as the position index itself\\n pick = randomIndex;\\n }\\n // 4. swap the value at randomIndex with the value at tail of the shrunk array.\\n // if maxIndex is selected before, use the value at maxIndex's position.\\n uint32 tailValue = memoryMatrix[maxIndex];\\n // if maxIndex is not selected, the value is maxIndex it self\\n if (tailValue == 0) {\\n tailValue = maxIndex;\\n }\\n // because we record the random value in res, we do not care about the tail of the array.\\n // so only move the tail to randomIndex, not need to move the pick value to tail.\\n memoryMatrix[randomIndex] = tailValue;\\n // use readable index rather than array index, thus + 1;\\n res[i] = pick + 1;\\n }\\n\\n emit RaffleResult(raffleId, total, n, info.filePath, res);\\n }\\n\\n // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract\\n /**\\n * @notice It allows the admin to withdraw tokens sent to the contract\\n * @param _tokenAddress: the address of the token to withdraw\\n * @param _tokenAmount: the number of token amount to withdraw\\n * @dev Only callable by owner.\\n */\\n function withdrawTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner {\\n IERC20(_tokenAddress).safeTransfer(address(msg.sender), _tokenAmount);\\n }\\n\\n /**\\n * @notice Change the fee\\n * @param _fee: new fee (in LINK)\\n */\\n function setFee(uint256 _fee) external onlyOwner {\\n fee = _fee;\\n }\\n\\n function setOperators(address[] calldata operators, bool ok) external onlyOwner {\\n for (uint256 idx = 0; idx < operators.length; idx++) {\\n approvedOperators[operators[idx]] = ok;\\n }\\n }\\n\\n /**\\n * @notice Change the keyHash\\n * @param _keyHash: new keyHash\\n */\\n function setKeyHash(bytes32 _keyHash) external onlyOwner {\\n keyHash = _keyHash;\\n }\\n\\n function _getAndIncreaseRaffleId() internal returns (uint32) {\\n return nextRaffleId++;\\n }\\n}\\n\"\r\n },\r\n \"@chainlink/contracts/src/v0.8/VRFConsumerBase.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./interfaces/LinkTokenInterface.sol\\\";\\n\\nimport \\\"./VRFRequestIDBase.sol\\\";\\n\\n/** ****************************************************************************\\n * @notice Interface for contracts using VRF randomness\\n * *****************************************************************************\\n * @dev PURPOSE\\n *\\n * @dev Reggie the Random Oracle (not his real job) wants to provide randomness\\n * @dev to Vera the verifier in such a way that Vera can be sure he's not\\n * @dev making his output up to suit himself. Reggie provides Vera a public key\\n * @dev to which he knows the secret key. Each time Vera provides a seed to\\n * @dev Reggie, he gives back a value which is computed completely\\n * @dev deterministically from the seed and the secret key.\\n *\\n * @dev Reggie provides a proof by which Vera can verify that the output was\\n * @dev correctly computed once Reggie tells it to her, but without that proof,\\n * @dev the output is indistinguishable to her from a uniform random sample\\n * @dev from the output space.\\n *\\n * @dev The purpose of this contract is to make it easy for unrelated contracts\\n * @dev to talk to Vera the verifier about the work Reggie is doing, to provide\\n * @dev simple access to a verifiable source of randomness.\\n * *****************************************************************************\\n * @dev USAGE\\n *\\n * @dev Calling contracts must inherit from VRFConsumerBase, and can\\n * @dev initialize VRFConsumerBase's attributes in their constructor as\\n * @dev shown:\\n *\\n * @dev contract VRFConsumer {\\n * @dev constuctor(<other arguments>, address _vrfCoordinator, address _link)\\n * @dev VRFConsumerBase(_vrfCoordinator, _link) public {\\n * @dev <initialization with other arguments goes here>\\n * @dev }\\n * @dev }\\n *\\n * @dev The oracle will have given you an ID for the VRF keypair they have\\n * @dev committed to (let's call it keyHash), and have told you the minimum LINK\\n * @dev price for VRF service. Make sure your contract has sufficient LINK, and\\n * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you\\n * @dev want to generate randomness from.\\n *\\n * @dev Once the VRFCoordinator has received and validated the oracle's response\\n * @dev to your request, it will call your contract's fulfillRandomness method.\\n *\\n * @dev The randomness argument to fulfillRandomness is the actual random value\\n * @dev generated from your seed.\\n *\\n * @dev The requestId argument is generated from the keyHash and the seed by\\n * @dev makeRequestId(keyHash, seed). If your contract could have concurrent\\n * @dev requests open, you can use the requestId to track which seed is\\n * @dev associated with which randomness. See VRFRequestIDBase.sol for more\\n * @dev details. (See \\\"SECURITY CONSIDERATIONS\\\" for principles to keep in mind,\\n * @dev if your contract could have multiple requests in flight simultaneously.)\\n *\\n * @dev Colliding `requestId`s are cryptographically impossible as long as seeds\\n * @dev differ. (Which is critical to making unpredictable randomness! See the\\n * @dev next section.)\\n *\\n * *****************************************************************************\\n * @dev SECURITY CONSIDERATIONS\\n *\\n * @dev A method with the ability to call your fulfillRandomness method directly\\n * @dev could spoof a VRF response with any random value, so it's critical that\\n * @dev it cannot be directly called by anything other than this base contract\\n * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).\\n *\\n * @dev For your users to trust that your contract's random behavior is free\\n * @dev from malicious interference, it's best if you can write it so that all\\n * @dev behaviors implied by a VRF response are executed *during* your\\n * @dev fulfillRandomness method. If your contract must store the response (or\\n * @dev anything derived from it) and use it later, you must ensure that any\\n * @dev user-significant behavior which depends on that stored value cannot be\\n * @dev manipulated by a subsequent VRF request.\\n *\\n * @dev Similarly, both miners and the VRF oracle itself have some influence\\n * @dev over the order in which VRF responses appear on the blockchain, so if\\n * @dev your contract could have multiple VRF requests in flight simultaneously,\\n * @dev you must ensure that the order in which the VRF responses arrive cannot\\n * @dev be used to manipulate your contract's user-significant behavior.\\n *\\n * @dev Since the ultimate input to the VRF is mixed with the block hash of the\\n * @dev block in which the request is made, user-provided seeds have no impact\\n * @dev on its economic security properties. They are only included for API\\n * @dev compatability with previous versions of this contract.\\n *\\n * @dev Since the block hash of the block which contains the requestRandomness\\n * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful\\n * @dev miner could, in principle, fork the blockchain to evict the block\\n * @dev containing the request, forcing the request to be included in a\\n * @dev different block with a different hash, and therefore a different input\\n * @dev to the VRF. However, such an attack would incur a substantial economic\\n * @dev cost. This cost scales with the number of blocks the VRF oracle waits\\n * @dev until it calls responds to a request.\\n */\\nabstract contract VRFConsumerBase is VRFRequestIDBase {\\n\\n /**\\n * @notice fulfillRandomness handles the VRF response. Your contract must\\n * @notice implement it. See \\\"SECURITY CONSIDERATIONS\\\" above for important\\n * @notice principles to keep in mind when implementing your fulfillRandomness\\n * @notice method.\\n *\\n * @dev VRFConsumerBase expects its subcontracts to have a method with this\\n * @dev signature, and will call it once it has verified the proof\\n * @dev associated with the randomness. (It is triggered via a call to\\n * @dev rawFulfillRandomness, below.)\\n *\\n * @param requestId The Id initially returned by requestRandomness\\n * @param randomness the VRF output\\n */\\n function fulfillRandomness(\\n bytes32 requestId,\\n uint256 randomness\\n )\\n internal\\n virtual;\\n\\n /**\\n * @dev In order to keep backwards compatibility we have kept the user\\n * seed field around. We remove the use of it because given that the blockhash\\n * enters later, it overrides whatever randomness the used seed provides.\\n * Given that it adds no security, and can easily lead to misunderstandings,\\n * we have removed it from usage and can now provide a simpler API.\\n */\\n uint256 constant private USER_SEED_PLACEHOLDER = 0;\\n\\n /**\\n * @notice requestRandomness initiates a request for VRF output given _seed\\n *\\n * @dev The fulfillRandomness method receives the output, once it's provided\\n * @dev by the Oracle, and verified by the vrfCoordinator.\\n *\\n * @dev The _keyHash must already be registered with the VRFCoordinator, and\\n * @dev the _fee must exceed the fee specified during registration of the\\n * @dev _keyHash.\\n *\\n * @dev The _seed parameter is vestigial, and is kept only for API\\n * @dev compatibility with older versions. It can't *hurt* to mix in some of\\n * @dev your own randomness, here, but it's not necessary because the VRF\\n * @dev oracle will mix the hash of the block containing your request into the\\n * @dev VRF seed it ultimately uses.\\n *\\n * @param _keyHash ID of public key against which randomness is generated\\n * @param _fee The amount of LINK to send with the request\\n *\\n * @return requestId unique ID for this request\\n *\\n * @dev The returned requestId can be used to distinguish responses to\\n * @dev concurrent requests. It is passed as the first argument to\\n * @dev fulfillRandomness.\\n */\\n function requestRandomness(\\n bytes32 _keyHash,\\n uint256 _fee\\n )\\n internal\\n returns (\\n bytes32 requestId\\n )\\n {\\n LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));\\n // This is the seed passed to VRFCoordinator. The oracle will mix this with\\n // the hash of the block containing this request to obtain the seed/input\\n // which is finally passed to the VRF cryptographic machinery.\\n uint256 vRFSeed = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);\\n // nonces[_keyHash] must stay in sync with\\n // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above\\n // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).\\n // This provides protection against the user repeating their input seed,\\n // which would result in a predictable/duplicate output, if multiple such\\n // requests appeared in the same block.\\n nonces[_keyHash] = nonces[_keyHash] + 1;\\n return makeRequestId(_keyHash, vRFSeed);\\n }\\n\\n LinkTokenInterface immutable internal LINK;\\n address immutable private vrfCoordinator;\\n\\n // Nonces for each VRF key from which randomness has been requested.\\n //\\n // Must stay in sync with VRFCoordinator[_keyHash][this]\\n mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces;\\n\\n /**\\n * @param _vrfCoordinator address of VRFCoordinator contract\\n * @param _link address of LINK token contract\\n *\\n * @dev https://docs.chain.link/docs/link-token-contracts\\n */\\n constructor(\\n address _vrfCoordinator,\\n address _link\\n ) {\\n vrfCoordinator = _vrfCoordinator;\\n LINK = LinkTokenInterface(_link);\\n }\\n\\n // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF\\n // proof. rawFulfillRandomness then calls fulfillRandomness, after validating\\n // the origin of the call\\n function rawFulfillRandomness(\\n bytes32 requestId,\\n uint256 randomness\\n )\\n external\\n {\\n require(msg.sender == vrfCoordinator, \\\"Only VRFCoordinator can fulfill\\\");\\n fulfillRandomness(requestId, randomness);\\n }\\n}\\n\"\r\n },\r\n \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\"\r\n },\r\n \"@openzeppelin/contracts/token/ERC20/IERC20.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\"\r\n },\r\n \"@openzeppelin/contracts/access/Ownable.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\"\r\n },\r\n \"@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface LinkTokenInterface {\\n\\n function allowance(\\n address owner,\\n address spender\\n )\\n external\\n view\\n returns (\\n uint256 remaining\\n );\\n\\n function approve(\\n address spender,\\n uint256 value\\n )\\n external\\n returns (\\n bool success\\n );\\n\\n function balanceOf(\\n address owner\\n )\\n external\\n view\\n returns (\\n uint256 balance\\n );\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8 decimalPlaces\\n );\\n\\n function decreaseApproval(\\n address spender,\\n uint256 addedValue\\n )\\n external\\n returns (\\n bool success\\n );\\n\\n function increaseApproval(\\n address spender,\\n uint256 subtractedValue\\n ) external;\\n\\n function name()\\n external\\n view\\n returns (\\n string memory tokenName\\n );\\n\\n function symbol()\\n external\\n view\\n returns (\\n string memory tokenSymbol\\n );\\n\\n function totalSupply()\\n external\\n view\\n returns (\\n uint256 totalTokensIssued\\n );\\n\\n function transfer(\\n address to,\\n uint256 value\\n )\\n external\\n returns (\\n bool success\\n );\\n\\n function transferAndCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n )\\n external\\n returns (\\n bool success\\n );\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 value\\n )\\n external\\n returns (\\n bool success\\n );\\n\\n}\\n\"\r\n },\r\n \"@chainlink/contracts/src/v0.8/VRFRequestIDBase.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ncontract VRFRequestIDBase {\\n\\n /**\\n * @notice returns the seed which is actually input to the VRF coordinator\\n *\\n * @dev To prevent repetition of VRF output due to repetition of the\\n * @dev user-supplied seed, that seed is combined in a hash with the\\n * @dev user-specific nonce, and the address of the consuming contract. The\\n * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in\\n * @dev the final seed, but the nonce does protect against repetition in\\n * @dev requests which are included in a single block.\\n *\\n * @param _userSeed VRF seed input provided by user\\n * @param _requester Address of the requesting contract\\n * @param _nonce User-specific nonce at the time of the request\\n */\\n function makeVRFInputSeed(\\n bytes32 _keyHash,\\n uint256 _userSeed,\\n address _requester,\\n uint256 _nonce\\n )\\n internal\\n pure\\n returns (\\n uint256\\n )\\n {\\n return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));\\n }\\n\\n /**\\n * @notice Returns the id for this request\\n * @param _keyHash The serviceAgreement ID to be used for this request\\n * @param _vRFInputSeed The seed to be passed directly to the VRF\\n * @return The id for this request\\n *\\n * @dev Note that _vRFInputSeed is not the seed passed by the consuming\\n * @dev contract, but the one generated by makeVRFInputSeed\\n */\\n function makeRequestId(\\n bytes32 _keyHash,\\n uint256 _vRFInputSeed\\n )\\n internal\\n pure\\n returns (\\n bytes32\\n )\\n {\\n return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));\\n }\\n}\"\r\n },\r\n \"@openzeppelin/contracts/utils/Address.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\"\r\n },\r\n \"@openzeppelin/contracts/utils/Context.sol\": {\r\n \"content\": \"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\"\r\n }\r\n },\r\n \"settings\": {\r\n \"optimizer\": {\r\n \"enabled\": true,\r\n \"runs\": 200\r\n },\r\n \"outputSelection\": {\r\n \"*\": {\r\n \"*\": [\r\n \"evm.bytecode\",\r\n \"evm.deployedBytecode\",\r\n \"abi\"\r\n ]\r\n }\r\n },\r\n \"metadata\": {\r\n \"useLiteralContent\": true\r\n },\r\n \"libraries\": {}\r\n }\r\n}}",
"ABI":"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"raffleId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"total\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"n\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"filePath\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"result\",\"type\":\"uint32[]\"}],\"name\":\"RaffleResult\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"raffleId\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"randomness\",\"type\":\"uint256\"}],\"name\":\"RandomnessFulfilled\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"approvedOperators\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"raffleId\",\"type\":\"uint32\"}],\"name\":\"calculateRaffleResultForLargeTotal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"raffleId\",\"type\":\"uint32\"}],\"name\":\"calculateRaffleResultForSmallTotal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextRaffleId\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"raffleIdToRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"raffleInfos\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"total\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"n\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"filePath\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"randomness\",\"type\":\"uint256\"}],\"name\":\"rawFulfillRandomness\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"requestIdToRaffleId\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"}],\"name\":\"setFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"}],\"name\":\"setKeyHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"operators\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"ok\",\"type\":\"bool\"}],\"name\":\"setOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_total\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_n\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"_filePath\",\"type\":\"string\"}],\"name\":\"startRaffle\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"raffleId\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_tokenAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
"ContractName":"Raffle",
"CompilerVersion":"v0.8.2+commit.661d1103",
"OptimizationUsed":"1",
"Runs":"200",
"ConstructorArguments":"0000000000000000000000008c7382f9d8f56b33781fe506e897a4f1e2d17255000000000000000000000000326c977e6efc84e512bb9c30f76e30c160ed06fb6e75b569a01ef56d18cab6a8e71e6600d6ce853834d4a5748b720d06f878b3a400000000000000000000000000000000000000000000000000005af3107a4000",
"EVMVersion":"Default",
"Library":"",
"LicenseType":"",
"Proxy":"0",
"Implementation":"",
"SwarmSource":""
}
]
}
Submits a contract source code to PolygonScan for verification.
Note : This endpoint is limited to 100 verifications/day, regardless of API PRO tier.
📝
- 1.
- 2.Only supports HTTP POST due to max transfer size limitations for HTTP GET
- 3.Supports up to 10 different library pairs
- 4.Contracts that use "imports" will need to have the code concatenated into one file as we do not support "imports" in separate files.
- 5.List of supported solc versions, only solc version v0.4.11 and above is supported e.g. v0.4.25+commit.59dbf8f1
- 6.Upon successful submission you will receive a GUID (50 characters) as a receipt
- 7.You may use this GUID to track the status of your submission
- 8.
Note: Upon successful submission, a GUID is returned, which can be used to check for submission status.
👇
//Submit Source Code for Verification
$.ajax({
type: "POST", //Only POST supported
url: "//api.polygonscan.com/api", //Set to the correct API url for Other Networks
data: {
apikey: $('#apikey').val(), //A valid API-Key is required
module: 'contract', //Do not change
action: 'verifysourcecode', //Do not change
contractaddress: $('#contractaddress').val(), //Contract Address starts with 0x...
sourceCode: $('#sourceCode').val(), //Contract Source Code (Flattened if necessary)
codeformat: $('#codeformat').val(), //solidity-single-file (default) or solidity-standard-json-input (for std-input-json-format support
contractname: $('#contractname').val(), //ContractName (if codeformat=solidity-standard-json-input, then enter contractname as ex: erc20.sol:erc20)
compilerversion: $('#compilerversion').val(), // see https://polygonscan.com/solcversions for list of support versions
optimizationUsed: $('#optimizationUsed').val(), //0 = No Optimization, 1 = Optimization used (applicable when codeformat=solidity-single-file)
runs: 200, //set to 200 as default unless otherwise (applicable when codeformat=solidity-single-file)
constructorArguements: $('#constructorArguements').val(), //if applicable
evmversion: $('#evmVersion').val(), //leave blank for compiler default, homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul (applicable when codeformat=solidity-single-file)
licenseType: $('#licenseType').val(), //Valid codes 1-12 where 1=No License .. 12=Apache 2.0, see https://polygonscan.com/contract-license-types
libraryname1: $('#libraryname1').val(), //if applicable, a matching pair with libraryaddress1 required
libraryaddress1: $('#libraryaddress1').val(), //if applicable, a matching pair with libraryname1 required
libraryname2: $('#libraryname2').val(), //if applicable, matching pair required
libraryaddress2: $('#libraryaddress2').val(), //if applicable, matching pair required
libraryname3: $('#libraryname3').val(), //if applicable, matching pair required
libraryaddress3: $('#libraryaddress3').val(), //if applicable, matching pair required
libraryname4: $('#libraryname4').val(), //if applicable, matching pair required
libraryaddress4: $('#libraryaddress4').val(), //if applicable, matching pair required
libraryname5: $('#libraryname5').val(), //if applicable, matching pair required
libraryaddress5: $('#libraryaddress5').val(), //if applicable, matching pair required
libraryname6: $('#libraryname6').val(), //if applicable, matching pair required
libraryaddress6: $('#libraryaddress6').val(), //if applicable, matching pair required
libraryname7: $('#libraryname7').val(), //if applicable, matching pair required
libraryaddress7: $('#libraryaddress7').val(), //if applicable, matching pair required
libraryname8: $('#libraryname8').val(), //if applicable, matching pair required
libraryaddress8: $('#libraryaddress8').val(), //if applicable, matching pair required
libraryname9: $('#libraryname9').val(), //if applicable, matching pair required
libraryaddress9: $('#libraryaddress9').val(), //if applicable, matching pair required
libraryname10: $('#libraryname10').val(), //if applicable, matching pair required
libraryaddress10: $('#libraryaddress10').val() //if applicable, matching pair required
},
success: function (result) {
console.log(result);
if (result.status == "1") {
//1 = submission success, use the guid returned (result.result) to check the status of your submission.
// Average time of processing is 30-60 seconds
document.getElementById("postresult").innerHTML = result.status + ";" + result.message + ";" + result.result;
// result.result is the GUID receipt for the submission, you can use this guid for checking the verification status
} else {
//0 = error
document.getElementById("postresult").innerHTML = result.status + ";" + result.message + ";" + result.result;
}
console.log("status : " + result.status);
console.log("result : " + result.result);
},
error: function (result) {
console.log("error!");
document.getElementById("postresult").innerHTML = "Unexpected Error"
}
});
//Check Source Code Verification Status
$.ajax({
type: "GET",
url: "//api.polygonscan.com/api",
data: {
apikey: $('#apikey').val(),
guid: 'ezq878u486pzijkvvmerl6a9mzwhv6sefgvqi5tkwceejc7tvn', //Replace with your Source Code GUID receipt above
module: "contract",
action: "checkverifystatus"
},
success: function (result) {
console.log("status : " + result.status); //0=Error, 1=Pass
console.log("message : " + result.message); //OK, NOTOK
console.log("result : " + result.result); //result explanation
$('#guidstatus').html(">> " + result.result);
},
error: function (result) {
alert('error');
}
});
Submits a proxy contract source code to PolygonScan for verification.
- 1.
- 2.Current daily limit of 100 submissions per day per user (subject to change)
- 3.Only supports HTTP post
- 4.Upon successful submission you will receive a GUID (50 characters) as a receipt
- 5.You may use this GUID to track the status of your submission
- 6.Verified proxy contracts will display the "Read/Write as Proxy" of the implementation contract under the contract address's contract tab
Request
Response
// example with only the mandatory contract address parameter
curl -d "address=0xcbdcd3815b5f975e1a2c944a9b2cd1c985a1cb7f" "https://api-testnet.polygonscan.com/api?module=contract&action=verifyproxycontract&apikey=YourApiKeyToken"
// example using the expectedimplementation optional parameter
// the expectedimplementation enforces a check to ensure the returned implementation contract address == address picked up by the verifier
curl -d "address=0xbc46363a7669f6e12353fa95bb067aead3675c29&expectedimplementation=0xe45a5176bc0f2c1198e2451c4e4501d4ed9b65a6" "https://api-testnet.polygonscan.com/api?module=contract&action=verifyproxycontract&apikey=YourApiKeyToken"
// OK
{"status":"1","message":"OK","result":"gwgrrnfy56zf6vc1fljuejwg6pelnc5yns6fg6y2i6zfpgzquz"}
// NOTOK
{"status":"0","message":"NOTOK","result":"Invalid API Key"}
Request
Response
curl "https://api-testnet.polygonscan.com/api?module=contract&action=checkproxyverification&guid=gwgrrnfy56zf6vc1fljuejwg6pelnc5yns6fg6y2i6zfpgzquz&apikey=YourApiKeyToken"
// OK
{"status":"1","message":"OK","result":"The proxy's (0xbc46363a7669f6e12353fa95bb067aead3675c29) implementation contract is found at 0xe45a5176bc0f2c1198e2451c4e4501d4ed9b65a6 and is successfully updated."}
// NOTOK
{"status":"0","message":"NOTOK","result":"A corresponding implementation contract was unfortunately not detected for the proxy address."}
Last modified 1yr ago