Skip to content

Instantly share code, notes, and snippets.

@Jropp
Last active November 2, 2023 17:03
Show Gist options
  • Save Jropp/fc06739697cafcdf0134c220462fe4fe to your computer and use it in GitHub Desktop.
Save Jropp/fc06739697cafcdf0134c220462fe4fe to your computer and use it in GitHub Desktop.
How to associate a user with a wallet

Overview

In order to associate a web2 user account with a Web3 wallet, we need a way for the database to provide a challenge that the web2 user must answer via web3.

Here is my very simple solution.

  1. Api creates a unique nonce to an authorized user who has provided an EVM wallet address. This hash is stored with an expiration in the Db and returned to the client.
  2. The client immediately initiates a transaction for the user to sign with the nonce as an argument to the smart contract function. This is sent to the WalletAssociation smart contract address.
  3. The code packages the nonce with msg.sender and emits an event.

Here is the contract in its entirety:

pragma solidity ^0.8.0;

// Contract to handle user registration and challenge answer
contract WalletAssociation {
    event E(address indexed userWallet, uint256 answer, uint256 timestamp);
    function a(string memory answer) public {
        emit E(msg.sender, answer, block.timestamp);
    }
}
  1. The indexer gathers the event and sends it to the backend to complete the handshake, checking the nonce address combination and validating the wallet for the user.
@Jropp
Copy link
Author

Jropp commented Oct 25, 2023

@Madgeniusblink depends on how you are defining on chain record, but no I’m not trying to store a value in the contract, just passing it through.

The emission of the event with msg.sender and the nonce is all the web2 db needs to know that the user that submitted the wallet address to web2 in fact has control of that wallet.

@Madgeniusblink
Copy link

Madgeniusblink commented Oct 27, 2023

What do you think about this @Jropp ?

Dhiraj and I used this method in the past to associate it.

Challenge-Response Mechanism:

Generating the Challenge:

  1. When a user wants to link their Web2 account to a Web3 wallet, the Web2 backend generates a unique "challenge" (a nonce or a random string).
  2. This challenge is sent to the user's client.

User Responds to Challenge:

  1. The user's client prompts the user to sign this challenge using their Web3 wallet.
  2. This doesn't initiate any transaction on the blockchain; it just produces a digital signature.
  3. The user's client sends back the signature to the Web2 backend.

Verifying the Response:

  1. The Web2 backend verifies the signature against the user's provided Polygon wallet address.
  2. If the signature is valid, it means the user has proven ownership of the wallet. The backend can then associate the Web2 account with the Web3 wallet.

Some of the benefits:

  1. Simplicity: The process is straightforward and doesn't involve deploying or interacting with smart contracts.
  2. Speed: Verification can be done quickly since it doesn't rely on block confirmation times.

the one downside is that this method relies on trusting the Web2 backend for verification, unlike the on-chain method you suggested where the verification is trustless and based on blockchain consensus.

@Jropp
Copy link
Author

Jropp commented Oct 27, 2023

@Madgeniusblink are there any other potential exploits with this approach that would have to be accounted for?

@Madgeniusblink
Copy link

If planned out properly and properly executed there wouldn't be many but there are always risk.

below are some risk:

Replay Attacks: If an attacker captures a valid signed challenge-response, they might try to replay it to the server to impersonate the user. To mitigate this we could do the following:

  • Ensure challenges (nonces) are used only once.
  • Set a short expiration time for the challenge.

Man-in-the-Middle Attacks (MitM): An attacker could intercept and modify traffic between the user and the server. To mitigate this we could do the following:

  • Always use HTTPS for communications.
  • Implement proper certificate pinning on client applications if possible.

Phishing: An attacker might trick users into signing malicious payloads or redirecting them to fake sites. To counter this:

  • Educate users about the risks of phishing.
  • Use recognizable patterns or messages when asking users to sign a challenge so they can distinguish genuine requests from malicious ones.

Storage of Signed Challenges: If signed challenges are stored insecurely, they could be stolen and used maliciously. To mitigate this:

  • Store them securely, encrypted, and for only as long as necessary.
  • Once verified, discard the signed challenge.

Endpoint Security: The server endpoint that verifies the signed challenge is a potential target. If it's compromised, false associations might be created. To counter this:

  • Ensure robust security on all server endpoints.
  • Regularly monitor and audit endpoint accesses.

Sybil Attacks: A malicious user could try to associate multiple fake or stolen Web2 accounts with their Web3 wallet. To mitigate this:

  • Implement rate limiting.
  • Have additional verification steps for associating accounts.

Reliance on Single Wallet: If a user loses access to their Web3 wallet, they might lose access to their associated Web2 account. To counter this:

  • Allow users to associate multiple wallets or provide backup methods for association.
  • Educate users about wallet backups and security.

There is always wallet vulnerabilities as well..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment