ICE 4 – Deploy with MetaMask (Remix → Ganache)

Goal: use MetaMask (connected to Ganache) as the signer in Remix to deploy and interact with a contract. Then test with a tiny HTML/JS page via ethers.js.

0) Prereqs

1) Contract

Create SimpleStorage.sol in Remix:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private storedData;
event ValueChanged(uint256 oldValue, uint256 newValue, address setter);
function set(uint256 x) public {
uint256 oldVal = storedData; storedData = x;
emit ValueChanged(oldVal, x, msg.sender);
}
function get() public view returns (uint256) { return storedData; }
}

2) Compile

  1. Open remix.ethereum.org.
  2. Solidity Compiler → select any 0.8.x version → click Compile SimpleStorage.sol (green check appears).

3) Deploy with Injected Provider – MetaMask

  1. Go to Deploy & Run Transactions (plug/ETH icon).
  2. Environment → choose Injected Provider – MetaMask.
  3. MetaMask popup: choose your funded Ganache account → NextConnect.
  4. Ensure the account shows a non‑zero balance and network label says Localhost/Ganache.
  5. Select SimpleStorage in the Contract dropdown → click Deploy.
  6. MetaMask pops up → review gas → Confirm.
  7. Under Deployed Contracts, expand the instance. Call get()0. Call set(123) → Confirm → get()123.

Open Remix’s bottom terminal and click the tx to see the ValueChanged event log.

Gas estimation failed? Fund the selected account (import from Ganache) and confirm the network is your Localhost.

4) Grab ABI + Address

  1. In Remix, after deploy, copy the contract address from the Deployed Contracts header.
  2. In Solidity Compiler → Compilation Details, copy the ABI (JSON array).

5) Minimal HTML/JS frontend (ethers.js)

Save this as simple_storage_frontend.html, then fill in your address and ABI from step 4.

<!DOCTYPE html>
<html><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>SimpleStorage Frontend</title></head>
<body>
<button id="connect">Connect MetaMask</button>
<div>
Address: <input id="addr" style="width:360px" value="PASTE_CONTRACT_ADDRESS"/>
</div>
<div>
ABI:<br/>
<textarea id="abi" rows="6" style="width:100%">PASTE_ABI_JSON_ARRAY</textarea>
</div>
<div>
<button id="get">get()</button> <span id="out"></span>
</div>
<div>
<input id="val" type="number" placeholder="value"/>
<button id="set">set(x)</button> <span id="status"></span>
</div>
<script src="https://cdn.jsdelivr.net/npm/ethers@6.13.2/dist/ethers.min.js"></script>
<script>
let provider, signer, c;
async function mk(){
const addr=document.getElementById('addr').value.trim();
const abi=JSON.parse(document.getElementById('abi').value.trim());
c=new ethers.Contract(addr, abi, signer);
}
document.getElementById('connect').onclick=async()=>{
if(!window.ethereum){ alert('MetaMask not found'); return; }
provider=new ethers.BrowserProvider(window.ethereum);
await provider.send('eth_requestAccounts', []);
signer=await provider.getSigner();
await mk();
};
document.getElementById('get').onclick=async()=>{
if(!c) await mk();
const v=await c.get(); document.getElementById('out').textContent=v.toString();
};
document.getElementById('set').onclick=async()=>{
if(!c) await mk();
const x=document.getElementById('val').value; if(x===''){alert('enter a number');return}
const tx=await c.set(ethers.toBigInt(x));
document.getElementById('status').textContent='Pending '+tx.hash;
const rc=await tx.wait();
document.getElementById('status').textContent='Mined in block '+rc.blockNumber;
};
</script>
</body></html>

Keep MetaMask on your Ganache network so calls go to localhost.

Submission

  • Screenshot: MetaMask on Localhost with funded account.
  • Screenshot: Remix (Injected Provider) and successful set(123) + get().
  • Screenshot: Frontend page showing get() and a mined set() tx.

Troubleshooting

  • Provider missing: Install/enable MetaMask; refresh page.
  • Gas estimation failed: Fund account; check Injected Provider network.
  • ABI errors: Ensure the ABI textarea contains a valid JSON array from Remix.
  • Wrong address: Use the deployed address from step 4 (not the account address).

Next: ICE 5 – Tokens (ERC‑20 or ERC‑721) using OpenZeppelin and Hardhat/Foundry.