Verifying Solidity Signatures
Processing everything on-chain is great, but not always practical and sometimes you might want to do something a little tricky in order to save users gas.
Sadly, simply passing the desired data to a contract is not secure and without security measures, people will certainly abuse your contract.
There is a nice solution to this issue.
Solidity signatures and signing data
You can bundle desired data into a hash and sign it with the desired wallet.
Below you can see me running a very simple signing on hardhat where I am treating the signer as my backend.
On line #45 you can see I am connecting to the sigTest contract as userWallet and firing off the isDataValid function. Passing in the timestamp and signature. Let's jump over to the contract to see what happens next.
Looking at isDataValid() we can see that the first thing we do is build the hash in the contract, using the same data as we used on the client. The resulting msgHash should be equal to the messageHash on the client. If there is any discrepancy in the data, the hashes won't match and the signature test will fail.
Still looking at isDataValid() you can see that it fires off a require and calls isValidSignature(). Here we have to first sign the hash. It might seem arbitrary to pack in \x19Ethereum Signed Message:\n32, have a good Google to understand the importance of it — its very interesting from a security point of view.
With the data signed we can utilize the ECDSA library to recover an address bashed on the has and signature.
If the recovered address matches the systemAddress, all is well and we consider that a success, else, fail.
I won't go into how the ECDSA library works as I believe it's important for developers to learn how to read other contracts and Google around to fill in knowledge gaps, plus I don't wanna ruin the fun :)
openzeppelin-contracts/ECDSA.sol at master · OpenZeppelin/openzeppelin-contracts
OpenZeppelin Contracts is a library for secure smart contract development. - openzeppelin-contracts/ECDSA.sol at master…
The code I have provided is in no way production-ready. It was written extremely fast and with no testing.
Tracking nonces is a nice feature you should look into adding to this code. It helps avoid replay attacks.