⚡ Ethers.js Simple Storage
A hands-on learning project building, deploying, and interacting with a SimpleStorage smart contract using ethers.js (v5) and the Solidity compiler (solc).
This repo documents my first step from traditional Web2 development toward Web3 / blockchain development — writing Solidity, compiling it, and driving a contract on-chain without a heavyweight framework like Hardhat or Foundry. Just Node.js, ethers.js, and solc.
🧠 What I Learned
This project was built to learn the fundamentals of smart-contract development, one concept at a time:
- ✅ Solidity basics — state variables,
struct,array,mapping,functionvisibility & purity (public,view). - ✅ Compiling Solidity manually with
solcto produce the ABI + bytecode (.abi&.binfiles). - ✅ ethers.js Provider & Wallet — connecting to an RPC endpoint and signing with a raw private key.
- ✅ Deploying a contract via a
ContractFactory(ABI + bytecode + signer). - ✅ Reading & writing the blockchain — calling a state-changing
store()(sends a transaction, waits for confirmation) vs. reading withretrieve()(free, no gas). - ✅ Async JavaScript — the
Promiselifecycle (pending→fulfilled/rejected) that powers all on-chain interaction. - ✅ Environment variables (
dotenv) — keeping secrets out of the code. - ✅ Secure key handling —
encryptKey.jsencrypts a private key into an encrypted JSON keystore (usingPRIVATE_KEY_PASSWORD) for production-style deployment.
🛠️ Tech Stack
| Tool | Purpose |
|---|---|
Solidity 0.8.7 |
Smart contract language |
ethers.js 5.7.2 |
Ethereum/blockchain library (Provider, Wallet, ContractFactory) |
solc 0.8.7 |
Solidity compiler (CLI) |
dotenv |
Environment variables / secrets |
fs-extra |
File system helpers (read ABI / bytecode, write keystore) |
prettier + prettier-plugin-solidity |
Code formatting |
📁 Project Structure
ethers-simple-storage/
├── SimpleStorage.sol # The smart contract
├── simpleStorage_*.abi / .bin # Compiled output (ABI + bytecode)
├── deploy.js # Compile → deploy → read/write on-chain
├── encryptKey.js # Encrypt a private key into a JSON keystore
├── package.json # Dependencies + scripts
└── .env # Local only (git-ignored): RPC_URL, PRIVATE_KEY
🚀 Getting Started
1. Install dependencies
yarn install
2. Set up environment variables
Create a .env file (git-ignored) at the project root:
RPC_URL=<your_ethereum_rpc_endpoint_here>
PRIVATE_KEY=<your_private_key_here> # TEST NETWORK ONLY
PRIVATE_KEY_PASSWORD=<your_keystore_password> # used by encryptKey.js
⚠️ Security note: never commit a real private key. Use a test network (e.g. Sepolia) or a local node (e.g. Ganache at
http://192.168.1.10:7545). For production, prefer an encrypted keystore (see below).
3. Compile the contract
yarn compile
This runs solcjs and generates SimpleStorage_sol_SimpleStorage.abi and .bin in the project root.
4. Deploy & interact
node deploy.js
You'll see the contract address, the current favorite number, then the updated favorite number after calling store(7).
(Optional) Secure key storage
node encryptKey.js
Writes a password-encrypted keystore to .encryptedKey.json (git-ignored). Switch the commented-out code in deploy.js to use it instead of a raw private key.
💡 About the Contract — SimpleStorage
contract SimpleStorage {
uint256 favoriteNumber;
struct People { uint256 favoriteNumber; string name; }
People[] public people;
mapping(string => uint256) public nameToFavoriteNumber;
function store(uint256 _favoriteNumber) public { ... } // write (costs gas)
function retrieve() public view returns (uint256) { ... } // read (free)
function addPerson(string memory _name, uint256 _favoriteNumber) public { ... } // write
}
store()/retrieve()— a state variable you can write and read.addPerson()— demonstrates astructpushed into a dynamicarray, plus amappingfrom name → favorite number (your first taste of more realistic on-chain data patterns).
🗺️ Roadmap / Next Steps
- Refactor to a production structure (separate compile / deploy scripts).
- Try a real framework like Hardhat or Foundry for testing & tooling.
- Add tests (e.g. with Foundry or Chai) to lock in contract behavior.
- Deploy to a real network and verify the contract on a block explorer.
👨💻 About the Author
Hello! I'm Hoelee — a hands-on developer and self-hoster based in Malaysia, currently making the leap from Web2 toward Web3 / blockchain development.
My Web2 background spans PHP/CodeIgniter, Java/Spring, JavaScript/Node.js, and WordPress (Kadence/Elementor) SME sites — and I run my own email hosting business at SifuMail (my projects live at hoelee.com).
I'm building real projects to learn, and I welcome comments, feedback, and contributions. This repo is part of my journey toward on-chain development, and I'm always happy to connect:
- 🌐 Portfolio: https://hoelee.com
- ✉️ Email: [email protected]
- 💬 WhatsApp: 012-797 2969
💼 Open to remote opportunities in Web3 / blockchain development (Solidity, ethers.js, Hardhat/Foundry, smart-contract security) and full-stack web. If you're hiring a self-taught, self-hosted developer who ships and learns fast — I'd love to talk.
📜 License
MIT — free to learn from, fork, and build on.
Built for learning. Simple, honest, and incrementally improved — the same way I approach every new technology.