Skip to content

Commit e30533a

Browse files
committed
更新初步归集方法,功能完善进度提示页面可见
1 parent d65df7a commit e30533a

3 files changed

Lines changed: 137 additions & 3 deletions

File tree

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import React, { useState } from "react";
2+
import { Button, Input, List, message, Form, Alert } from "antd";
3+
import { ethers } from "ethers";
4+
5+
const ERC20Aggregator = () => {
6+
const [form] = Form.useForm();
7+
const [loading, setLoading] = useState(false);
8+
const [errors, setErrors] = useState([]);
9+
10+
// ERC20 代币 ABI(只需要 balanceOf 和 transfer 方法)
11+
const erc20Abi = [
12+
"function balanceOf(address owner) view returns (uint256)",
13+
"function transfer(address to, uint256 amount) returns (bool)",
14+
];
15+
16+
// 处理归集
17+
const handleAggregate = async (values) => {
18+
const { rpcUrl, mainPrivateKey, tokenData } = values;
19+
setLoading(true);
20+
setErrors([]);
21+
22+
try {
23+
const provider = new ethers.JsonRpcProvider(rpcUrl);
24+
const mainWallet = new ethers.Wallet(mainPrivateKey, provider);
25+
26+
// 解析代币数据
27+
const tokenList = tokenData
28+
.split("\n")
29+
.filter((line) => line.trim() !== "")
30+
.map((line) => {
31+
const [tokenAddress, privateKey] = line
32+
.split(",")
33+
.map((item) => item.trim());
34+
return { tokenAddress, privateKey };
35+
});
36+
37+
// 遍历代币列表
38+
for (const { tokenAddress, privateKey } of tokenList) {
39+
try {
40+
const wallet = new ethers.Wallet(privateKey, provider);
41+
const tokenContract = new ethers.Contract(
42+
tokenAddress,
43+
erc20Abi,
44+
wallet
45+
);
46+
47+
// 查询代币余额
48+
const balance = await tokenContract.balanceOf(wallet.address);
49+
if (balance !== 0) {
50+
// 转账代币
51+
const tx = await tokenContract.transfer(
52+
mainWallet.address,
53+
balance
54+
);
55+
await tx.wait();
56+
message.success(
57+
`Transferred ${balance}} tokens from ${wallet.address} to ${mainWallet.address}`
58+
);
59+
} else {
60+
setErrors((prev) => [
61+
...prev,
62+
`No balance for token ${tokenAddress} in wallet ${wallet.address}`,
63+
]);
64+
}
65+
} catch (error) {
66+
setErrors((prev) => [
67+
...prev,
68+
`Error with token ${tokenAddress}: ${error.message}`,
69+
]);
70+
}
71+
}
72+
} catch (error) {
73+
message.error(`Error: ${error.message}`);
74+
} finally {
75+
setLoading(false);
76+
}
77+
};
78+
79+
return (
80+
<div>
81+
<h1>ERC20 代币归集</h1>
82+
<Alert
83+
message="提示"
84+
description="目前调用的方法为erc20通用的balanceOf和transfer方法,如果代币合约不支持这两个方法或实现有误,将无法归集,后续更新中细分各类方法。"
85+
type="info"
86+
showIcon
87+
closable
88+
/>
89+
<Form form={form} onFinish={handleAggregate}>
90+
<Form.Item
91+
name="rpcUrl"
92+
label="RPC 接口"
93+
rules={[{ required: true, message: "请输入 RPC 接口" }]}
94+
>
95+
<Input placeholder="例如: https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID" />
96+
</Form.Item>
97+
<Form.Item
98+
name="mainPrivateKey"
99+
label="主钱包私钥"
100+
rules={[{ required: true, message: "请输入主钱包私钥" }]}
101+
>
102+
<Input.Password placeholder="用于接收代币的钱包私钥" />
103+
</Form.Item>
104+
<Form.Item
105+
name="tokenData"
106+
label="代币地址及私钥"
107+
rules={[{ required: true, message: "请输入代币地址及对应钱包私钥" }]}
108+
>
109+
<Input.TextArea rows={4} placeholder="每行格式: 代币地址,钱包私钥" />
110+
</Form.Item>
111+
<Form.Item>
112+
<Button type="primary" htmlType="submit" loading={loading}>
113+
开始归集
114+
</Button>
115+
</Form.Item>
116+
</Form>
117+
118+
{/* 错误提示 */}
119+
{errors.length > 0 && (
120+
<div style={{ marginTop: "24px" }}>
121+
<h3>错误信息</h3>
122+
<List
123+
bordered
124+
dataSource={errors}
125+
renderItem={(item) => <List.Item>{item}</List.Item>}
126+
/>
127+
</div>
128+
)}
129+
</div>
130+
);
131+
};
132+
133+
export default ERC20Aggregator;

src/container/EtherContain/WalletUpgrateTab.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Tabs from "@mui/material/Tabs";
33
import Tab from "@mui/material/Tab";
44
import WalletTransactionHistory from "../../components/ethers/wallet_upgrate_functions/WalletTransactionHistory";
55
import ContractEventListener from "../../components/ethers/wallet_upgrate_functions/ContractEventListener";
6+
import Erc20Aggregator from "../../components/ethers/wallet_upgrate_functions/Erc20Aggregator";
67

78
const WalletUpgrateTab = () => {
89
const [index, setIndex] = useState("A");
@@ -16,7 +17,7 @@ const WalletUpgrateTab = () => {
1617
<Tabs value={index} onChange={handleChange}>
1718
<Tab label="交易记录查询" value="A" />
1819
<Tab label="区块链交易监听" value="B" />
19-
<Tab label="AA" value="C" />
20+
<Tab label="ERC20归集" value="C" />
2021
</Tabs>
2122

2223
{/* 根据选中的 tab 显示不同内容 */}
@@ -30,7 +31,7 @@ const WalletUpgrateTab = () => {
3031
<ContractEventListener />
3132
</div>
3233
)}
33-
{index === "C" && <div></div>}
34+
{index === "C" && <Erc20Aggregator />}
3435
</>
3536
);
3637
};

update.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
at provider-jsonrpc.js:314:1``
1818
原因:httpurl 过滤器周期过短
1919

20-
- 重新尝试,更换rpc接口为infura,获取成功。尝试修复bug
20+
- 重新尝试,更换rpc接口为infura,获取成功。后续更新更健全的版本
2121

2222
### 部署与验证问题
2323
- DeployContract 功能受阻

0 commit comments

Comments
 (0)