🚀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! 🚀
Top comments (2)
Hey, wish you good luck on your Solidity journey!
Notice that a smart contract can also receive ETH by using the
receive() external payable {}
, but still a good practice to have a proper name function asdeposit()
in your implementation.I would recommend you to take a look at foundry to write your test in Solidity, instead of switching to typescript, but maybe you are proficient in typescript.
All the best!
I'm having some difficulties on finding good solidity posts... this is one is very good!