Abstract
This ERC is an administered blockchain whitelist that addresses the proliferation of addresses by ensuring their authenticity for important transactions. It allows an organisation, called a registrant, to list the valid smart contract addresses it has deployed and it operates. Once an administrator of the recognized authority approves a registrant, that registrant can then record their service-related smart contract addresses in the "references" list. Overall this ERC facilitates on-chain verification and the identification and management of smart contract ecosystems.
Motivation
The rapid proliferation of smart contract addresses poses a challenge to users calling to implement robust mechanisms for authenticity verification for any transactions using them. This proposal aims to standardize a type of administered blockchain whitelist, addressing this issue by providing a structured solution for managing trust on-chain. The proposal for newcomers as well as for seasoned users will greatly facilitate and bring certainty to the "do your homework" address validation phase.
To achieve the goals to have both a decentralized administration of the whitelist while also having the ability to be trusted by the users we have a design where a trusted supervisor delegates the contracts management to vetted actors or operators.
The smart-contract operators, known as registrants, securely expose and maintain the valid smart contract addresses that they operate. Through an off-chain process, administrators of a recognized authority approve registrants using its own criteria, the operators then gain the ability to record their service-related smart contracts addresses in a dedicated "references" list.
In terms of automation, the directory allows on-chain verification for:
- smart wallets to check and validate the addresses upon usage or
- other smart contracts to perform addresses checks within their code possibly using standardized mechanisms
Information is maintained by the stakeholders and it is also in their best interest to keep it up to date for their customers.
Specification
The following interface and rules are normative. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Definitions
-
recognized authority
An organisation which is well known by potential users who decides to deploy an ERC-8095 contract. Such organisations can be major token issuers, exchanges, state regulators, non profit foundations, industry consortia ...
-
ERC-8095 contract
An administered blockchain whitelist smart-contract that serves as a shared, on-chain repository for lists of addresses, which can be either Externally Owned Accounts (EOA) or smart contracts. It functions as a decentralized directory composed of references (smart contract addresses) and their issuers (registrants).
-
Registrant
A service provider who, after receiving approval from an administrator of the recognized authority, is registered by that administrator in the ERC-8095 contract. The registrant must have blockchain access and signing capability in order to write address records into the ERC-8095 contract to build its references list. Once registered, a registrant can deploy smart contracts for the purpose of their services and record their addresses in the references list. The registrant must provide and keep updated its own Universal Resource Identifier (URI) for its clients to consult service terms and possibly register for services. The registrant's address can be an EOA or another smart contract.
-
Reference
A smart contract addresse issued by a registrant. The core data is held within the ERC-8095 contract's "references table," which contains all declared smart contract addresses; these can also be EOAs. Each reference includes: the registrant's address, the reference's address, a project ID, the reference type, the reference version, and a status.
-
Administrator
The ERC-8095 contract is operated from one or several administrator addresses. In its simple form the ERC-8095 contract administrator address is the contract deployer address usually called the "owner" Provision is made to allow several distinct administrator addresses (see Optional Features) Administrators have the authority to add or invalidate registrants on the "registrants list". Administrator addresses are responsible for (de)activating, configuring, and managing the decentralized directory.
-
ReferenceStatus
A component within the statusHistory of a reference, tracking its evolution over time. It contains a status (a free-text string describing the current state, e.g., "in production," "pending," "abandoned") and a timeStamp (the exact time of the status update).
-
on-chain verification
A concept where a token (fungible or non-fungible) is programmed to consult a ERC-8095 contract to filter addresses for transactions (e.g., transfers, minting). This allows for access control mechanisms within token ecosystems; if the list of references in the ERC-8095 contract changes, the token contract does not need to be modified. They are configured with the relevant ERC-8095 contract address and
registrantAddressvariables to enable this consultation functionality. -
URI
A string that a registrant can provide and update to offer additional information about their services, accessible to clients (Web2 entry point). The ERC-8095 contract itself can have a contractUri at deployment, the URI refers to an informative page describing the usage of the specific instance of the contract.
Public Interface
solidity
call interface
constructor parameters
_contractUri (string)
A non-modifiable string URI that describes the ERC-8095 contract itself and the recognized authority that has issued it. It has to be hosted by the issuer on its main domain name. This URI allows the recognized authority to provide descriptive information about itself to the users.
setActivationCode(uint256 _activationCode) _activationCode values
- 0 notActivated (initial value at deployment time)
- 1 activated
- 2 endOfLife It is important to signal to the users that a specific instance of an ERC-8095 contract has reached end of life so that they don't inadvertently rely on outdated information
getContractUri() String
Returns the URI given at contract deployment time This URI informs the user of the identity of the recognized authority managing the contract see also: Security Considerations for impersonation prevention
getActivationCode()
If the contract reaches its end of life, it will revert with message "Directory is not active" to any other calls. This call allows to ascertain that a valid contract address is used but that the contract is no longer in use.
createRegistrant(address registrantAddress)
Creates a new registrant. This can only be called by one of the administrators.
disableRegistrant(address registrantAddress)
Disables a registrant by setting its status to invalid, preventing them from creating new references. This can only be called by one of the administrators Once disabled, the registrant cannot be re-enabled unless the optional registrant status audit trail is implemented
updateRegistrantUri(string registrantUri)
Allows a registrant (msg.sender) to update their registrant_uri.
createReference(address referenceAddress, string referenceDescription, string referenceType, string referenceVersion, string status)
Creates a new reference by a registrant giving an initial status. Registrant must have been created by the administrator, the msg.sender is implicitly used as registrantAddress The registrant must not be disabled for the reference to be created The intent for referenceDescription is to hold a JSON structure with fields such as title, metadata, codeHash, API, documentation URI ... referenceType, referenceVersion, status are meant to be predefined value strings such that they can be verified by a smart contract without parsing
updateReferenceStatus(address referenceAddress, string newStatus)
Adds a new status and timestamp to a reference status see also: Optional Features for a possible audit trail
information API (getters)
getRegistrantUri(address _registrantAddress) external view returns (string memory)
Returns the information URI from the given registrant, this allows a user to confirm the web identity of a contract owner.
getReferenceStatus(address referenceAddress)
Returns the latest status and timestamp of a reference This is the simplest and main information entry for the public
getReference(address referenceAddress)
Returns all the information known about a reference:
- address registrantAddress
- string memory referenceDescription
- string memory referenceType
- string memory referenceVersion
- string memory status
constant values
Contract Activation code
As returned by getActivationCode()
- 0 notActivated (initial value at deployment time)
- 1 activated
- 2 endOfLife
Reference status
This is status field returned by getReference()
- 0 reference created but contract is not to be used
- 1 contract in beta test
- 2 contract is use
- 3 contract being deprecated, can still be used
- 4 contract end of life, should not be used
Required Behavior
The owner only can alter the registrant list. Each registrant can alter its own references.
Optional Features
distinct supplementary administrator addresses
This feature allows the deployer to give administration power to other addresses specified at deployment time This may help if the organization of the recognized authority requires such separation In this case, the constructor receives the administration addresses as parameters:
- _parentAddress1 (address): ◦ The address of the first ERC-8095 contract administrator. ◦ One of two addresses designated as creators/administrators, with rights to add or invalidate registrants. ◦ Must be different from _parentAddress2 and not address(0).
- _parentAddress2 (address): ◦ The address of the second ERC-8095 contract administrator. ◦ Similar to _parentAddress1, it has administrative rights. ◦ Must be different from _parentAddress1 and not address(0).
consultable audit trail for the reference statuses
This feature allows recording and exposing to the requesting user all the past status changes of a reference. This is meant to ease administration or for forensics
getReference(address referenceAddress) see full description above
when the optional audit trail is implemented getReference returns an additional information: the timestamp of the status
getReferenceLastStatusIndex(address referenceAddress)
when the optional audit trail is implemented, returning the last index allows to retrieve all the changes by iterating getReferenceStatusAtIndex
getReferenceStatusAtIndex(address referenceAddress, uint256 statusIndex)
Returns the status and timestamp at a specific index in the statusHistory
registrant status management
isValidRegistrant (_registrantAddress)
An implementation may want to distinguish between non existent registrants and invalid registrants This returns whether the registrant is disabled, a non existent registrant will raise an error
registrant status audit trail
In the optional case where an audit trail of the registrant status changes is recorded This feature is used if registrant drop out of compliance and needs to be reenacted later
getContractVersion
This feature allows to track code versions of the contract
functions for enumerating the registrant and reference lists
getDisabledRegistrants() address[]
Returns an address table listing all the registrants that are disabled
getRegistrantLastIndex()
Returns the last index used in the registrants list This allows to retrieve all the registrants
getRegistrantAtIndex(uint256 index)
Returns the address and URI of a registrant at a specific index
getReferencesList(address registrantAddress)
Returns an array of references for a given registrant
reference additional status
- 5 contract compromised, should not be used This may be required in some jurisdictions where every hack must be reported to users.
Rationale
Authorities, mostly regulators today, maintain lists of authorized operators on the web. Operators maintain list of their main smart contracts on their own website. On-chain maintenance may exist but without standardization and there is no mechanism linking both practice.
The conflicting requirements of having a distributed management of the smart-contract list by the operator themselves while maintaining a high level of trust led us to implement 2 kind of actors and 2 level of trust. The recognized authority gives the overall trust to the contract it administers through the vetting it imposes to the registrants. Each of the registrants gives the trust to the smart-contrats (called "references") it manages. The distributed management is therefore among the registrants.
Through the URI-contract address cross linking, we anchor the actors blockchain addresses to the web domain names. The latter authenticated by the domain certificates thus maximizing anchorage with real-life actors.
Administration Considerations
The deploying recognized authority needs to have an administrative off-chain process for organizations to apply and be vetted as registrants, as well as maintain the vetted registrant status. The registrant list must be updated accordingly, possibly disabling registrants at some point when they no longer match the vetting requirements. This off-chain administrative due diligence seems to be unavoidable, the alternative would be a system of confidence votes given by the users themselves. We have found that going through a recognized authority would avoid vote manipulations and therefore give more certainty to the users.
Each registrant organization is then sole responsible of its own references (contract addresses), this includes keeping each URI alive with user oriented information, keeping the version number and status updated to reflect the state of its publicly reachable contracts addresses. This distributed organization reduces administrative burden of maintaining the addresses on the recognized authority.
Reference Implementation
Security Considerations
URI cross references
recognized authority URI
When consulting the recognized authority URI, the data served should contain the address of the ERC-8095 contract as meta-data in machine readable format and possibly in human readable format. The purpose of this cross reference is to avoid a rogue contract claiming having been issued by a recognized authority. example of cross reference data: X-Blockchain-Addresses: {"1": "0x1234567890abcdef1234567890abcdef12345678", "56": "0xabcdef1234567890abcdef1234567890abcdef12"} Addresses are indexed by their EIP-155 chainIDs To avoid rogue deployments on newer blockchains, addresses from all blockchain IDs must be enumerated even if the contract is deployed at the same address on every blockchain known to the recognized authority. In order to prevent alteration, the URI is supplied at contract deployment time to the solidity constructor and cannot be changed later.
registrant URI
When consulting the registrant URI, the data served at the URI should contain the address of the registrant as meta-data such as X-Blockchain-Address: "0x1234567890abcdef1234567890abcdef12345678"
reference owner
The declaring registrant of a reference may be coerced by the createReference function to also be the owner of the reference. When needed, this extra check ensures that only contracts that are controlled by the registrant can be listed. Note that this also prevents registrants to declare "friendly" contracts that are not theirs as references.
In case of loss or compromise of keys corresponding the addresses used
There are several cases to be considered depending of the nature of the address
- If the address is a smart-contract (reference): the registrant declares it end-of-life or compromised and deploys a replacement contract at a new address
- if the address is a registrant (management) address: The registrant unlinks the address cross referenced in its URI, rendering the address invalid because it will fail the cross reference check. The registrant needs to ask for a new management address to be added by the recognized authority. It is up to the recognized authority to inspect (or not) the internal processes of the registrant which have led to such loss or compromise and to vet again (or not) the registrant and allow the addition of a new address in the list of registrants.
- if the address is the recognized authority one.
- If it is a loss and the optional provision of 2 (or more) _parentAddress has been implemented, then use the other _parentAddress to operate the contract and replace the lost _parentAddress.
- If it is a compromise or a non recoverable loss: as with the registrant, it needs to unlink the address cross referenced in its URI, this voids the verification of the cross-references and renders the contract address unusable for the authentication mechanisms. The recognized authority has to redeploy the contract, repopulate it with the existing registrant addresses which are still valid, publicize the new address to all registrants and users. Notice that if registrants and users tools go through the (new) address cross-references through the URI of the recognized authority, they do not have to reissue the tools.
Copyright
Copyright and related rights waived via CC0.
