用PHP实现imToken数字资产到账实时通知方案

qbadmin 982 0
本方案针对IMToken数字资产到账实时通知需求,采用PHP作为后端核心实现技术,通过对接区块链浏览器或imToken开放接口获取链上交易数据,PHP后端校验交易是否指向目标钱包地址、过滤无效交易后,调用消息推送服务,将到账信息实时推送至用户端,该方案轻量易部署,适配imToken支持的多链资产,可高效满足用户对数字资产到账的实时提醒需求。

imToken链上资产自动化到账通知方案(优化版)


背景

imToken是国内用户量较大的非托管区块链钱包,广泛支持以太坊、BSC、Polygon等多链数字资产存储,是个人投资者、项目方及中小商家管理链上资产的常用工具,但对于有资金入账需求的用户而言,手动刷新钱包查询到账状态不仅效率低下,还可能因网络延迟、操作疏漏或交易确认不及时错过关键信息,由于imToken本身未提供公开的到账回调接口,我们可以借助成熟的第三方区块链浏览器API(如Etherscan、BSCscan),结合PHP定时任务实现一套低成本、易部署的自动化到账通知方案——无需搭建和维护全链节点,即可快速完成监听与通知。


核心原理

imToken钱包的资产到账本质是对应区块链网络上的有效入金交易,因此到账通知的核心逻辑可分为三步:

  1. 监听目标地址交易:通过第三方区块链API拉取目标钱包地址的最新链上交易记录;
  2. 筛选有效交易:过滤掉不符合条件的交易(如非入金交易、确认数不足、已通知过的交易);
  3. 触发通知动作:将有效到账交易通过指定渠道(邮件、企业微信等)发送给用户。

选择第三方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查看执行日志,排查问题。


扩展与优化

  1. 支持ERC20代币监听:将API接口的action=txlist改为action=tokentx,可获取ERC20代币的交易记录,同时需根据代币小数位数转换金额(如USDT为6位,需除以1e6),示例API:https://api.etherscan.io/api?module=account&action=tokentx&address=钱包地址&apikey=API Key
  2. 多链资产支持:对应不同公链更换区块链浏览器API,如BSC用BSCscan(https://api.bscscan.com/api)、Polygon用Polygonscan(https://api.polygonscan.com/api),仅需修改API地址和对应链的确认数阈值即可;
  3. 高可用与数据持久化:生产环境建议将已处理交易哈希存入MySQL/Redis,替换文件存储,避免单文件损坏或并发写入问题,同时可实现多服务器部署的同步;
  4. 多通知渠道适配:除邮件外,可替换为企业微信/钉钉机器人,示例企业微信机器人调用代码:
    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"}';
    }
    
  5. 异常处理与容错:增加API请求超时重试、网络波动自动恢复机制,同时可添加交易哈希校验,避免API返回重复或无效交易;
  6. 敏感信息安全:所有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地址,可修改脚本为循环处理多个地址,每个地址独立存储已处理交易哈希,避免混淆。

标签: #钱包 #imToken #数字资产