251 lines
8.1 KiB
JavaScript
251 lines
8.1 KiB
JavaScript
const express = require('express');
|
||
const {Web3} = require('web3');
|
||
const axios = require('axios');
|
||
const cors = require('cors');
|
||
const bip39 = require('bip39');
|
||
const util = require('ethereumjs-util');
|
||
const {hdkey} = require('ethereumjs-wallet');
|
||
const BSCSCAN_API_KEY = '1UQ3PHID4UJUDTVD4EJK35PZB8XDKS7K9T';
|
||
|
||
const app = express();
|
||
const web3 = new Web3('https://bsc-dataseed1.binance.org:443');
|
||
//便用cor5中间件
|
||
app.use(cors());
|
||
|
||
// 你的 BNB 钱包地址
|
||
// const BNB_WALLET_ADDRESS = '0x2335070d3FA557aAcD5F762903b050d0A358b421';
|
||
// BNB 合约地址
|
||
const BNB_CONTRACT_ADDRESS = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
|
||
// USDT 合约地址
|
||
const USDT_CONTRACT_ADDRESS = '0x55d398326f99059fF775485246999027B3197955';
|
||
|
||
// USDT 合约 ABI
|
||
const USDT_ABI = [
|
||
{
|
||
"constant": true,
|
||
"inputs": [{"name": "_owner", "type": "address"}],
|
||
"name": "balanceOf",
|
||
"outputs": [{"name": "", "type": "uint256"}],
|
||
"payable": false,
|
||
"stateMutability": "view",
|
||
"type": "function"
|
||
}
|
||
];
|
||
|
||
// 获取钱包地址
|
||
app.get('/generateWords', async (req, res) => {
|
||
try {
|
||
const mnemonic = await generateWordsOptions();
|
||
res.json(mnemonic);
|
||
} catch (error) {
|
||
res.status(500).json({ error: error.message });
|
||
}
|
||
});
|
||
//获取已有钱包地址
|
||
app.get('/getMoneyList', async (req, res) => {
|
||
try {
|
||
const mnemonic = req.query.mnemonic;
|
||
const moneyInfo = await getMoneyInfos(mnemonic);
|
||
res.json(moneyInfo);
|
||
} catch (error) {
|
||
res.status(500).json({ error: error.message });
|
||
}
|
||
});
|
||
//根据助记词获取已有钱包地址
|
||
function getMoneyInfos(mnemonic){
|
||
const seed = bip39.mnemonicToSeedSync(mnemonic);
|
||
const hdwallet = hdkey.fromMasterSeed(seed);
|
||
const wallet = hdwallet.derivePath(`m/44'/60'/0'/0/0`).getWallet();
|
||
const address = `0x${wallet.getAddress().toString('hex')}`;
|
||
const privateKey = wallet.getPrivateKey().toString('hex');
|
||
const userMoneyInfo = {
|
||
address,
|
||
privateKey
|
||
};
|
||
return userMoneyInfo
|
||
}
|
||
//生成钱包地址
|
||
function generateWordsOptions(){
|
||
const mnemonic = bip39.generateMnemonic();
|
||
let name=mnemonic.split(" ");
|
||
let max=100;
|
||
let min=0;
|
||
let rand = Math.floor(Math.random() * (max - min + 1) ) + min;
|
||
let seedBuffer = bip39.mnemonicToSeedSync(mnemonic,"");
|
||
let hdWallet = hdkey.fromMasterSeed(seedBuffer);
|
||
let key = hdWallet.derivePath("m/44'/60'/0'/0/0");
|
||
let privateKey = util.bufferToHex(key._hdkey._privateKey);
|
||
let publicKey = util.bufferToHex(key._hdkey._publicKey);
|
||
let address = util.pubToAddress(key._hdkey._publicKey, true);
|
||
address = util.toChecksumAddress("0x"+address.toString('hex'));
|
||
let wallet={
|
||
mnemonic,
|
||
publicKey,
|
||
privateKey,
|
||
address,
|
||
type:"Ethereum"
|
||
}
|
||
return wallet
|
||
}
|
||
// BNB的交易转账
|
||
app.get('/transfer', async (req, res) => {
|
||
// const { from_addr, siyao, to_addr, coin } = req.body;
|
||
const from_addr = req.query.from_addr;
|
||
const to_addr = req.query.to_addr;
|
||
const coin = req.query.coin;
|
||
const siyao = req.query.siyao;
|
||
try {
|
||
// 转账金额(以 wei 为单位)
|
||
const amount = web3.utils.toWei(coin + '', 'ether'); // 这里以 Gwei 为单位
|
||
// 获取当前 gasPrice
|
||
const gasPrice = await web3.eth.getGasPrice();
|
||
|
||
// 创建转账交易对象
|
||
const transactionObject = {
|
||
from: from_addr,
|
||
to: to_addr,
|
||
value: amount,
|
||
gas: 21000, // 假设固定 gas 为 21000
|
||
gasPrice: gasPrice // 使用当前 gasPrice
|
||
};
|
||
|
||
|
||
// 签名交易
|
||
const signedTx = await web3.eth.accounts.signTransaction(transactionObject, siyao);
|
||
|
||
// 发送已签名的交易
|
||
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
|
||
|
||
res.status(200).json({ success: true });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, error: error.message });
|
||
}
|
||
});
|
||
|
||
// USDT的交易转账
|
||
async function qukuailian(from_addr, to_addr, coin, siyao) {
|
||
try {
|
||
const web3 = new Web3('https://bsc-dataseed1.binance.org:443');
|
||
const USDT_CONTRACT_ADDRESS = '0x55d398326f99059fF775485246999027B3197955';
|
||
|
||
const usdtContractABI = [{
|
||
"constant": false,
|
||
"inputs": [{
|
||
"name": "_to",
|
||
"type": "address"
|
||
},
|
||
{
|
||
"name": "_value",
|
||
"type": "uint256"
|
||
}
|
||
],
|
||
"name": "transfer",
|
||
"outputs": [{
|
||
"name": "",
|
||
"type": "bool"
|
||
}],
|
||
"type": "function"
|
||
}];
|
||
|
||
const usdtContract = new web3.eth.Contract(usdtContractABI, USDT_CONTRACT_ADDRESS);
|
||
|
||
const recipientAddress = to_addr;
|
||
const amountToSend = Number(coin) * 10 ** 18;
|
||
|
||
const txCount = await web3.eth.getTransactionCount(from_addr);
|
||
const txObject = {
|
||
from: from_addr,
|
||
to: USDT_CONTRACT_ADDRESS,
|
||
gasPrice: web3.utils.toHex(await web3.eth.getGasPrice()), // 使用区块链当前的 gas 价格
|
||
gasLimit: web3.utils.toHex(210000), // 设置一个适当的 gasLimit
|
||
value: '0', // 设置交易的价值为 0(因为我们使用 BNB 作为 gas 费)
|
||
data: usdtContract.methods.transfer(recipientAddress, amountToSend).encodeABI(),
|
||
nonce: web3.utils.toHex(txCount)
|
||
};
|
||
console.log(web3.utils.toHex(await web3.eth.getGasPrice()),'gas费')
|
||
const signedTx = await web3.eth.accounts.signTransaction(txObject, siyao);
|
||
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction); //交易成功
|
||
return receipt;
|
||
} catch (error) {
|
||
throw error;//交易失败
|
||
}
|
||
}
|
||
|
||
|
||
// 处理区块链打款请求
|
||
app.get('/qukuailian', async (req, res) => {
|
||
const from_addr = req.query.from_addr;
|
||
const to_addr = req.query.to_addr;
|
||
const coin = req.query.coin;
|
||
const siyao = req.query.siyao;
|
||
try {
|
||
const receipt = await qukuailian(from_addr, to_addr, coin, siyao);
|
||
res.json({ success: true });
|
||
} catch (error) {
|
||
res.status(500).json({ success: false, error: error.message });
|
||
}
|
||
});
|
||
|
||
// 获取指定地址的交易历史记录
|
||
async function getTransactions(address) {
|
||
try {
|
||
// 使用 BSCScan API 获取交易记录
|
||
const response = await axios.get('https://api.bscscan.com/api', {
|
||
params: {
|
||
module: 'account',
|
||
action: 'tokentx',
|
||
contractaddress: USDT_CONTRACT_ADDRESS,
|
||
address: address,
|
||
apikey: BSCSCAN_API_KEY,
|
||
sort: 'desc' // 按时间降序排序
|
||
}
|
||
});
|
||
|
||
// 处理 API 响应
|
||
if (response.data.status === '1') {
|
||
const transactions = response.data.result;
|
||
return transactions;
|
||
} else {
|
||
throw new Error(response.data.message);
|
||
}
|
||
} catch (error) {
|
||
return [];
|
||
}
|
||
};
|
||
// 获取历史记录的接口
|
||
app.get('/transactions', async (req, res) => {
|
||
const address = req.query.address;
|
||
try {
|
||
const transactions = await getTransactions(address);
|
||
res.json(transactions);
|
||
} catch (error) {
|
||
res.status(500).json({ error: error.message });
|
||
}
|
||
});
|
||
// 获取余额的路由
|
||
app.get('/balances', async (req, res) => {
|
||
const address = req.query.address;// 钱包地址
|
||
try {
|
||
// 获取 BNB 钱包余额
|
||
const bnbBalanceWei = await web3.eth.getBalance(address);
|
||
const bnbBalance = web3.utils.fromWei(bnbBalanceWei.toString(), 'ether');
|
||
|
||
// 获取 USDT 代币余额
|
||
const usdtContract = new web3.eth.Contract(USDT_ABI, USDT_CONTRACT_ADDRESS);
|
||
const usdtBalance = await usdtContract.methods.balanceOf(address).call();
|
||
|
||
res.json({
|
||
bnbBalance: bnbBalance,
|
||
usdtBalance: usdtBalance.toString()
|
||
});
|
||
} catch (error) {
|
||
res.status(500).json({ error: 'An error occurred' });
|
||
}
|
||
});
|
||
|
||
// 启动服务器
|
||
const PORT = process.env.PORT || 3000;
|
||
app.listen(PORT, () => {
|
||
console.log(`Server running on port ${PORT}`);
|
||
});
|