init: Smartcontract token
This commit is contained in:
commit
957d30aa3d
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
You’ll 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.).
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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] : [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -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 };
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {};
|
||||
|
|
@ -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");
|
||||
|
|
@ -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 {};
|
||||
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue