ERC-1271: Standard Signature Validation Method for Contracts
Standard way to verify a signature when the account is a smart contract
Why is it important?
Smart Accounts (which are Smart Contracts) can now sign transactions on behalf of a user. In the past, only EOA accounts could this and a user would need to be present to sign the transaction. This will tie in nicely with the concept of session keys (sometimes called permissions), so apps can perform actions on behalf of users (assuming they’ve been granted permission by the user).
Abstract
Externally Owned Accounts (EOA) can sign messages with their associated private keys, but currently contracts cannot. We propose a standard way for any contracts to verify whether a signature on a behalf of a given contract is valid. This is possible via the implementation of a isValidSignature(hash, signature)
function on the signing contract, which can be called to validate a signature.
Motivation
There are and will be many contracts that want to utilize signed messages for validation of rights-to-move assets or other purposes. In order for these contracts to be able to support non Externally Owned Accounts (i.e., contract owners), we need a standard mechanism by which a contract can indicate whether a given signature is valid or not on its behalf.
One example of an application that requires signatures to be provided would be decentralized exchanges with off-chain orderbook, where buy/sell orders are signed messages. In these applications, EOAs sign orders, signaling their desire to buy/sell a given asset and giving explicit permissions to the exchange smart contracts to conclude a trade via a signature. When it comes to contracts however, regular signatures are not possible since contracts do not possess a private key, hence this proposal.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
isValidSignature
can call arbitrary methods to validate a given signature, which could be context dependent (e.g. time based or state based), EOA dependent (e.g. signers authorization level within smart wallet), signature scheme Dependent (e.g. ECDSA, multisig, BLS), etc.
This function should be implemented by contracts which desire to sign messages (e.g. smart contract wallets, DAOs, multisignature wallets, etc.) Applications wanting to support contract signatures should call this method if the signer is a contract.
Rationale
We believe the name of the proposed function to be appropriate considering that an authorized signers providing proper signatures for a given data would see their signature as "valid" by the signing contract. Hence, a signed action message is only valid when the signer is authorized to perform a given action on the behalf of a smart wallet.
Two arguments are provided for simplicity of separating the hash signed from the signature. A bytes32 hash is used instead of the unhashed message for simplicity, since contracts could expect a certain hashing function that is not standard, such as with EIP-712.
isValidSignature()
should not be able to modify states in order to prevent GasToken
minting or similar attack vectors. Again, this is to simplify the implementation surface of the function for better standardization and to allow off-chain contract queries.
The specific return value is expected to be returned instead of a boolean in order to have stricter and simpler verification of a signature.
Backwards Compatibility
This EIP is backward compatible with previous work on signature validation since this method is specific to contract based signatures and not EOA signatures.
Reference Implementation
Example implementation of a signing contract:
Example implementation of a contract calling the isValidSignature() function on an external signing contract ;
Security Considerations
Since there are no gas-limit expected for calling the isValidSignature() function, it is possible that some implementation will consume a large amount of gas. It is therefore important to not hardcode an amount of gas sent when calling this method on an external contract as it could prevent the validation of certain signatures.
Note also that each contract implementing this method is responsible to ensure that the signature passed is indeed valid, otherwise catastrophic outcomes are to be expected.
Copyright
Copyright and related rights waived via CC0.