我在Rinkeby Testnet上使用@chainlink验证我的智能合约时遇到问题。我的合同是部署到Rinkeby很好,但遇到问题,当我有publish_source上。当使用v0.6和Solidity 0.6.6时,合约验证良好,我似乎只有v0.8有问题。有人知道为什么会这样吗?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
/**
* @title MyContract is an example contract which requests data from
* the Chainlink network
* @dev This contract is designed to work on multiple networks, including
* local test networks
*/
contract MyContract is ChainlinkClient, ERC721 {
using Chainlink for Chainlink.Request;
address constant RINKEBY_ORACLE =
0x3A56aE4a2831C3d3514b5D7Af5578E45eBDb7a40;
bytes32 constant RINKEBY_JOB_ID =
bytes32("187bb80e5ee74a139734cac7475f3c6e");
uint256 constant FEE = 0.1 * 10**18;
uint256 public tokenCounter;
bytes32 public data;
string public image_url;
struct Clip {
string name;
string url;
}
Clip[] public clips;
mapping(bytes32 => string) public requestIdToClipName;
mapping(bytes32 => address) public requestIdToSender;
mapping(bytes32 => string) public requestIdToTokenURI;
event requestedCollectible(bytes32 indexed requestId);
mapping(bytes32 => uint256) public requestToTokenId;
mapping(uint256 => string) public tokenIdToName;
mapping(uint256 => string) public tokenIdToImgUrl;
constructor(address _link) public ERC721("Tests", "TST") {
if (_link == address(0)) {
setPublicChainlinkToken();
} else {
setChainlinkToken(_link);
}
setChainlinkOracle(0x3A56aE4a2831C3d3514b5D7Af5578E45eBDb7a40);
tokenCounter = 0;
}
function getChainlinkToken() public view returns (address) {
return chainlinkTokenAddress();
}
function createRequestTo(
string memory _url,
string memory _path,
string memory clipName
) public returns (bytes32 requestId) {
Chainlink.Request memory req = buildChainlinkRequest(
RINKEBY_JOB_ID,
address(this),
this.fulfill.selector
);
req.add("get", _url);
req.add("path", _path);
requestId = sendChainlinkRequestTo(RINKEBY_ORACLE, req, FEE);
requestIdToClipName[requestId] = clipName;
requestIdToSender[requestId] = msg.sender;
emit requestedCollectible(requestId);
return requestId;
}
function fulfill(bytes32 _requestId, bytes32 _data)
public
recordChainlinkFulfillment(_requestId)
{
address nftOwner = requestIdToSender[_requestId];
string memory name = requestIdToClipName[_requestId];
uint256 newItemId = clips.length;
data = _data;
image_url = bytes32ToString(data);
clips.push(Clip(name, image_url));
_safeMint(nftOwner, newItemId);
tokenIdToName[newItemId] = name;
tokenIdToImgUrl[newItemId] = image_url;
}
function getNumberOfClips() public view returns (uint256) {
return clips.length;
}
/**
* @notice Allows the owner to withdraw any LINK balance on the contract
*/
function withdrawLink() public {
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
/**
* @notice Call this method if no response is received within 5 minutes
* @param _requestId The ID that was generated for the request to cancel
* @param _payment The payment specified for the request to cancel
* @param _callbackFunctionId The bytes4 callback function ID specified for
* the request to cancel
* @param _expiration The expiration generated for the request to cancel
*/
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
) public {
cancelChainlinkRequest(
_requestId,
_payment,
_callbackFunctionId,
_expiration
);
}
}
下面是我用来部署的脚本:
from brownie import MyContract, accounts, network, config
from scripts.helpful_scripts import fund_contract
def main():
dev = accounts.add(config['wallets']['from_key'])
print(network.show_active())
publish_source = True
my_contract = MyContract.deploy(
config['networks'][network.show_active()]['link_token'],
{"from": dev},
publish_source=publish_source
)
fund_contract(my_contract)
return my_contract
错误:
Transaction sent: 0x01ef409a5b0c2f6de60194f14f1d2e8ffac9a6ce6397aaa38392d949e2656909
Gas price: 1.000000008 gwei Gas limit: 2793499 Nonce: 359
MyContract.constructor confirmed Block: 9332417 Gas used: 2539545 (90.91%)
MyContract deployed at: 0x42fBa06808C3cB11e5D7AcC6BB02B1A612e040d1
File "brownie/_cli/run.py", line 49, in main
return_value, frame = run(
File "brownie/project/scripts.py", line 103, in run
return_value = f_locals[method_name](*args, **kwargs)
File "./scripts/deploy_api.py", line 11, in main
my_contract = MyContract.deploy(
File "brownie/network/contract.py", line 600, in __call__
return tx["from"].deploy(
File "brownie/network/account.py", line 555, in deploy
contract.publish_source(deployed_contract, silent=silent)
File "brownie/network/contract.py", line 410, in publish_source
contract_info = self.get_verification_info()
File "brownie/network/contract.py", line 292, in get_verification_info
if symbol_alias["local"] is not None:
KeyError: 'local'
这里有两点:
- Brownie Etherscan验证在Solidity v0.8中不能很好地工作。我们正在修复这个问题。
- 看起来您正在部署到本地网络而不是Rinkeby。要么在本地部署时删除publish_source,要么在部署脚本的末尾添加
--network rinkeby
以部署到Rinkeby。