本方案针对imToken数字资产到账实时通知需求,采用PHP作为后端核心实现技术,通过对接区块链浏览器或imToken开放接口获取链上交易数据,PHP后端校验交易是否指向目标钱包地址、过滤无效交易后,调用消息推送服务,将到账信息实时推送至用户端,该方案轻量易部署,适配imToken支持的多链资产,可高效满足用户对数字资产到账的实时提醒需求。
imToken链上资产自动化到账通知方案(优化版)
背景
imToken是国内用户量较大的非托管区块链钱包,广泛支持以太坊、BSC、Polygon等多链数字资产存储,是个人投资者、项目方及中小商家管理链上资产的常用工具,但对于有资金入账需求的用户而言,手动刷新钱包查询到账状态不仅效率低下,还可能因网络延迟、操作疏漏或交易确认不及时错过关键信息,由于imToken本身未提供公开的到账回调接口,我们可以借助成熟的第三方区块链浏览器API(如Etherscan、BSCscan),结合PHP定时任务实现一套低成本、易部署的自动化到账通知方案——无需搭建和维护全链节点,即可快速完成监听与通知。
核心原理
imToken钱包的资产到账本质是对应区块链网络上的有效入金交易,因此到账通知的核心逻辑可分为三步:
- 监听目标地址交易:通过第三方区块链API拉取目标钱包地址的最新链上交易记录;
- 筛选有效交易:过滤掉不符合条件的交易(如非入金交易、确认数不足、已通知过的交易);
- 触发通知动作:将有效到账交易通过指定渠道(邮件、企业微信等)发送给用户。
选择第三方API而非自建节点,主要优势在于:第三方API提供了成熟的交易查询接口,无需维护节点同步、硬件成本低,适合快速开发轻量型应用;同时API接口经过大量场景验证,稳定性和可靠性更有保障。
实现步骤
准备工作
- 目标imToken钱包地址:确定需要监听的钱包地址(如以太坊地址
0x123...abc),确保地址格式正确; - 区块链浏览器API Key:注册对应链的区块链浏览器(如Etherscan对应以太坊、BSCscan对应BSC),免费注册即可获取API Key,注意部分浏览器需实名认证后才能调用;
- PHP运行环境:版本≥7.4(推荐使用PHP 8.x),且需开启curl扩展(Linux下可通过
sudo apt install php-curl安装); - 通知渠道配置:根据需求选择通知方式,本文以邮件通知为例(建议使用SMTP方式而非原生mail函数,避免服务器邮件发送限制),也可选择企业微信机器人、钉钉机器人等渠道。
核心代码实现
(1)定时监听脚本(notify.php)
该脚本每5分钟执行一次,通过第三方API拉取最新交易,对比已处理的交易哈希,筛选符合条件的新到账交易并触发通知,以下是优化后的完整代码(已加入重试、文件锁、稳定邮件发送等机制):
<?php
// 加载环境变量(避免硬编码敏感信息,推荐使用)
$apiKey = getenv('ETHERSCAN_API_KEY') ?: '你的Etherscan API Key';
$walletAddress = getenv('WALLET_ADDRESS') ?: '你的imToken钱包地址';
$confirmThreshold = 6; // 以太坊建议6个确认数,BSC建议15个
$notifyEmail = getenv('NOTIFY_EMAIL') ?: '你的通知邮箱';
$processedTxFile = 'processed_tx_' . strtolower($walletAddress) . '.txt'; // 多地址监听时,每个地址独立存储
$apiUrl = "https://api.etherscan.io/api?module=account&action=txlist&address={$walletAddress}&startblock=0&endblock=99999999&sort=desc&apikey={$apiKey}";
// 初始化CURL,带重试机制
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 超时10秒
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 连接超时5秒
$response = false;
$retryCount = 0;
while ($retryCount < 2 && !$response) { // 最多重试2次
$response = curl_exec($ch);
$retryCount++;
}
$curlError = curl_error($ch);
curl_close($ch);
// 处理API请求失败
if (!$response || $curlError) {
error_log("Etherscan API请求失败:" . ($curlError ?: $response));
exit;
}
// 解析API返回数据
$txData = json_decode($response, true);
if ($txData['status'] != 1) {
error_log("API返回错误:" . $txData['message'] ?? '未知错误');
exit;
}
if (empty($txData['result'])) {
error_log("未查询到目标地址交易");
exit;
}
// 读取已处理交易(带文件锁,避免并发问题)
$processedTx = [];
$fp = fopen($processedTxFile, 'a+');
flock($fp, LOCK_EX); // 加排他锁
if (filesize($processedTxFile) > 0) {
$processedTx = array_filter(explode("\n", file_get_contents($processedTxFile)));
}
flock($fp, LOCK_UN);
fclose($fp);
// 筛选新的有效入金交易
$newTx = [];
foreach ($txData['result'] as $tx) {
$txHash = $tx['hash'];
$toAddress = strtolower($tx['to']);
$currentConfirm = (int)$tx['confirmations'];
// 条件:到账地址匹配、确认数达标、未通知过
if ($toAddress == strtolower($walletAddress) && $currentConfirm >= $confirmThreshold && !in_array($txHash, $processedTx)) {
$newTx[] = $tx;
$processedTx[] = $txHash; // 标记为待更新
}
}
// 发送通知并更新已处理交易
if (!empty($newTx)) {
foreach ($newTx as $tx) {
// 转换单位:wei转ETH(1 ETH = 1e18 wei)
$amount = bcdiv($tx['value'], '1000000000000000000', 18);
$subject = "imToken到账通知:新ETH到账";
$message = "您的imToken钱包收到一笔ETH:\n交易哈希:{$tx['hash']}\n金额:{$amount} ETH\n区块高度:{$tx['blockNumber']}\n确认数:{$tx['confirmations']}";
// 发送邮件(使用PHPMailer,需先通过composer安装)
if (!sendEmail($notifyEmail, $subject, $message)) {
error_log("交易{$tx['hash']}邮件发送失败");
}
}
// 更新已处理交易文件
$fp = fopen($processedTxFile, 'w');
flock($fp, LOCK_EX);
fwrite($fp, implode("\n", $processedTx) . "\n");
flock($fp, LOCK_UN);
fclose($fp);
}
- 稳定邮件发送函数(使用PHPMailer) */ function sendEmail($to, $subject, $message) { // 引入PHPMailer自动加载文件(需先执行composer require phpmailer/phpmailer) require 'vendor/autoload.php'; try { $mail = new PHPMailer\PHPMailer\PHPMailer(true); // SMTP配置(替换为自己的SMTP信息) $mail->isSMTP(); $mail->Host = 'smtp.qq.com'; // 示例:QQ邮箱SMTP服务器 $mail->SMTPAuth = true; $mail->Username = 'your-email@qq.com'; // QQ邮箱账号 $mail->Password = 'your-qq-email-auth-code'; // QQ邮箱授权码(非登录密码) $mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS; $mail->Port = 465; // 邮件内容 $mail->setFrom('imtoken-notify@qq.com', 'ImToken到账通知'); $mail->addAddress($to); $mail->Subject = $subject; $mail->Body = $message; $mail->isHTML(false); return $mail->send(); } catch (Exception $e) { error_log("邮件发送失败:" . $e->getMessage()); return false; } } ?>
配置定时任务(Linux Crontab)
为确保脚本自动执行,需在Linux系统中添加crontab定时任务,注意:1. 需使用绝对路径指向PHP可执行文件(可通过which php命令查看);2. 日志文件需确保PHP进程有写入权限;3. 建议设置为每5分钟执行一次,平衡API请求频率和通知及时性:
crontab -e添加以下内容(替换为你的脚本路径和PHP路径)
/5 * /usr/bin/php /var/www/imtoken_notify/notify.php >> /var/log/imtoken_notify.log 2>&1
保存退出后,crontab会自动加载任务,可通过tail -f /var/log/imtoken_notify.log查看执行日志,排查问题。
扩展与优化
- 支持ERC20代币监听:将API接口的
action=txlist改为action=tokentx,可获取ERC20代币的交易记录,同时需根据代币小数位数转换金额(如USDT为6位,需除以1e6),示例API:https://api.etherscan.io/api?module=account&action=tokentx&address=钱包地址&apikey=API Key; - 多链资产支持:对应不同公链更换区块链浏览器API,如BSC用BSCscan(
https://api.bscscan.com/api)、Polygon用Polygonscan(https://api.polygonscan.com/api),仅需修改API地址和对应链的确认数阈值即可; - 高可用与数据持久化:生产环境建议将已处理交易哈希存入MySQL/Redis,替换文件存储,避免单文件损坏或并发写入问题,同时可实现多服务器部署的同步;
- 多通知渠道适配:除邮件外,可替换为企业微信/钉钉机器人,示例企业微信机器人调用代码:
function sendWechatRobot($webhook, $content) { $data = ['msgtype' => 'text', 'text' => ['content' => $content]]; $ch = curl_init($webhook); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5 ]); $result = curl_exec($ch); curl_close($ch); return $result !== false && $result == '{"errcode":0,"errmsg":"ok"}'; } - 异常处理与容错:增加API请求超时重试、网络波动自动恢复机制,同时可添加交易哈希校验,避免API返回重复或无效交易;
- 敏感信息安全:所有API Key、邮箱密码等敏感信息建议存入环境变量或配置文件(如.env),避免硬编码到代码中,可通过vlucas/phpdotenv库加载环境变量。
注意事项
- API频率限制:免费版区块链浏览器API有严格的调用频率限制,如Etherscan免费版每分钟最多5次请求,因此定时任务间隔建议设置为≥12秒,实际应用中建议设置为1分钟以上,避免触发限制导致API返回错误;
- 确认数阈值设置:不同公链的分叉风险不同,以太坊建议设置为6个确认数,BSC建议设置为15个,Polygon建议设置为20个,可根据自身需求调整;
- 环境依赖检查:部署前需确认PHP环境已安装curl扩展,且SMTP服务器配置正确(邮件通知时),可通过命令行执行
php -m | grep curl检查curl扩展是否开启; - 权限与日志:脚本文件和日志目录需设置正确权限,避免PHP进程无写入权限,同时定期清理旧日志,避免占用磁盘空间;
- 多地址监听:若需监听多个imToken地址,可修改脚本为循环处理多个地址,每个地址独立存储已处理交易哈希,避免混淆。