Metamask: React dapp using same previous account(from ganache) even though changed in metamask

Metamask issue: stuck in previous account even after switching

As a developer building a React dapp, interacting with Ethereum contracts hosted on the native Ganache blockchain is a common challenge. One such issue that has plagued many developers is the ability to switch between different MetaMask accounts while still accessing previously accessed features and resources.

In this article, we will explore why this happens and how to fix it.

Problem:

When you create a new account using Metamask, the Ethereum wallet app creates a new account with an initial balance of 0 Ether (ETH) and no transactions. However, if you have already interacted with the contract or accessed funds in another account, this interaction will continue even after switching to the new account.

For example, if you deployed an ERC-20 token using the Ganache Solidity compiler and then switched to a different wallet, but still have the same contract deployed, interacting with it through your React dapp code will result in errors or unexpected events. behavior due to the persistent state of the contract.

Solution:

To resolve this issue, we will explore two solutions:

  • Using eth.accounts instead of switching accounts: Instead of switching between accounts using the MetaMask account selector function, we can take a more modern approach using the ‘eth.accounts’ object.
  • Setting up a separate contract and storage for each wallet

    : We will create a separate contract instance with the same function signature but different storage locations to avoid conflicts when switching between wallets.

1. solution: use eth.accounts instead of switching accounts

In your React dapp, you might be using something like this:

import {connect} from 'react-redux';

import { getAccount, interactWithContract } from './actions';

const mapStateToProps = state => {

return {

account: getAccount(state)

};

};

const mapDispatchToProps = dispatch => {

return {

interactWithContract: (contractAddress, args) => dispatch(interactWithContract(contractAddress, args))

}

};

export defaultConnection(mapStateToProps, mapDispatchToProps) (App);

In this example, “getAccount” returns the current Ethereum account ID. Since we are using a single contract instance and passing it to interactWithContract, changes to the account will affect all interactions.

2. solution: use a separate contract and storage for each wallet

Here is an updated example that separates the contract and storage:

// contracts/MyContract.sol

pragma hardness ^0,6,0;

contract MyContract {

// ... contract execution ...

mapping(address => uint256) state balances;

}

// app.js (React dapp)

import React from 'react';

import {connect} from 'react-redux';

const mapStateToProps = state => {

return {

balance: state.balance

};

};

const mapDispatchToProps = dispatch => {

return {

updateBalance: (newBalance) => dispatch(updateBalance(newBalance))

}

};

export defaultConnection(mapStateToProps, mapDispatchToProps) (App);

In this example, we are using a contract “My Contract” with a separate storage for each wallet. When switching between wallets, you will need to create a new contract instance and update its storage.

Conclusion:

To solve the problem of interacting with previously accessed functions and assets across different Ethereum accounts in a React dapp, try using “eth.accounts” instead of switching accounts or setting up separate contracts and storage for each wallet. This approach will allow you to maintain consistent state across different wallets while accessing functions and assets from other wallets.

Leave a Comment

Your email address will not be published. Required fields are marked *

Open chat
Hello 👋
Can we help you?