DEV Community

yo yo ben zhou
yo yo ben zhou

Posted on • Edited on

Solidity Learning Journey:  Deploying and Testing a Smart Contract

🚀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");
}
Enter fullscreen mode Exit fullscreen mode

❌ 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;
Enter fullscreen mode Exit fullscreen mode

I could just let Solidity handle the math and use

payable(msg.sender).transfer(amount);
Enter fullscreen mode Exit fullscreen mode

💡 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
Enter fullscreen mode Exit fullscreen mode

💡 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);
Enter fullscreen mode Exit fullscreen mode

You write:

event Deposit(address indexed sender, uint amount);
emit Deposit(msg.sender, msg.value);
Enter fullscreen mode Exit fullscreen mode

💡 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)

Collapse
 
regisgraptin profile image
Régis

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 as deposit() 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!

Collapse
 
miguelrferreiraf profile image
Miguel Ferreira

I'm having some difficulties on finding good solidity posts... this is one is very good!