Search code examples
reactjsweb3js

Problems with web3.js sign message method, simple react example


I wanted to create a simple page with react with two button, one to sign a message with a wallet and then another button to verify if signature is valid... My problem is that the address i receive in verifyMessage is not the address I signed with, what am I doing wrong?

Here my code:


import './App.css';
import Web3 from "web3/dist/web3.min.js"
import React, { useState, useEffect } from 'react';

function App() {
  const [address, setAddress] = useState('');
  const [message, setMessage] = useState('ciao');
  const [signature, setSignature] = useState('');
  const [isValid, setIsValid] = useState(false);
  const [web3, setWeb3] = useState(null);

  useEffect(() => {
    async function getWeb3() {
      if (window.ethereum) {
        const web3 = new Web3(window.ethereum);
        await window.ethereum.enable();
        const accounts = await web3.eth.getAccounts();
        setAddress(accounts[0]);
        setWeb3(web3);
      }
    }
    getWeb3();
  }, []);

  const signMessage = async () => {
    const messageHash = web3.utils.sha3(message);
    const signature = await web3.eth.sign(messageHash, address);
    setSignature(signature);
  };

  const verifyMessage = async () => {
    const messageHex = web3.utils.utf8ToHex(message);
    const messageHash = web3.utils.sha3(messageHex);
    const signer = await web3.eth.accounts.recover(messageHash, signature);
    console.log(signer)
    if (signer == address) {
      setIsValid(true);
      console.log("yes")
    }
  };

  return (
    <div className="App">
      <header className="App-header">
        <p>Sign Message: {message}</p>
        <button onClick={signMessage}>Sign</button>
        <p>Signature: {signature}</p>
        <button onClick={verifyMessage}>Verify</button>
        <p>Is Valid: {isValid ? 'True' : 'False'}</p>
      </header>
    </div>
  );
}

export default App;


Solution

  • You are setting the public address of your wallet account setAddress(accounts[0]); According to web3js documentation, this address will be a private key

    If you provide your accounts private key there, then you will get the same address you have signed with.