-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathautoMiner.js
More file actions
156 lines (132 loc) Β· 4.16 KB
/
autoMiner.js
File metadata and controls
156 lines (132 loc) Β· 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const express = require('express');
const { loadWallet } = require('./wallet');
// π Load wallet
const wallet = loadWallet();
if (!wallet) {
console.error('β Wallet belum dibuat. Jalankan: node wallet.js generate');
process.exit(1);
}
// π Path chain.json
const chainPath = path.join(process.cwd(), 'chain.json');
if (!fs.existsSync(chainPath)) {
console.error('β chain.json tidak ditemukan. Buat Genesis block dulu.');
process.exit(1);
}
// π Fungsi hashing
function scripthash(data, nonce) {
return crypto.createHash('sha256')
.update(data + nonce)
.digest('hex');
}
// π₯ Load chain
function loadChain() {
const raw = fs.readFileSync(chainPath, 'utf8');
return JSON.parse(raw);
}
// πΎ Save chain
function saveChain(chain) {
fs.writeFileSync(chainPath, JSON.stringify(chain, null, 2), 'utf8');
}
// βοΈ Mining block
function mineBlock() {
const chain = loadChain();
const lastBlock = chain[chain.length - 1];
const previousHash = lastBlock.hash;
const index = lastBlock.index + 1;
const timestamp = Date.now();
const rewardTx = {
from: 'SYSTEM',
to: wallet.publicKey,
amount: 100,
salt: crypto.randomBytes(16).toString('hex'),
timestamp: Date.now() // β
tambahin ini
};
let nonce = 0;
let hash = '';
const difficultyPrefix = '0000';
console.log(`βοΈ Mining block #${index}...`);
while (true) {
hash = scripthash(JSON.stringify(rewardTx) + previousHash + timestamp, nonce);
if (hash.startsWith(difficultyPrefix)) break;
nonce++;
}
const newBlock = { index, timestamp, transactions: [rewardTx], previousHash, nonce, hash };
if (chain.find(b => b.hash === hash)) {
console.log(`β οΈ Duplicate block hash detected, rejected`);
return;
}
chain.push(newBlock);
saveChain(chain);
console.log(`β
Block #${index} mined!`);
console.log(`π§± Hash: ${hash}`);
console.log(`π Reward sent to: ${wallet.publicKey}`);
}
// π Loop tiap 2 menit
setInterval(() => {
mineBlock();
}, 2 * 60 * 1000);
console.log('π Auto miner started. Mining block setiap 2 menit...');
// π Express API
const app = express();
app.use(express.json());
// Monitoring
app.get('/chain-stats', (req, res) => {
const chain = loadChain();
const lastBlock = chain[chain.length - 1];
res.json({
height: chain.length - 1,
lastHash: lastBlock.hash,
lastIndex: lastBlock.index,
lastTimestamp: lastBlock.timestamp,
wallet: wallet.publicKey,
blocks: chain.length
});
});
// Mining task untuk client
app.get('/mining-task', (req, res) => {
const chain = loadChain();
const lastBlock = chain[chain.length - 1];
const rewardTx = {
from: 'SYSTEM',
to: wallet.publicKey,
amount: 100,
salt: crypto.randomBytes(16).toString('hex'),
timestamp: Date.now() // β
tambahin ini
};
res.json({
index: lastBlock.index + 1,
previousHash: lastBlock.hash,
transactions: [rewardTx],
difficulty: '0000',
minerAddress: wallet.publicKey,
timestamp: Date.now()
});
});
// Submit block dari client
app.post('/submit-block', (req, res) => {
const { index, previousHash, transactions, nonce, hash, minerAddress } = req.body;
const chain = loadChain();
const lastBlock = chain[chain.length - 1];
if (previousHash !== lastBlock.hash) {
return res.json({ status: 'rejected', reason: 'Invalid previousHash' });
}
if (!hash.startsWith('0000')) {
return res.json({ status: 'rejected', reason: 'Hash does not meet difficulty' });
}
if (chain.find(b => b.hash === hash)) {
return res.json({ status: 'rejected', reason: 'Duplicate block hash' });
}
const newBlock = { index, timestamp: Date.now(), transactions, previousHash, nonce, hash };
chain.push(newBlock);
saveChain(chain);
console.log(`β
Block #${index} submitted by ${minerAddress}, hash: ${hash}`);
res.json({ status: 'accepted', height: chain.length - 1 });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => {
console.log(`π’ Full Node API running at http://0.0.0.0:${PORT}`);
console.log(`π‘ Endpoints: /chain-stats, /mining-task, /submit-block`);
});