Posted By : Jagveer
Blockchain technology enables innovative applications like a decentralized "Buy Me a Coffee" service. This guide will walk you through developing and deploying a smart contract development service for this purpose using Alchemy, Hardhat, Ethers.js, and the Ethereum Sepolia testnet. By the end, you'll know how to: Build, test, and deploy smart contracts with Hardhat. Connect MetaMask to Sepolia via an Alchemy RPC endpoint. Obtain Sepolia ETH from a faucet. Interact with the contract using Ethers.js and build a frontend for the application.
Also, Read | Solidity Smart Contract Vulnerabilities and Ways To Mitigate Them
Prerequisites
Before starting, ensure you have:
Step 1: Project Setup 1- Create a new directory and then navigate into it:
mkdir BuyMeACoffee-contracts cd BuyMeACoffee-contracts
2- Initialize a new npm project:
npm init -y
3- Install Hardhat:
npm install --save-dev hardhat
4- Generate a Hardhat project:
npx hardhat
Select "Create a JavaScript project" and agree to the defaults.
5- Verify the setup by running tests:
npx hardhat test
Step 2: Writing the Smart Contract 1. Create the smart contract file: Copy BuyMeACoffee.sol and replace its content with:
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; contract BuyMeACoffee
{
event NewMemo(address indexed from, uint256 timestamp, string name, string message);
struct Memos { address from; uint256 timestamp; string name; string message; }
address payable owner; Memos[] memos;
constructor() { owner = payable(msg.sender); }
function fetchMemosDetails() public view returns (Memos[] memory) { return memos; }
function buyCoffees(string memory _name, string memory _message) public payable {
require(msg.value > 0, "can't buy coffee for free!");
memos.push(Memos(msg.sender, block.timestamp, _name, _message)); emit NewMemo(msg.sender, block.timestamp, _name, _message);
}
function withdrawTips() public {
require(owner.send(address(this).balance));
}
}
Step 3: Testing the Contract 1- Create a test script: Copy buy-coffee.js and use the following code:
const hre = require("hardhat");
async function getBalance(address) {
const balanceBigInt = await hre.ethers.provider.getBalance(address);
return hre.ethers.utils.formatEther(balanceBigInt);
}
async function printBalances(addresses) {
for (const [index, address] of addresses.entries()) {
console.log(Address ${index} balance: ,
await getBalance(address));
}
}
async function printMemos(memos) {
for (const memo of memos) {
console.log(At ${memo.timestamp}, ${memo.name} (${memo.from}) said: "${memo.message}");
}
}
async function main() {
const [owner, tipper3, tipper2, tipper] = await hre.ethers.getSigners();
const BuyMeACoffee = await hre.ethers.getContractFactory("BuyMeACoffee");
const buyMeACoffee = await BuyMeACoffee.deploy(); await buyMeACoffee.deployed();
console.log("BuyMeACoffee deployed to:", buyMeACoffee.address);
const addresses = [owner.address, tipper.address, buyMeACoffee.address];
console.log("== start =="); await printBalances(addresses);
const tip = { value: hre.ethers.utils.parseEther("1") };
await buyMeACoffee.connect(tipper).buyCoffees("Carolina", "You're the best!", tip);
await buyMeACoffee.connect(tipper2).buyCoffees("Vitto", "Amazing teacher", tip);
await buyMeACoffee.connect(tipper3).buyCoffees("Kay", "I love my Proof of Knowledge", tip);
console.log("== bought coffee ==");
await printBalances(addresses);
await buyMeACoffee.connect(owner).withdrawTips();
console.log("== withdrawTips ==");
await printBalances(addresses);
console.log("== memos ==");
const memos = await buyMeACoffee.fetchMemosDetails();
printMemos(memos);
} main() .then(() => process.exit(0)) .catch((error) => {
console.error(error); process.exit(1);
});
2- Run the script:
npx hardhat run scripts/buy-coffee.js
Step 4: Deploying to Sepolia Testnet 1- Create a deployment script:
Create scripts/deploy.js with:
const hre = require("hardhat");
async function main() {
const BuyMeACoffee = await hre.ethers.getContractFactory("BuyMeACoffee");
const buyMeACoffee = await BuyMeACoffee.deploy();
await buyMeACoffee.deployed();
console.log("BuyMeACoffee deployed to:", buyMeACoffee.address);
} main() .then(() => process.exit(0)) .catch((error) => {
console.error(error); process.exit(1);
});
2- Configure Hardhat for Sepolia: Edit hardhat.config.js:
require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-waffle");
require("dotenv").config();
const SEPOLIA_URL = process.env.SEPOLIA_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
module.exports = {
solidity: "0.8.4",
networks: {
sepolia: { url: SEPOLIA_URL, accounts: [PRIVATE_KEY] }
}
};
3- Install dotenv:
npm install dotenv
4- Create a .env file:
touch .env
5- Add your Alchemy and MetaMask details:
SEPOLIA_URL=https://eth-sepolia.alchemyapi.io/v2/ PRIVATE_KEY=
Also, Read | Identifying Smart Contract Orchestration Patterns in Solidity
Developing a decentralized "Buy Me a Coffee" dApp using Solidity enables secure, transparent microtransactions. This blockchain-based approach ensures immutable and verifiable transactions, fostering trust and eliminating intermediaries to reduce fees and increase efficiency. It's a perfect solution for content creators and small businesses, promoting decentralized finance. Are you a smart contract developer ready to transform microtransactions? Join us in creating secure, transparent dApps and shaping the future of decentralized payment solutions. Start building today!
- Medium
November 21, 2024 at 11:38 am
Your comment is awaiting moderation.