init: Smartcontract token

This commit is contained in:
adelyaou 2025-09-23 14:34:31 +07:00
commit 957d30aa3d
13 changed files with 8255 additions and 0 deletions

22
.gitignore vendored Normal file
View File

@ -0,0 +1,22 @@
# Node modules
/node_modules
# Compilation output
/dist
# pnpm deploy output
/bundle
# Hardhat Build Artifacts
/artifacts
# Hardhat compilation (v2) support directory
/cache
# Typechain output
/types
# Hardhat coverage reports
/coverage
.env

37
README.md Normal file
View File

@ -0,0 +1,37 @@
# adel-token-contract
AdelToken is an ERC-20 token built on the Polygon (Amoy) network. This project uses Hardhat for smart contract development, testing, and deployment, and integrates with MetaMask as the primary wallet for interacting with the token.
Features
- ERC-20 compliant token
- Built on Polygon Amoy testnet
- Hardhat for compilation, deployment, and testing
- MetaMask wallet integration
- Ready for future dApp development
Tech Stack
- Blockchain: Polygon (Amoy testnet)
- Smart Contract Framework: Hardhat
- Wallet Integration: MetaMask
- Token Standard: ERC-20
Installation & Setup
1. Clone the repo
git clone https://github.com/your-username/adel-token-contract.git
cd adel-token-contract
3. Install dependencies
npm install
4. Compile smart contracts
npx hardhat compile
6. Deploy to Polygon Amoy
Make sure you have a .env file with your PRIVATE_KEY and RPC_URL for Polygon Amoy.
npx hardhat run scripts/deploy.ts --network amoy
Usage
Import the deployed contract address into MetaMask as a custom token.
Youll be able to send, receive, and manage AdelToken directly from your wallet.
Use Hardhat tasks or scripts to interact with the smart contract (mint, transfer, etc.).

10
contracts/AdelToken.sol Normal file
View File

@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract AdelToken is ERC20 {
constructor(uint256 initialSupply) ERC20("AdelToken", "ADL") {
_mint(msg.sender, initialSupply * 10 ** decimals());
}
}

19
contracts/Counter.sol Normal file
View File

@ -0,0 +1,19 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;
contract Counter {
uint public x;
event Increment(uint by);
function inc() public {
x++;
emit Increment(1);
}
function incBy(uint by) public {
require(by > 0, "incBy: increment should be positive");
x += by;
emit Increment(by);
}
}

23
hardhat.config.cjs Normal file
View File

@ -0,0 +1,23 @@
require("dotenv").config();
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
version: "0.8.28",
settings: {
optimizer: { enabled: true, runs: 200 },
},
},
defaultNetwork: "hardhat",
networks: {
localhost: {
url: "http://127.0.0.1:8545",
},
hardhat: {},
amoy: {
url: process.env.AMOY_RPC_URL || "",
accounts: process.env.AMOY_PRIVATE_KEY ? [process.env.AMOY_PRIVATE_KEY] : [],
},
},
};

View File

@ -0,0 +1,9 @@
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("CounterModule", (m) => {
const counter = m.contract("Counter");
m.call(counter, "incBy", [5n]);
return { counter };
});

7957
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "smartcontract",
"version": "1.0.0",
"description": "This project showcases a Hardhat 3 Beta project using `mocha` for tests and the `ethers` library for Ethereum interactions.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
"@types/node": "^22.18.6",
"dotenv": "^17.2.2",
"forge-std": "github:foundry-rs/forge-std#v1.9.4",
"hardhat": "^2.26.2",
"typescript": "~5.8.0"
},
"dependencies": {
"@openzeppelin/contracts": "^5.4.0"
},
"directories": {
"test": "test"
}
}

20
scripts/deploy.ts Normal file
View File

@ -0,0 +1,20 @@
import hre from "hardhat";
async function main() {
const initialSupply = 1_000_000; // 1 juta token
const { ethers } = hre;
const AdelToken = await ethers.getContractFactory("AdelToken");
const token = await AdelToken.deploy(initialSupply, {
gasLimit: 5000000,
gasPrice: ethers.parseUnits("30", "gwei"),
});
await token.waitForDeployment();
console.log("✅ AdelToken deployed at:", await token.getAddress()); }
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
export {};

22
scripts/send-op-tx.ts Normal file
View File

@ -0,0 +1,22 @@
import { network } from "hardhat";
const { ethers } = await network.connect({
network: "hardhatOp",
chainType: "op",
});
console.log("Sending transaction using the OP chain type");
const [sender] = await ethers.getSigners();
console.log("Sending 1 wei from", sender.address, "to itself");
console.log("Sending L2 transaction");
const tx = await sender.sendTransaction({
to: sender.address,
value: 1n,
});
await tx.wait();
console.log("Transaction sent successfully");

59
scripts/tesDeploy.ts Normal file
View File

@ -0,0 +1,59 @@
import hre from "hardhat";
async function main() {
const { ethers } = hre;
// Ambil signer
const [deployer, user1, user2, merchant] = await ethers.getSigners();
console.log("Deploying token with deployer:", deployer.address);
// Deploy token AdelToken dengan initialSupply 1.000.000
const initialSupply = 1_000_000;
const AdelToken = await ethers.getContractFactory("AdelToken");
const token = await AdelToken.deploy(initialSupply);
await token.waitForDeployment();
console.log("✅ Token deployed at:", await token.getAddress());
// Cek saldo awal deployer
console.log(`Deployer initial balance: ${(await token.balanceOf(deployer.address)).toString()}`);
// Payment test 1: deployer -> user1
const payment1 = 1000;
await token.transfer(user1.address, payment1);
console.log(`✅ Payment test 1: ${payment1} tokens to user1`);
// Payment test 2: deployer -> user2
const payment2 = 500;
await token.transfer(user2.address, payment2);
console.log(`✅ Payment test 2: ${payment2} tokens to user2`);
// Conversion / payment simulation:
// user1 pays merchant 300 tokens
const conversionAmount = 300;
await token.connect(user1).transfer(merchant.address, conversionAmount);
console.log(`✅ Conversion/payment: user1 paid ${conversionAmount} tokens to merchant`);
// User2 pays merchant 200 tokens
const conversionAmount2 = 200;
await token.connect(user2).transfer(merchant.address, conversionAmount2);
console.log(`✅ Conversion/payment: user2 paid ${conversionAmount2} tokens to merchant`);
// Cek saldo akhir semua akun
console.log("\n=== Final Balances ===");
console.log(`Deployer: ${(await token.balanceOf(deployer.address)).toString()}`);
console.log(`User1: ${(await token.balanceOf(user1.address)).toString()}`);
console.log(`User2: ${(await token.balanceOf(user2.address)).toString()}`);
console.log(`Merchant: ${(await token.balanceOf(merchant.address)).toString()}`);
}
// Jalankan main
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
export {};

37
test/Counter.js Normal file
View File

@ -0,0 +1,37 @@
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Counter", function () {
it("Should emit the Increment event when calling the inc() function", async function () {
const counter = await ethers.deployContract("Counter");
// Di ethers v6, gunakan BigInt untuk literal angka
await expect(counter.inc())
.to.emit(counter, "Increment")
.withArgs(1n); // pakai 1n (BigInt)
});
it("The sum of the Increment events should match the current value", async function () {
const counter = await ethers.deployContract("Counter");
const deploymentBlockNumber = await ethers.provider.getBlockNumber();
// run a series of increments
for (let i = 1; i <= 10; i++) {
await counter.incBy(i);
}
const events = await counter.queryFilter(
counter.filters.Increment(),
deploymentBlockNumber,
"latest"
);
// check that the aggregated events match the current value
let total = 0n;
for (const event of events) {
total += event.args.by; // event.args.by udah BigInt di ethers v6
}
expect(await counter.x()).to.equal(total);
});
});

13
tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
/* Based on https://github.com/tsconfig/bases/blob/501da2bcd640cf95c95805783e1012b992338f28/bases/node22.json */
{
"compilerOptions": {
"lib": ["es2023"],
"module": "node16",
"target": "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "node16",
"outDir": "dist"
}
}