Before I explain what ERC1271 is used for, I will explain why this standard is needed.
Some dapps require you to sign a specific message to logging. Usually something like this:
It is needed because the dapp needs to know that the user trying to logging into the dapp is an authorized agent. A typical application usually uses a User-Password system to check if you are allowed. Still, this concept on web3 is optional because we already have a wallet that stores our private key, and this is all we need. In web3, we use cryptographic signatures to check that you can access a private key without revealing it. Im not going to explain in this article the cryptography behind blockchain. I only want to put it in context before explaining the ERC1271 standard.
If your account is an EOA (Externally owned account), there is no problem with signing a message to logging because you know the private key of your account. The problem is when you try to logging with a smart contract. Imagine that a DAO or a company using a multi-sig contract wants to use a dapp that requires you to sign a message to logging. The problem here is that nobody knows which is the private key of a smart contract because the address of a smart contract is not generated from a known private key like the EOA. The smart contract address is generated using the sender address and the sender's nonce of the transaction in which the smart contract is created. So since the smart contract private key is impossible to know, you cannot sign messages. For this reason, we need a way to check if a smart contract authorizes a signature.
To solve this problem, the Ethereum community has created the ERC1271 standard. This standard allows checking if a signature is valid to use in the name of a smart contract.
Now, We understand why this standard is needed. Now, I'm going to explain how to implement it to be able to sign messages in the name of your smart contract. It's essential to understand that you never will be able to sign with your smart contract account. Only we will create a system to delegate the signature to another account in the name of your smart contract.
The ERC1271 standard requires that your smart contract implement this interface:
interface ERC1271 {
function isValidSignature(
bytes32 _hash,
bytes memory _signature)
external
view
returns (bytes4);
}
You can see that this interface has only a function with the name isValidSignature
. The function receives two parameters:
bytes32: The hash (keccak256) of the message signed.
bytes: The signature of the message. It has a length of 65 bytes.
isValidSignature
function always returns a type bytes4
. It is established in the standard that in case of success, the function must return the value 0x1626ba7e
(This is not a random value. It is the signature of the function isValidSignature(bytes32,bytes)
).
An example of implementation would be:
function isValidSignature(
bytes32 _hash,
bytes calldata _signature
) external override view returns (bytes4) {
// Omitted the implementation of recoverSigner
if (recoverSigner(_hash, _signature) == owner) {
return 0x1626ba7e;
} else {
return 0xffffffff;
}
}
In this example, the contract would respond with success if the signature signer is the smart contract's owner, but we could define any other logic. For instance, for a multi-sig, we could create a method that requires that the signature have to be approved by several members of the multi-sig. There are many examples of possible implementations. The only requisite is that the smart contract implements the method isValidSignature
, which returns 0x1626ba7e
in case of success.
Now, I'm going to share how it would be the sequence to logging into a dapp with a smart contract using the ERC1271 standard:
In summary, we can sign in the name of a smart contract using this standard. It is very useful if you have a DAO, multi-sig, or something similar, and for example, you want to logging into a dapp using the smart contract.
I hope that this article has been helpful for you and now you can understand what this standard is used for and how to implement it.