VelvetShark

ERC-1271 - Now smart contracts can sign transactions too!

Published on

Artist signatures

This article is part of a "30 Days with Ethereum Standards" series. To see the first article in the series and to understand why the standards matter, check the initial article: 30 Days with Ethereum Standards.

ERC-1271: Standard Signature Validation Method for Contracts

Standard way to verify a signature when the account is a smart contract

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.


What ERC-1271 is about

ERC-1271 provides a standard way for smart contracts to verify signatures made on their behalf. Before ERC-1271, only Externally Owned Accounts (EOAs) could sign messages with their private keys, but contracts could not.

With ERC-1271, contracts can implement an isValidSignature(hash, signature) function that takes in a message hash and signature bytes, and returns a magic value of 0x1626ba7e if the signature is valid. This allows contracts to define their own custom logic for what constitutes a valid signature.

Interesting trivia: Why the magic value 0x1626ba7e? It's a keccak256 hash of the string isValidSignature(bytes32,bytes) and serves as a unique value that is unlikely to be returned by any other function, making it a good choice for signaling a valid signature. If the return value were true or false, it could conflict with other functions that return boolean values, e.g. a fallback function.

Why it is important

ERC-1271 is crucial for enabling smart contract wallets to sign messages and transactions. Smart contract wallets need a way to prove a signature came from them, similar to how EOAs sign with their private key. Smart contracts don't have private keys though, and will never have them, due to the open nature of the blockchain. ERC-1271 provides a way for contracts to verify signatures without needing a private key.

ERC-1271 also allows for more advanced signature schemes beyond ECDSA signatures from a single private key. Multisig, social recovery, and other complex signing logic can be implemented. This opens up plenty of possibilities for smart contract wallets.

ERC-1271 is key for any applications that use signed messages to authenticate users or authorize actions. For example, it enables smart contract wallets to use the Sign-In With Ethereum (SIWE) standard to login to websites. It's also needed for signing off-chain orders on DEXes. Some decentralized exchanges use an off-chain order book to collect signed messages before they become orders, allowing for additional optimizations. In order for smart contracts to be able to trade using these systems, they need ERC-1271 to validate signatures.

Use cases

Some key use cases of ERC-1271 include:

  • Allowing smart contract multisig wallets like Gnosis Safe to sign and verify signatures for transactions
  • Enabling smart contract wallets to use Sign-In With Ethereum (SIWE) to authenticate and login users to websites and apps
  • Signing off-chain orders for DEXes that use an off-chain orderbook
  • Implementing advanced signature schemes like multisig, social recovery, and delegated signing

Drawbacks

While ERC-1271 provides a needed standard for smart contract signature verification, it does introduce some additional complexity compared to EOA signatures:

To determine if a signature should be verified with ERC-1271 or as an EOA, it's necessary to first check if the signing address is a contract by seeing if any code exists at that address. If code exists, then ERC-1271 verification is used by calling the isValidSignature function. If no code exists, then it's assumed to be an EOA signature.

This contract code check requires an extra RPC call, and overall doubles the number of RPC calls needed for signature verification (one to check for code, one to call isValidSignature if code exists). This adds some overhead.

There have been some attempts to solve this like CAIP-74 which propose annotating signatures with a type so it's clear if it should be verified with ERC-1271 or as an EOA without needing to check for contract code. However, these solutions are not yet widely adopted, not backwards compatible with existing systems using signatures, and still require supporting both ERC-1271 and EOA verification logic.

So while ERC-1271 is an important standard, it does introduce some additional complexity and overhead to the signature verification process compared to EOAs. There are additinoal EIPs trying to address this issue, for example ERC-6492. I'll have a separate article focusing just on ERC-6492. Stay tuned!

Resources