ERC-5289 Ethereum notarization interface (Ethereum Notary Interface)

Review · Signatures & auth · created 2022-07-16

A standard that lets a smart contract provide a link pointing to a legal document and record a user's signature history on-chain, adding legal binding force to the use of the contract.

Why it is needed

A smart contract executes as code, but that alone does not make it a legally binding contract. The original text uses NFTs as an example. NFTs are often known as a means of holding and proving copyright, but in reality this is rarely the case. Most NFTs have no legal meaning whatsoever, and even in the rare cases where they do, they only grant limited usage permission to the initial holder, without passing any permission on to subsequent holders. This standard aims to create direct contractual privity between a contract's users and a legal document, by having the contract provide an immutable link to the legal document and verify and record whether and when a user has signed that document. However, the original authors state that they are not lawyers and that this proposal is not legal advice.

What to implement

In depth

Legal document library interface

IERC5289Library inherits from ERC-165. legalDocument(uint16 documentId) returns an immutable link to the legal document; IPFS hosting is RECOMMENDED, and a common file format such as PDF, HTML, TeX, or Markdown MUST be used. documentSigned(address user, uint16 documentId) returns whether a signature exists, and documentSignedAt returns the signing time as a uint64. If the user has not signed, the timestamp returned by documentSignedAt may be any value, so documentSigned must be checked first to confirm whether a signature exists. signDocument(address signer, uint16 documentId) must be verified by the contract and must either emit a DocumentSigned event or fail (throw).

Requesting a signature via an ERC-5568 signal

To require a signature on a specific document, the contract reverts with an ERC-5568 signal. The signal's instruction_data is an ABI-encoded (address, uint16) pair, where address is the library address and uint16 is the document's documentId. The original text shows an example of the form throw WalletSignal24(0, 5289, abi.encode(library address, 12345)). In other words, the transaction is deliberately made to fail, and the failure data carries information to the wallet about which document needs to be signed.

Behavior required of the wallet

A wallet that receives a signature request MUST call legalDocument to fetch the document, display that document to the user, and then present a screen asking the user to sign or cancel. If the user agrees, the wallet MUST call signDocument. An implementation that processes the signature without displaying the document does not conform to the standard.

Rationale behind the types and design choices

uint64 was chosen as the return type for the signing time because a 64-bit time register is standard. uint16 was chosen for the document ID because 65,536 documents are likely sufficient for any use case; if not enough, the contract can simply be redeployed. The reason signDocument does not take an ECDSA signature as an argument is for future compatibility with account abstraction, and if needed, this functionality can be added by a later extension. IPFS was made mandatory because it can prove the authenticity of the signed document.

A proposal in Review stage, and not legal advice

The status of this proposal is Review, meaning it has not yet been finalized and its content may change. Also, the original authors explicitly state that they are not lawyers and that this proposal is not legal advice. It should be read with the understanding that actual legal effect may vary depending on the laws of each jurisdiction.

Things to watch out for

Original ERC · ← ERCs