ERC-173 Contract ownership standard
Final · Other · created 2018-06-07
Unifies how to read who owns a smart contract and how to transfer ownership to another address. Wallets and apps can check and manage the owner of any contract in the same way.
Why it is needed
Many smart contracts need to be owned or controlled by someone in order to withdraw funds or perform administrative tasks. But if the way to check and transfer the owner differs from contract to contract, tools for handling ownership cannot be made general-purpose. The original text gives four examples of why such a standard is needed. Exchanges that buy, sell or auction contracts can operate widely only if there is a standard for reading the owner and transferring ownership. The same applies to contract wallets that hold and move ownership of many contracts. A contract registry needs a standard for verifying that a submitter is the real owner, so that only owners can register or remove their own contracts. User interfaces that show and transfer ownership can also only be built if they assume the same interface. This standard defines a single ownership interface for this compatibility.
What to implement
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);: Records the previous owner and the new owner addresses when contract ownership changes.function owner() view external returns(address);: Returns the address of the current owner.function transferOwnership(address _newOwner) external;: Sets the address of the new owner. Passing the zero address renounces ownership.function supportsInterface(bytes4 interfaceID) external view returns (bool);: An ERC-165 function that tells whether the contract implements the given interface.
In depth
Interface structure and ERC-165 identifier
A contract that follows ERC-173 must implement the ERC173 interface. This interface consists of one OwnershipTransferred event and two functions, owner() and transferOwnership(address _newOwner). It is also recommended (should) to implement ERC-165 for the ERC-173 interface. The ERC-165 interface identifier is 0x7f5828d0. supportsInterface(bytes4 interfaceID) returns true if it implements the given interfaceID and that value is not 0xffffffff, and false otherwise. With this value, other contracts or interfaces can check for support before calling the ownership functions.
owner(): owner lookup
owner() is a lookup function that returns the owner's address. It is declared as view external in the interface, but the original text explicitly says it may be implemented as pure. This means an implementation that hardcodes the owner in the code instead of reading it from a state variable is also allowed. The return value is a single address, and an exchange or registry can compare it with the caller's address to decide whether the submitter is the owner.
transferOwnership(): transfer and renounce
transferOwnership(address _newOwner) sets the new owner address of the contract. It is declared as external in the interface, but may be implemented as public. To renounce ownership, call transferOwnership(address(0)) with the zero address as _newOwner. This leaves the contract with no owner. The original text defines only the function signature and the meaning of its behavior, and does not specify an access control scheme for who may call this function.
OwnershipTransferred event
OwnershipTransferred(address indexed previousOwner, address indexed newOwner) is emitted when ownership of a contract changes. Both parameters are declared indexed, so you can filter the logs for ownership changes that a given address handed over or received. The original text says a contract should also emit this event when it is created. That way the first owner can be identified from the event record alone.
Rationale: minimal functions, backward compatibility, gas efficiency
The standard weighed four key factors: keeping the number of interface functions to a minimum so contracts do not become bloated, backward compatibility with existing contracts, simplicity, and gas efficiency. After reviewing several ownership schemes, the authors chose the current one because it is simple, has low gas cost, and is compatible with existing contracts. This standard does not rule out other ownership schemes. A single contract can implement this standard together with other schemes, so ownership can be managed and transferred through multiple paths. The original text also notes that other standards can extend this one to add ownership features, and that this has in fact happened.
Approaches considered but not adopted
The first links an ENS (Ethereum Name Service) domain name to the contract. owner() looks up the owner address of a specific ENS name and treats it as the contract owner, so transferring ownership of the ENS name also transfers the contract. Its drawbacks are that it is not compatible with existing contracts and that getting the owner address requires an external call to ENS-related contracts, which costs gas. The second links an ERC-721 based NFT (non-fungible token) to the contract. Its advantage is that existing ERC-721 infrastructure can be used to buy, sell or auction the contract, but it requires added complexity and extra infrastructure. Unless the NFT is separately programmed to track the contract, the NFT side does not know that it owns the contract, and this approach is also not backward compatible.
Backward compatibility and proposal status
The original text states that many existing contracts already implement this standard. This is also why the standard treats backward compatibility with existing contracts as a key factor. This standard belongs to the ERC category of the Standards Track and its status is Final. It was created on June 7, 2018, and the authors are Nick Mudge and Dan Finlay. Because the status is Final, the specification is settled and will not change further.
Things to watch out for
- Private key management for externally owned accounts: If the address returned by owner() is an externally owned account (EOA), the private key of that account must not be lost or leaked. This is because the owner key is the administrative authority over the contract.