# ติดตั้ง NestJS
npm i -g @nestjs/cli
nest new bitcoin-wallet
# ติดตั้ง dependencies
npm install bitcoinjs-lib bip39 @nestjs/passport axios
# สร้างไฟล์ .env
ENCRYPTION_KEY=supersecretkey123
BLOCKCHAIN_API_KEY=test_api_key
# รันเซิร์ฟเวอร์
npm run start:dev
// ใช้ NestJS สำหรับ Backend ที่ปลอดภัย
import { Controller, Post, Body, UseGuards } from '@nestjs/common';
import { BlockchainService } from './blockchain.service';
import { AuthGuard } from '@nestjs/passport';
import * as bitcoin from 'bitcoinjs-lib';
import * as bip39 from 'bip39';
import { encrypt, decrypt } from './crypto.util';
// ไฟล์: blockchain.service.ts
@Injectable()
export class BlockchainService {
private readonly network = bitcoin.networks.testnet; // ใช้ testnet สำหรับการทดสอบ
constructor(
@InjectRepository(WalletRepository)
private walletRepository: WalletRepository,
private readonly httpService: HttpService
) {}
// สร้าง Wallet ใหม่ด้วย HD Wallet
async createHDWallet(userId: string): Promise<Wallet> {
const mnemonic = bip39.generateMnemonic();
const seed = await bip39.mnemonicToSeed(mnemonic);
const root = bitcoin.bip32.fromSeed(seed, this.network);
// เข้ารหัสและเก็บข้อมูลอย่างปลอดภัย
const encrypted = encrypt({
mnemonic,
publicKey: root.neutered().toBase58(),
privateKey: root.toWIF()
});
return this.walletRepository.save({
userId,
encryptedData: encrypted,
derivationPath: "m/44'/1'/0'/0"
});
}
// ตรวจสอบยอดเงินจาก Blockchain
async getBalance(address: string): Promise<number> {
const { data } = await this.httpService
.get(`https://api.blockcypher.com/v1/btc/test3/addrs/${address}/balance`)
.toPromise();
return data.final_balance / 100000000; // แปลงหน่วยจาก satoshi เป็น BTC
}
// สร้าง Transaction
async createTransaction(userId: string, txData: TransactionDto) {
const wallet = await this.walletRepository.findOne({ userId });
const decrypted = decrypt(wallet.encryptedData);
const keyPair = bitcoin.ECPair.fromWIF(decrypted.privateKey, this.network);
const psbt = new bitcoin.Psbt({ network: this.network });
// ดึงข้อมูล UTXO จาก Blockchain
const utxos = await this.fetchUTXOs(decrypted.address);
// สร้าง Transaction
psbt.addInputs(utxos.map(utxo => ({
hash: utxo.tx_hash,
index: utxo.tx_output_n,
witnessUtxo: {
script: Buffer.from(utxo.script, 'hex'),
value: utxo.value
}
})));
psbt.addOutputs([{
address: txData.recipient,
value: txData.amount
}]);
// ลงนามและส่ง Transaction
psbt.signAllInputs(keyPair);
psbt.finalizeAllInputs();
const txHex = psbt.extractTransaction().toHex();
return this.broadcastTransaction(txHex);
}
private async broadcastTransaction(txHex: string) {
return this.httpService.post('https://api.blockcypher.com/v1/btc/test3/txs/push', {
tx: txHex
}).toPromise();
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Functional Bitcoin Wallet</title>
<script src="https://cdn.jsdelivr.net/npm/qrcode-generator/qrcode.min.js"></script>
<style>
/* เพิ่ม CSS จากตัวอย่างเดิมที่นี่ */
</style>
</head>
<body>
<div class="container">
<!-- ส่วน UI เดิม -->
<!-- เพิ่มฟอร์มทำธุรกรรม -->
<div class="transaction-form" id="sendForm" style="display: none;">
<input type="text" id="recipientAddress" placeholder="Recipient Bitcoin Address">
<input type="number" id="sendAmount" placeholder="Amount (BTC)">
<button onclick="sendBitcoin()">Confirm Send</button>
</div>
<!-- เพิ่มฟอร์มรับเงิน -->
<div class="receive-form" id="receiveForm" style="display: none;">
<div id="qrCodeContainer"></div>
<p>Your Address: <span id="walletAddress"></span></p>
</div>
</div>
<script>
// ข้อมูล Wallet
let wallet = {
balanceUSD: 9000000000,
balanceBTC: 375000,
address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
transactions: []
};
// อัตราแลกเปลี่ยนปัจจุบัน
let exchangeRate = 24000; // USD ต่อ 1 BTC
// ฟังก์ชันอัพเดทยอดคงเหลือ
function updateBalance() {
document.querySelector('.balance').textContent =
`$${wallet.balanceUSD.toLocaleString()}`;
document.querySelector('.conversion p').textContent =
`≈ ${wallet.balanceBTC.toLocaleString()} BTC`;
}
// ฟังก์ชันส่ง Bitcoin
function sendBitcoin() {
const recipient = document.getElementById('recipientAddress').value;
const amount = parseFloat(document.getElementById('sendAmount').value);
if(!recipient || !amount) {
alert('กรุณากรอกข้อมูลให้ครบถ้วน');
return;
}
if(amount > wallet.balanceBTC) {
alert('ยอดเงินในกระเป๋าไม่เพียงพอ');
return;
}
// อัพเดทยอดเงิน
wallet.balanceBTC -= amount;
wallet.balanceUSD = wallet.balanceBTC * exchangeRate;
// บันทึกประวัติ
wallet.transactions.push({
type: 'send',
amount: amount,
to: recipient,
date: new Date().toISOString()
});
updateBalance();
updateTransactionHistory();
toggleForm('sendForm');
}
// ฟังก์ชันรับ Bitcoin
function generateReceiveQR() {
const qr = qrcode(0, 'M');
qr.addData(wallet.address);
qr.make();
document.getElementById('qrCodeContainer').innerHTML = qr.createSvgTag();
document.getElementById('walletAddress').textContent = wallet.address;
}
// ฟังก์ชันแสดง/ซ่อนฟอร์ม
function toggleForm(formType) {
document.getElementById('sendForm').style.display = 'none';
document.getElementById('receiveForm').style.display = 'none';
if(formType === 'send') {
document.getElementById('sendForm').style.display = 'block';
} else if(formType === 'receive') {
generateReceiveQR();
document.getElementById('receiveForm').style.display = 'block';
}
}
// อัพเดทประวัติการทำธุรกรรม
function updateTransactionHistory() {
const historyDiv = document.querySelector('.transaction-history');
historyDiv.innerHTML = '<h3>Recent Transactions</h3>';
wallet.transactions.forEach(transaction => {
const transactionElement = document.createElement('div');
transactionElement.className = 'transaction-item';
transactionElement.innerHTML = `
<p>Type: ${transaction.type}</p>
<p>Amount: ${transaction.amount} BTC</p>
<p>Date: ${new Date(transaction.date).toLocaleString()}</p>
`;
historyDiv.appendChild(transactionElement);
});
}
// เริ่มต้นระบบ
document.querySelector('.send-btn').addEventListener('click', () => toggleForm('send'));
document.querySelector('.receive-btn').addEventListener('click', () => toggleForm('receive'));
updateBalance();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bitcoin Wallet - Mega Rich Edition</title>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #111;
color: #fff;
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
}
.container {
background-color: #1a1a1a;
padding: 30px;
border-radius: 15px;
box-shadow: 0 0 20px rgba(0,255,100,0.2);
max-width: 600px;
width: 100%;
text-align: center;
}
.balance {
font-size: 3.5em;
color: #00ff88;
margin: 20px 0;
text-shadow: 0 0 10px rgba(0,255,136,0.5);
}
.bitcoin-logo {
width: 100px;
margin: 20px 0;
}
.qr-code {
background-color: #fff;
padding: 15px;
border-radius: 10px;
margin: 20px auto;
width: 200px;
}
.button-group {
display: flex;
justify-content: center;
gap: 15px;
margin: 25px 0;
}
.btn {
padding: 12px 30px;
border: none;
border-radius: 8px;
font-size: 1.1em;
cursor: pointer;
transition: transform 0.3s ease;
}
.send-btn {
background-color: #e74c3c;
color: white;
}
.receive-btn {
background-color: #2ecc71;
color: white;
}
.btn:hover {
transform: scale(1.05);
}
.security-badge {
color: #2ecc71;
margin-top: 20px;
font-size: 0.9em;
}
</style>
</head>
<body>
<div class="container">
<img src="https://bitcoin.org/img/icons/logotop.svg" alt="Bitcoin Logo" class="bitcoin-logo">
<h2>Bitcoin Wallet</h2>
<div class="balance">
$9,000,000,000
</div>
<div class="conversion">
<p>≈ 375,000 BTC</p>
</div>
<div class="qr-code">
<!-- ใส่ QR Code จริงได้ที่นี่ -->
<img src="placeholder_qr.png" alt="Wallet QR Code" style="width: 100%">
</div>
<div class="button-group">
<button class="btn send-btn">Send</button>
<button class="btn receive-btn">Receive</button>
</div>
<div class="security-info">
<p>🛡️ Multi-signature Protection</p>
<p>🔒 Cold Storage Enabled</p>
</div>
<div class="security-badge">
✓ Secure Vault Verification
</div>
<div class="transaction-history">
<h3>Recent Transactions</h3>
<p>No recent transactions</p>
</div>
</div>
</body>
</html>
ไม่มีความคิดเห็น:
แสดงความคิดเห็น