BC2: Keys and digital signatures
Signing and verifying
๐ฏYou'll be able to
Sign a message, verify a signature, and say exactly what a valid signature proves.
๐ The everyday picture
A wax seal pressed with a signet ring: anyone who knows the ring's pattern can check the seal, but only the ring's owner can make it.
๐What it really is
- Signing: the signer hashes the message and uses the private key to produce a signature (on Ethereum, 65 bytes: r, s and v).
-
Verifying: anyone with the message, the signature and the public key (or address) can check it. On Ethereum,
ecrecoverworks out the signer's address from the hash and signature, and the code compares it with the expected address. -
What it proves: the holder of that private key approved those exact bytes. Change one byte and the signature no longer matches.
-
What it doesn't prove: that the holder understood what they signed, that they signed it today, or that the message is meant for this place. Those need the message itself to say so (Lesson 4).
-
Off-chain signatures: signing costs nothing and needs no network. A contract can accept signed approvals collected elsewhere (Project 2).
๐A worked example
Input: M01 signs "Approve payment of 0.2 to M04".
Steps:
- M01's wallet hashes the message and signs it.
- The treasurer receives the message and signature, and recovers the signer's address with ethers'
verifyMessage. - It matches M01's address, so the treasurer knows M01's key approved this exact text.
- If someone changes "0.2" to "2.0", the recovered address is a different, random one, and the check fails.
Expected output: a check that passes only for M01's key and the exact message.
๐Where it's used
- Every Ethereum transaction.
- Sign-in with a wallet (EIP-4361).
- Permit-style approvals for tokens, signed off-chain.
๐Case scenario
A team checked that ecrecover returned "an owner" but forgot that it returns the zero address for a broken signature, and the zero
address had been set as an owner by mistake. Anyone could send garbage signatures and pass. The fix: refuse the zero address as an
owner and as a recovered signer.
๐ฑ๏ธTry it
With ethers in the kit folder, sign a message with a random wallet and verify it, then change one character and verify again. Success: the first check returns the wallet's address and the second returns a different one.
โ ๏ธCommon mistakes
- Not comparing with the expected address. Sign: "a signature was present" counted as approval. Fix: check who signed.
- Accepting the zero address. Sign: broken signatures pass. Fix: reject it.
- Signing unclear text. Sign: users approve hex they can't read. Fix: typed, readable messages (Lesson 4).
๐ ๏ธFor your project
Project 2's executeWithSignatures recovers each signer and checks they're an owner (tests 8 and 9).
โ Quick check
What does a valid signature prove?
Show the answer
That the holder of the private key approved those exact bytes.
What does ecrecover return for a broken signature?
Show the answer
The zero address, which must be refused.
