deploy.js ->
const hre = require("hardhat");
const { ethers } = require('hardhat');
const { utils } = require('hardhat');
// Returns the ether balance of a given address.
async function getBalance(address) {
const balanceBigInt = await hre.ethers.provider.getBalance(address);
return ethers.formatEther(balanceBigInt);
}
// Logs the Ether balances for a list of addresses.
async function printBalances(addresses) {
let index = 0;
for (const address of addresses) {
console.log(`Addresses ${index} balance: `, await getBalance(address));
index++;
}
}
// Logs the memos stored on-chain from coffee purchases.
async function printMemos(memos) {
for (const memo of memos) {
const timestamp = memo.timestamp;
const tipper = memo.name;
const tipperAddress = memo.from;
const message = memo.message;
console.log(`At ${timestamp}, ${tipper} (${tipperAddress}) said: "${message}"`);
}
}
async function main() {
const [owner, tipper, tipper2, tipper3] = await hre.ethers.getSigners();
// const BuyMeACoffee = await hre.ethers.getContractFactory("BuyMeACoffee");
const buyMeACoffee = await hre.ethers.deployContract("BuyMeACoffee");
// Deploy the contract.
await buyMeACoffee.waitForDeployment();
console.log("BuyMeACoffee deployed to:", buyMeACoffee.target);
console.log("5");
// Check balances before the coffee purchase.
const addresses = [owner.address, tipper.address, buyMeACoffee.target];
console.log("== start ==");
await printBalances(addresses);
// Buy the owner a few coffees.
// Error somewhere in tips
const tip = { value: ethers.parseEther("1") };
await buyMeACoffee.connect(tipper).buyCoffee("Rahul", "You're a good coder", tip);
await buyMeACoffee.connect(tipper2).buyCoffee("Suprit", "You're a good coder", tip);
await buyMeACoffee.connect(tipper3).buyCoffee("Prasad", "You're a good coder", tip);
// Check balances after the coffee purchase.
console.log("== bought coffee ==");
await printBalances(addresses);
// Withdraw.
await buyMeACoffee.connect(owner).withdrawTips();
// Check balances after withdrawal.
console.log("== withdrawTips ==");
await printBalances(addresses);
// Check out the memos.
console.log("== memos ==");
const memos = await buyMeACoffee.getMemos();
printMemos(memos);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
BuyMeACoffee.sol ->
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
contract BuyMeACoffee {
// Events notify external users, such as a listening frontend website that something has happenned on the blockchain.
event NewMemo (
address indexed from,
uint256 timestamp,
string name,
string message,
string CoffeeType
);
// Creating a struct
struct Memo {
address from;
uint256 timestamp;
string name;
string message;
string CoffeeType;
}
address payable owner;
// creating memos
Memo[] memos;
constructor(){
owner = payable(msg.sender);
}
// fetching all stored memos
function getMemos() public view returns (Memo[] memory){
return memos;
}
function buyCoffee(string memory _name, string memory _message, string memory _CoffeeType) public payable{
require(msg.value > 0, "Can't buy Coffee for free");
memos.push(Memo(
msg.sender,
block.timestamp,
_name,
_message,
_CoffeeType
));
emit NewMemo(msg.sender, block.timestamp, _name, _message, _CoffeeType);
}
// sends the entire balance stored in this contract to the owner
function withdrawTips() public {
require(owner.send(address(this).balance));
}
function updateWithdraw(address _newAddress) public {
require(msg.sender == owner, "Only owner can call this method");
owner = payable(_newAddress);
}
function buyLargeCoffee (
string memory _name,
string memory _message,
string memory _coffeeType
) public payable {
require(msg.value == 0.03 ether, "Pay 0.03 to buy coffee");
memos.push(
Memo(msg.sender, block.timestamp, _name, _message, _coffeeType)
);
emit NewMemo(msg.sender, block.timestamp, _name, _message, _coffeeType);
}
}