Remix
如何將文件導入混音(ERC721 合約)?
我得到這個錯誤 -
無法導入“未定義”:未找到
這在螢幕上閃現——
正在載入 https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/introspection/ERC165.sol …
導入有錯誤嗎?
該程式碼剛剛從 github 獲取 ERC721。
pragma 可靠性 ^0.5.2; 導入“https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721.sol”; 導入“https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721Receiver.sol”; 導入“https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol”; 導入“https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/utils/Address.sol”; 導入“https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.0.0/contracts/drafts/Counter.sol”; 導入“https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/introspection/ERC165.sol”; /** * @title ERC721 Non-Fungible Token Standard 基本實現 * @dev 見 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ 合約 ERC721 是 ERC165,IERC721 { 對 uint256 使用 SafeMath; 使用地址作為地址; 使用 Counters.Counter 的計數器; // 等於`bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // 也可以通過 `IERC721Receiver(0).onERC721Received.selector` 獲得 bytes4 私有常量 _ERC721_RECEIVED = 0x150b7a02; // 令牌 ID 到所有者的映射 映射(uint256 => 地址)私有_tokenOwner; // 從令牌 ID 到批准地址的映射 映射(uint256 => 地址)私有 _tokenApprovals; // 從所有者映射到擁有令牌的數量 映射(地址=> Counters.Counter)私有_ownedTokensCount; // 從所有者到操作員批准的映射 映射(地址=>映射(地址=>布爾))私有_operatorApprovals; bytes4 私有常量 _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ 建構子()公共{ // 通過 ERC165 註冊支持的介面以符合 ERC721 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev 獲取指定地址的餘額 * @param 所有者地址查詢餘額 * @return uint256 代表傳遞地址擁有的數量 */ 函式 balanceOf(地址所有者)公共視圖返回(uint256){ 要求(所有者!= 地址(0)); 返回 _ownedTokensCount[所有者].current(); } /** * @dev 獲取指定token ID的所有者 * @param tokenId uint256 查詢所有者的token ID * @return 目前標記為給定令牌 ID 所有者的地址 */ 函式 ownerOf(uint256 tokenId) 公共視圖返回(地址){ 地址所有者 = _tokenOwner[tokenId]; 要求(所有者!= 地址(0)); 返回所有者; } /** * @dev 批准另一個地址來傳輸給定的令牌 ID * 零地址表示沒有批准的地址。 * 在給定時間,每個令牌只能有一個批准的地址。 * 只能由令牌所有者或經批准的操作員呼叫。 * @param 要為給定令牌 ID 批准的地址 * @param tokenId uint256 待批准的token ID */ 功能批准(地址,uint256 tokenId)公共{ 地址所有者 = ownerOf(tokenId); 要求(到!=所有者); 要求(msg.sender == 所有者 || isApprovedForAll(所有者,msg.sender)); _tokenApprovals[tokenId] = to; 發出批准(所有者,to,tokenId); } /** * @dev 獲取令牌 ID 的批准地址,如果沒有設置地址,則為零 * 如果令牌 ID 不存在,則還原。 * @param tokenId uint256 查詢審批的token ID * @return 目前批准給定令牌 ID 的地址 */ 函式 getApproved(uint256 tokenId) 公共視圖返回(地址){ 要求(_exists(tokenId)); 返回 _tokenApprovals[tokenId]; } /** * @dev 設置或取消對給定操作員的批准 * 運營商可以代為轉移發送方的所有代幣 * @param to operator address 設置審批 * @param approved 表示要設置的批准狀態 */ 功能 setApprovalForAll(地址,布爾批准)公共 { 要求(到!= msg.sender); _operatorApprovals[msg.sender][to] = 批准; 發出 ApprovalForAll(msg.sender, to, 批准); } /** * @dev 告訴操作員是否被給定所有者批准 * @param owner 想要查詢審批的所有者地址 * @param operator 要查詢審批的操作員地址 * @return bool 給定的操作員是否被給定的所有者批准 */ function isApprovedForAll(address owner, address operator) public view returns (bool) { 返回 _operatorApprovals[所有者][操作員]; } /** * @dev 將給定令牌 ID 的所有權轉移到另一個地址 * 不鼓勵使用此方法,盡可能使用 `safeTransferFrom` * 要求 msg.sender 是所有者、批准者或操作者 * @param 來自令牌的目前所有者 * @param to address 以接收給定令牌 ID 的所有權 * @param tokenId uint256 要轉移的token的ID */ 函式 transferFrom(地址來自,地址,uint256 tokenId)公共{ 要求(_isApprovedOrOwner(msg.sender,tokenId)); _transferFrom(from, to, tokenId); } /** * @dev 安全地將給定令牌 ID 的所有權轉移到另一個地址 * 如果目標地址是合約,則必須實現`onERC721Received`, * 在安全傳輸時呼叫,並返回魔法值 *`bytes4(keccak256("onERC721Received(地址,地址,uint256,字節)"))`; 除此以外, * 轉移被還原。 * 要求 msg.sender 是所有者、批准者或操作者 * @param 來自令牌的目前所有者 * @param to address 以接收給定令牌 ID 的所有權 * @param tokenId uint256 要轉移的token的ID */ 函式safeTransferFrom(地址來自,地址,uint256 tokenId)公共{ safeTransferFrom(from, to, tokenId, ""); } /** * @dev 安全地將給定令牌 ID 的所有權轉移到另一個地址 * 如果目標地址是合約,則必須實現`onERC721Received`, * 在安全傳輸時呼叫,並返回魔法值 *`bytes4(keccak256("onERC721Received(地址,地址,uint256,字節)"))`; 除此以外, * 轉移被還原。 * 要求 msg.sender 是所有者、批准者或操作者 * @param 來自令牌的目前所有者 * @param to address 以接收給定令牌 ID 的所有權 * @param tokenId uint256 要轉移的token的ID * @param _data 字節數據與安全傳輸檢查一起發送 */ 函式safeTransferFrom(地址來自,地址,uint256 tokenId,字節記憶體_data)公共{ transferFrom(from, to, tokenId); 要求(_checkOnERC721Received(從,到,tokenId,_data)); } /** * @dev 返回指定token是否存在 * @param tokenId uint256 查詢是否存在的token的ID * @return bool 令牌是否存在 */ function _exists(uint256 tokenId) 內部視圖返回 (bool) { 地址所有者 = _tokenOwner[tokenId]; 返回所有者!=地址(0); } /** * @dev 返回給定的消費者是否可以轉移給定的令牌 ID * @param spender 要查詢的spender地址 * @param tokenId uint256 要轉移的token的ID * @return bool msg.sender 是否被批准用於給定的令牌 ID, * 是 owner 的 operator,或者是 token 的 owner */ 函式_isApprovedOrOwner(地址花費者,uint256 tokenId)內部視圖返回(布爾){ 地址所有者 = ownerOf(tokenId); return (spender == 所有者 || getApproved(tokenId) == 支出者 || isApprovedForAll(所有者,支出者)); } /** * @dev 內部函式來鑄造一個新的代幣 * 如果給定的令牌 ID 已經存在,則恢復 * @param to 擁有鑄造代幣的地址 * @param tokenId uint256 要鑄造的令牌的 ID */ 函式_mint(地址,uint256 tokenId)內部{ 要求(到!= 地址(0)); 要求(!_exists(tokenId)); _tokenOwner [tokenId] = to; _ownedTokensCount[to].increment(); 發出 Transfer(address(0), to, tokenId); } /** * @dev 內部函式燒錄特定令牌 * 如果令牌不存在則恢復 * 已棄用,請改用 _burn(uint256)。 * @param owner 要銷毀的令牌的所有者 * @param tokenId uint256 被燒掉的token的ID */ 函式_burn(地址所有者,uint256 tokenId)內部{ 要求(所有者(令牌ID)==所有者); _clearApproval(tokenId); _ownedTokensCount[所有者].decrement(); _tokenOwner[tokenId] = 地址(0); 發出轉移(所有者,地址(0),tokenId); } /** * @dev 內部函式燒錄特定令牌 * 如果令牌不存在則恢復 * @param tokenId uint256 被燒掉的token的ID */ 函式_burn(uint256 tokenId)內部{ _burn(ownerOf(tokenId), tokenId); } /** * @dev 將給定令牌 ID 的所有權轉移到另一個地址的內部函式。 * 與 transferFrom 不同,這對 msg.sender 沒有任何限制。 * @param 來自令牌的目前所有者 * @param to address 以接收給定令牌 ID 的所有權 * @param tokenId uint256 要轉移的token的ID */ 函式_transferFrom(地址來自,地址,uint256 tokenId)內部{ 需要(ownerOf(tokenId)==來自); 要求(到!= 地址(0)); _clearApproval(tokenId); _ownedTokensCount[來自].decrement(); _ownedTokensCount[to].increment(); _tokenOwner [tokenId] = to; 發出轉移(從,到,tokenId); } /** * @dev 在目標地址上呼叫 `onERC721Received` 的內部函式 * 如果目標地址不是合約,則不執行呼叫 * @param from address 代表給定令牌 ID 的先前所有者 * @param 到將接收令牌的目標地址 * @param tokenId uint256 要轉移的token的ID * @param _data bytes 與呼叫一起發送的可選數據 * @return bool 呼叫是否正確返回了預期的魔法值 */ 函式_checkOnERC721Received(地址來自,地址,uint256 tokenId,字節記憶體_data) 內部回報 (bool) { if (!to.isContract()) { 返回真; } bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); 返回(retval == _ERC721_RECEIVED); } /** * @dev 私有函式,用於清除給定令牌 ID 的目前批准 * @param tokenId uint256 要轉移的token的ID */ 函式_clearApproval(uint256 tokenId)私有{ if (_tokenApprovals[tokenId] != 地址(0)) { _tokenApprovals[tokenId] = 地址(0); } } }
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/IERC721.sol"; import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol"; import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol"; import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/utils/Address.sol"; import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/drafts/Counters.sol"; import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/introspection/ERC165.sol";
這編譯。我不確定櫃檯上的 v2.0.0。我把它換成了大師。
從 NPM 導入
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
帶版本
import "@openzeppelin/contracts@4.2.0/token/ERC20/ERC20.sol";
從 Github 導入
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/math/SafeMath.sol";