Erc-721

為什麼 ERC721 ownerOf 函式在內部的引用與所有其他函式不同

  • November 3, 2021

在以下取自 Openzeppelin 的 ERC721 合約的函式中,為什麼ERC721.ownerOf()像靜態函式一樣呼叫所有其他函式而不引用合約本身(例如:) getApproved?這只是一個約定嗎?我在函式簽名中找不到任何可以將其與其他方法區分開來的異常之處。

function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
   require(_exists(tokenId), "ERC721: operator query for nonexistent token");
   address owner = ERC721.ownerOf(tokenId);
   return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}

它確保呼叫的 ownerOf 函式始終是 OpenZeppelin ERC721 實現中定義的函式,即使 ownerOf 函式在子合約中被覆蓋。

函式的簽名沒有什麼不尋常的,關鍵是它所做的:定義相對於合約實際儲存狀態的所有權。

正如你在這裡看到的:

“以這種方式建構的原因是,如果 ERC721.ownerOf 可以是我們在儲存中擁有的所有者以外的任何東西,那麼我們就不可能確保契約的內部一致性。保證內部一致性的負擔轉移到了希望的開發人員身上在這些利基案例中覆蓋。”

您可以在以下範例中看到該行為:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.0 <0.9.0;

interface Interface {
   function ownerOf() external view returns (address);
}

contract Parent is Interface {
     
   function ownerOf() public view virtual override returns (address) {
       return msg.sender;
   }
   
   function getOwnerOfSecure() public view returns (address) {
       return Parent.ownerOf();
   }
   
   function getOwnerOfInsecure() public view returns (address) {
       return ownerOf();
   }
}

contract Child is Parent {
   function ownerOf() public view virtual override returns (address) {
       return address(0);
   }
   
}

getOwnerOfSecure 永遠不會改變行為,而當 ownerOf 被子類覆蓋時 getOwnerOfInsecure 會改變。

引用自:https://ethereum.stackexchange.com/questions/112782