forked from wanshade/holesky-send
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
106 lines (86 loc) · 3.58 KB
/
app.js
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
const sendForm = document.getElementById('send-form');
const sendButton = document.getElementById('send-button');
const outputDiv = document.getElementById('output');
// 创建全局 Web3 实例
const web3 = new Web3(new Web3.providers.HttpProvider('https://sepolia.base.org'));
sendButton.addEventListener('click', async () => {
const privateKeys = document.getElementById('private-key').value.split('\n')
.map(key => key.trim())
.filter(key => key !== '');
const toAddresses = sendForm.elements['to-addresses'].value.split('\n')
.map(address => address.trim())
.filter(address => address !== '');
if (privateKeys.length === 0) {
outputDiv.textContent = 'Please enter at least one private key';
return;
}
if (toAddresses.length === 0) {
outputDiv.textContent = 'Please enter at least one recipient address';
return;
}
outputDiv.textContent = '';
let numTransactions = 0;
let numErrors = 0;
for (const privateKey of privateKeys) {
try {
const transactions = await sendTransactions(privateKey, toAddresses);
numTransactions += transactions.length;
transactions.forEach(({ transactionHash, from, to, value }, index) => {
outputDiv.innerHTML += `Transaction #${numTransactions - transactions.length + index + 1} sent from ${from} with hash: <a href="https://holesky.etherscan.io/tx/${transactionHash}" rel="noopener" target="_blank">${transactionHash}</a><br>`;
outputDiv.innerHTML += `Sent ${value} ETH to ${to}<br><br>`;
});
} catch (error) {
numErrors++;
outputDiv.textContent += `Error sending transactions from ${error.from}: ${error.message}\n`;
}
}
if (numErrors > 0) {
outputDiv.textContent += `Failed to send ${numErrors} transaction${numErrors === 1 ? '' : 's'}\n`;
}
});
async function sendTransactions(privateKey, toAddresses) {
const account = web3.eth.accounts.privateKeyToAccount(privateKey);
const balance = await web3.eth.getBalance(account.address);
const currentGasPrice = await web3.eth.getGasPrice();
const priorityFee = web3.utils.toWei('1.5', 'gwei');
const gasPrice = web3.utils.toBN(currentGasPrice).add(web3.utils.toBN(priorityFee));
const transactions = [];
for (const toAddress of toAddresses) {
try {
const receipt = await sendSingleTransaction(account, toAddress, web3.utils.toWei('1', 'ether'), gasPrice, balance);
transactions.push({
transactionHash: receipt.transactionHash,
from: account.address,
to: toAddress,
value: '0.5'
});
} catch (error) {
console.error('Error sending transaction:', error);
throw { from: account.address, message: error.message };
}
}
return transactions;
}
async function sendSingleTransaction(account, toAddress, value, gasPrice, balance) {
const txObject = {
from: account.address,
to: toAddress,
value: web3.utils.toHex(value),
gasPrice: gasPrice
};
const gas = await web3.eth.estimateGas(txObject);
const transaction = {
...txObject,
gas: gas
};
const gasLimit = web3.utils.toBN(transaction.gas);
const totalGasCost = gasLimit.mul(gasPrice);
const accountBalance = web3.utils.toBN(balance);
if (totalGasCost.gt(accountBalance)) {
throw new Error('Insufficient balance to pay gas');
}
const signedTx = await account.signTransaction(transaction);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
console.log('Transaction successful:', receipt.transactionHash);
return receipt;
}