Jumping into Solidity — The ERC721 Standard (Part 2)

“A displayed content of a toolkit displayed showing tools like hammer, axe, box cutter, iron and flashlight” by Todd Quackenbush on Unsplash

Interfaces and the ERC165 Standard

The ERC721 Standard states that:

Interfaces

An interface is basically an abstract contract, but the only thing you can define are unimplemented functions. It’s an outline, written in Solidity code, which ensures contracts written by other developers all work well together, without having to know each other’s code base.

function balanceOf(address _owner) external view returns (uint256);

The ERC165 Standard

interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as
/// specified in ERC-165
/// @dev Interface identification is specified in
/// ERC-165. This function uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID`
/// and `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
function balanceOf(address _owner) external view returns (uint256){
//...
};
this.balanceOf.selector
bytes4(keccak256("balanceOf(address)"))
interfaceID = this.function1.selector ^ this.function2.selector ^ this.function3.selector;
contract CheckERC165 is ERC165 {

mapping (bytes4 => bool) internal supportedInterfaces;
function supportsInterface(bytes4 interfaceID) external view returns (bool){
return supportedInterfaces[interfaceID];
}
constructor() public {
supportedInterfaces[this.supportsInterface.selector] = true;
}

The ERC721 Interfaces

Now that we know about interfaces, let’s move back to ERC721. You’ll notice that the ERC721 Standard actually contains four different interfaces. One main one for a general ERC721 contract, one for contracts that can receive ERC721 tokens, and two for optional extensions which add extra functionality. We’ll ignore the extensions for now, and just have a quick look at the main interface and the receiver.

Payable Functions and Mutability

Something that immediately stood out to me was that four of the functions in the ERC721 interface have the payable modifier. Namely the two safeTransferFrom functions, transferFrom and approve. It didn’t really make sense that an ERC721 contract should always take payment every time a token is transferred, or control of a token is granted.

  1. keep these functions as payable, and just return any Ether that gets sent with transactions (or keep it if that’s your design), or
  2. remove the payable modifier, but you’ll have to do the same thing in your copy of the ERC721 interface in order to avoid throwing a TypeError.

ERC721TokenReceiver

Before I wrap up I want to quickly cover the ERC721TokenReceiver interface. This isn’t something our token contract needs to inherit. As the name implies, it’s an interface for contracts that can receive ERC721 tokens.

function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))
contract ValidReceiver is ERC721TokenReceiver {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4){
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
}
}
contract InvalidReceiver is ERC721TokenReceiver {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4){
return bytes4(keccak256("some invalid return data"));
}
}

Wrapping up

So after all that, you should be familiar with interfaces, and have an ERC165 implementation which you can use for indicating which interfaces are implemented by your contract. We also covered mutability guarantees in the ERC721 standard, and quickly wrote a couple of dummy wallet contracts for testing later.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Andrew Parker

Andrew Parker

Codeslinger. Melbourne based Solidity developer for hire.