feat: initialize crypto_clash_contract with TypeScript, Hardhat, and deployment script

- Added package.json with scripts for compiling, deploying, and testing the contract.
- Created deploy.ts script for deploying the HelloWorld contract and saving the contract address to config.json.
- Configured TypeScript with tsconfig.json for Node.js environment and ES module support.
This commit is contained in:
averel10
2025-11-11 21:01:16 +01:00
parent b27ae2dc5d
commit 44bc814114
11 changed files with 1673 additions and 6 deletions

40
.github/workflows/deploy_backend.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: Deploy Contract
on:
push:
branches:
- main
paths:
- 'crypto_clash_contract/**'
- '.github/workflows/deploy_backend.yml'
jobs:
build-and-deploy-contract:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
# update the Node version to meet your needs
node-version: 24
cache: npm
cache-dependency-path: crypto_clash_contract/package-lock.json
- name: Install dependencies and compile contract
run: npm ci && npm run compile && npm run deploy
working-directory: crypto_clash_contract
env:
API_URL: ${{ vars.API_URL }}
WALLET_PRIVATE_KEY: ${{ secrets.WALLET_PRIVATE_KEY }}
- name: Commit deployed contract address
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add config.json
git commit -m "Update deployed contract address" || echo "No changes to commit"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,9 +1,13 @@
name: Publish Frontend on GitHub Pages name: Deploy frontend
on: on:
push: push:
branches: branches:
- main - main
paths:
- 'crypto_clash_frontend/**'
- '.github/workflows/deploy_frontend.yml'
- 'config.json'
permissions: permissions:
contents: read contents: read
@@ -14,8 +18,8 @@ concurrency:
group: "pages" group: "pages"
cancel-in-progress: false cancel-in-progress: false
jobs: jobs:
build: build-frontend:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
@@ -36,13 +40,14 @@ jobs:
uses: actions/upload-pages-artifact@v3 uses: actions/upload-pages-artifact@v3
with: with:
path: ./crypto_clash_frontend/out path: ./crypto_clash_frontend/out
deploy: deploy-frontend:
environment: environment:
name: github-pages name: github-pages
url: ${{ steps.deployment.outputs.page_url }} url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs:
- build-frontend
steps: steps:
- name: Publish to GitHub Pages - name: Publish to GitHub Pages
id: deployment id: deployment

62
config.json Normal file
View File

@@ -0,0 +1,62 @@
{
"API_URL": "http://185.48.228.49:8545",
"CONTRACT_ADDRESS": "0xC6884BfDA402C8a944256Ef225dF77Bc104320f8",
"ABI": [
{
"inputs": [
{
"internalType": "string",
"name": "initMessage",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "oldStr",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "newStr",
"type": "string"
}
],
"name": "UpdatedMessages",
"type": "event"
},
{
"inputs": [],
"name": "message",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "newMessage",
"type": "string"
}
],
"name": "update",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
}

View File

@@ -1 +1,22 @@
.node_modules/ # 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

View File

@@ -0,0 +1,7 @@
# Sample Hardhat 3 Beta Project (minimal)
This project has a minimal setup of Hardhat 3 Beta, without any plugins.
## What's included?
The project includes native support for TypeScript, Hardhat scripts, tasks, and support for Solidity compilation and tests.

View File

@@ -0,0 +1,31 @@
// Specifies the version of Solidity, using semantic versioning.
// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity >=0.7.3;
// Defines a contract named `HelloWorld`.
// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
//Emitted when update function is called
//Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen.
event UpdatedMessages(string oldStr, string newStr);
// Declares a state variable `message` of type `string`.
// State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.
string public message;
// Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.
// Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
// Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).
message = initMessage;
}
// A public function that accepts a string argument and updates the `message` storage variable.
function update(string memory newMessage) public {
string memory oldMsg = message;
message = newMessage;
emit UpdatedMessages(oldMsg, newMessage);
}
}

View File

@@ -0,0 +1,18 @@
import { defineConfig } from "hardhat/config";
import dotenv from "dotenv";
dotenv.config();
const { API_URL = "", WALLET_PRIVATE_KEY = "" } = process.env;
export default defineConfig({
solidity: {
version: "0.8.28",
},
networks: {
testnet: {
url: API_URL,
accounts: [WALLET_PRIVATE_KEY],
type: "http"
}
}
});

1379
crypto_clash_contract/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
{
"name": "crypto_clash_contract",
"version": "1.0.0",
"scripts": {
"compile": "hardhat compile",
"deploy": "tsc && node dist/scripts/deploy.js",
"test": "tsc && node dist/scripts/test.js"
},
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@types/node": "^22.19.0",
"hardhat": "^3.0.13",
"typescript": "~5.8.0"
},
"type": "module",
"dependencies": {
"dotenv": "^17.2.3",
"ethers": "^6.15.0"
}
}

View File

@@ -0,0 +1,65 @@
import dotenv from "dotenv";
import { ethers } from "ethers";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
// Load environment variables
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function main() {
const artifactPath = path.join(
__dirname,
"../../artifacts/contracts/testcontract.sol/HelloWorld.json"
);
if (!fs.existsSync(artifactPath)) {
throw new Error(`Artifact not found at ${artifactPath}. Please compile the contracts first.`);
}
const artifact = JSON.parse(fs.readFileSync(artifactPath, "utf8"));
const contractABI = artifact.abi;
const contractBytecode = artifact.bytecode;
// Create provider and signer
const provider = new ethers.JsonRpcProvider(process.env.API_URL);
const signer = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY!, provider);
// Create contract factory
const HelloWorldFactory = new ethers.ContractFactory(
contractABI,
contractBytecode,
signer
);
// Deploy the contract
console.log("Deploying HelloWorld contract...");
const hello_world = await HelloWorldFactory.deploy("Hello World!");
// Wait for deployment to complete
await hello_world.waitForDeployment();
console.log("Contract deployed to address:", hello_world.target);
// Save contract address to config.json
const configPath = path.join(__dirname, "../../../config.json");
let config = {};
if (fs.existsSync(configPath)) {
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
}
(config as any).CONTRACT_ADDRESS = hello_world.target;
(config as any).API_URL = process.env.API_URL;
(config as any).ABI = contractABI;
fs.writeFileSync(configPath, JSON.stringify(config, null, 4));
console.log("✓ Contract address saved to config.json");
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,17 @@
/* 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"
},
"ts-node": {
"esm": true,
"experimentalEsm": true
}
}