🚀Previously in My Journey…
In my previous post, I shared why I'm transitioning from SDET to Smart Contract Engineer. I talked about my fascination with Bitcoin's whitepaper, Ethereum's smart contracts, and the revolutionary potential of Web3.
But motivation alone isn't enough - you have to put in the work.
Today, I'm diving into Solidity for the first time, writing, deploying, and testing my first smart contract.
🎯The Plan: A Simple Ethereum Bank
For my first Solidity project, I decided to build a basic Ethereum bank - a contract where users can:
- 🏦 Deposit ETH into the contract.
- 💸 Withdraw ETH from the contract.
- 📊 Keep track of balances (but let Solidity handle the math). Sounds simple, right? Well, things got complicated fast.
🛑 Solidity's First Surprise: Depositing ETH Works Differently Than I Thought
Coming from traditional programming, I assumed I needed a function like this:
function deposit(uint amount) public payable {
require(amount > 0, "Deposit must be greater than zero");
}
❌ WRONG Solidity doesn't work like that.The ETH amount is automatically included in msg.value
, so no need to pass amount
explicitly. A function just needs the payable
modifier to receive ETH.
💡 LESSON:Solidity handles ETH transfers at the transaction level, not as function parameters.
💰 Withdrawals and Solidity's Automatic Balance Tracking
Next, I worked on withdrawals, assuming I needed a balance variable. But Solidity already tracks contract balances internally using address(this).balance.
So, instead of:
uint public balance;
balance -= amount;
I could just let Solidity handle the math and use
payable(msg.sender).transfer(amount);
💡 LESSON: Solidity is smarter than I thought. You don't need to track balances manually - the blockchain does it for you.
🛠️ Deploying and Testing in Hardhat: "Why Isn't My Contract Deploying?"
I decided to deploy my contract using Hardhat. I wrote a deploy.js script, but then realized:
❌ WRONG. Hardhat tests don't actually use deploy.js
.
✅ RIGHT Each test runs on a fresh blockchain state, deploying dynamically.
Still, I ran into errors like:
❌ HH606: Solidity version mismatch
→ Fixed by updating hardhat.config.js
to include solidity version inside.
❌ "Cannot find module 'dotenv'"
→ Installed missing package (dotenv
).
❌ Hardhat compilation issues
→ Fixed by running:
npx hardhat clean npx hardhat compile
💡 LESSON: Hardhat automates a lot, but you have to configure Solidity versions correctly to avoid mismatches.
🔥 The Magic of Indexed Events in Solidity
Solidity lets you log transactions with events, which I thought were just for debugging. ❌ WRONG.
✅ Events actually live on the blockchain and make transaction searches super efficient.
For example:
event Deposit(address indexed sender, uint amount);
Indexed parameters make searching logs faster.
Why not use msg.sender
directly? Solidity doesn't allow direct global variables in event definitions.
So instead of:
event Deposit(msg.sender, msg.value);
You write:
event Deposit(address indexed sender, uint amount);
emit Deposit(msg.sender, msg.value);
💡 LESSON: Events aren't just console logs - they are part of the Ethereum blockchain history.
🔑 Key Takeaways from Day 1
✅ Solidity has built-in ETH balance tracking - no need for manual balance variables.
✅ payable functions automatically receive ETH without an explicit amount parameter.
✅ Hardhat automates testing but requires careful Solidity version configuration.
✅ Events are stored on-chain and indexed makes them searchable.
** 🚀 Next Steps & Future Improvements**
🔹 Add multi-user banking using mapping(address => uint) balances.
🔹 Implement admin-only withdrawals for full contract balance management.
🔹 Deploy SingleUserBank on a public Ethereum testnet.
🔹 Explore gas optimizations and smart contract security best practices.
🌍 Join Me on This Journey!
If you're also learning Solidity, Smart Contracts, or blockchain development, let's connect!
📌GitHub: https://github.com/benzdriver
📌LinkedIn: https://www.linkedin.com/in/ziyan-zhou/
💡 Let’s build the future of blockchain together! 🚀