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

Metamask Issue: Stuck on Previous Account Even After Switching

As a developer building a React dapp, interacting with Ethereum contracts deployed on the local Ganache blockchain is a common challenge. One such issue that has plagued many developers is being able to switch between different accounts in MetaMask while still accessing previously accessed functions and assets.

In this article, we’ll explore why it’s happening and how to resolve it.

The 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’ve already interacted with a contract or accessed assets on another account, those interactions will persist even after switching to a new account.

For example, if you’ve deployed an ERC-20 token using the Solidity compiler in Ganache, 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 behavior due to the persisted state of the contract.

The Solution:

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

To resolve this issue, we’ll explore two solutions:

  • Using eth.accounts instead of changing accounts: Instead of switching between accounts using MetaMask’s account selector feature, we can use a more modern approach by leveraging the eth.accounts object.

  • Setting up a separate contract and storage for each wallet: We’ll create a separate contract instance with the same function signature but different storage locations to avoid conflicts when switching between wallets.

Solution 1: Using eth.accounts instead of changing accounts

In your React dapp, you’re likely 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 default connect(mapStateToProps, mapDispatchToProps)(App);

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

Solution 2: Using separate contract and storage for each wallet

Here’s an updated example that separates the contract and storage:

// contracts/MyContract.sol

pragma solidity ^0.6.0;

contract MyContract {

// ... contract implementation ...

mapping(address => uint256) public 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 default connect(mapStateToProps, mapDispatchToProps)(App);

In this example, we’re using the MyContract contract with separate storage for each wallet. When switching between wallets, you’ll need to create a new instance of the contract and update its storage.

Conclusion:

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

ETHEREUM USING SCRIPTS

Leave a Reply

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