I'm aware I could tell which wallet address is calling the contract and whitelist certain addresses. But how could I instead make a contract that can only be used by people who hold a certain secret key? I was thinking of a standard hashed password mechanism but with something to protect against replay attacks, since everything on-chain is publicly visible. Searching around, I found this article using that for a secrets store, and here's the code.
- I generate a secret and pass it out.
- User hashes their secret with a nonce the contract stores.
- User calls contract method with the hash and whatever other params.
- Contract increments nonce so the hash can't be reused.
But what happens if the method call fails? Won't everyone (or at least some node operators) see the failed call with its params and be able to reuse the hash from it, since the contract's nonce never got incremented?
Edit: Oh, the caller could just include the wallet address in the hash so nobody else can use that hash. Though I'm still curious about whether or not there's a vulnerability in the original solution.