How To Build "Buy Me a Coffee" DeFi dApp Using Solidity

Posted By : Jagveer

May 30, 2024

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

Detailed steps for building "Buy Me a Coffee" DeFi dApp Using Solidity 


Before starting, ensure you have:

  • npm version 8.5.5 or higher. 
  • node version 16.13.1 or higher. 
  • An Alchemy account. 


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 { 

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.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(); 
} 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:      

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:      



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! 


- Ethereum Stack Exchange : 

- GitHub :


Leave a


Name is required

Invalid Name

Comment is required

Recaptcha is required.


July 16, 2024 at 01:52 pm

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text