Skip to content

Instantly share code, notes, and snippets.

@PhilippLgh
Last active May 11, 2021 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhilippLgh/88fd0357eb5e5e3aa02828c148a7b8fd to your computer and use it in GitHub Desktop.
Save PhilippLgh/88fd0357eb5e5e3aa02828c148a7b8fd to your computer and use it in GitHub Desktop.
Password Verification on Ethereum

Secure Password Verification on Ethereum Blockchain

const { BrainWallet } = require("@ethersproject/experimental");
const createKey = async (password, progressCallback = () => { }) => {
let project = "Rise of the Shadow Monkey"
const brainWallet = BrainWallet.generate(project, password, progressCallback);
return brainWallet
}
const tryUserPassword = async (answer) => {
// construct signer from answer
const signer = await createKey(answer)
// read key from smart contract
const key = await contract.key()
if (signer.address == key) {
// found password - can claim now like this:
// return claimTreasure(answer)
} else {
// wrong answer
}
}
export const claimTreasure = async (password) => {
const treasure = await getTreasureContract()
const address = await getUserAddress()
const key = await createKey(password)
const signer = new ethers.utils.SigningKey(key.privateKey)
const digest = await treasure.getMessage(address)
const signatureRaw = signer.signDigest(digest)
const signature = ethers.utils.joinSignature(signatureRaw)
return treasure.mint(signature);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
interface ERC721 {
function mint(address to) public returns (uint256);
}
contract Treasure is Ownable {
using ECDSA for bytes32;
ERC721 public keyContract;
address public key;
function setTokenContract(ERC721 contractAddress) public onlyOwner {
tokenContract = contractAddress;
}
function setKey(address _key) public onlyOwner {
key = _key;
}
function msgSigner(bytes32 hash, bytes memory signature) public pure returns (address) {
return hash.recover(signature);
}
function getMessage(address addr) public pure returns(bytes32) {
bytes32 _msg = keccak256(abi.encodePacked(addr));
return _msg;
}
function mint(bytes memory signature) public returns (uint256) {
// create message
bytes32 _msg = getMessage(msg.sender);
// verify signature
address recovered = msgSigner(_msg, signature);
require(recovered == key, "Bad password");
// mint nft
uint256 tokenId = tokenContract.mint(msg.sender);
return tokenId;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment