|
@@ -947,83 +947,100 @@ class Pay extends Api
|
|
|
$service = Web3Service::instance('bsc', 'usdt', '');
|
|
$service = Web3Service::instance('bsc', 'usdt', '');
|
|
|
// $info =$service->getLastTransfer([], ['0xbfc3b2193653ebf94bfa3fe586627b9c01f26db9'],1748293200);
|
|
// $info =$service->getLastTransfer([], ['0xbfc3b2193653ebf94bfa3fe586627b9c01f26db9'],1748293200);
|
|
|
|
|
|
|
|
-// 设置常量
|
|
|
|
|
- define('BSC_BLOCKS_PER_SECOND', 3); // BSC平均每秒3个区块
|
|
|
|
|
- $toAddress = '0xbfc3b2193653ebf94bfa3fe586627b9c01f26db9';
|
|
|
|
|
- $targetTimestamp = 1748379600;
|
|
|
|
|
|
|
+// 使用函数
|
|
|
|
|
+ $transfers = paginatedTransferQuery($service, '0xbfc3b2193653ebf94bfa3fe586627b9c01f26db9', 1748379600);
|
|
|
|
|
|
|
|
-// 计算起始区块(基于时间戳估算)
|
|
|
|
|
- $currentTimestamp = time();
|
|
|
|
|
- $currentBlockEstimate = intval($currentTimestamp * BSC_BLOCKS_PER_SECOND);
|
|
|
|
|
- $startBlockEstimate = intval($targetTimestamp * BSC_BLOCKS_PER_SECOND);
|
|
|
|
|
|
|
+// 安全地排序和获取结果
|
|
|
|
|
+ $info = null;
|
|
|
|
|
+ if (!empty($transfers)) {
|
|
|
|
|
+ // 先过滤掉没有时间戳的记录
|
|
|
|
|
+ $validTransfers = array_filter($transfers, function($t) {
|
|
|
|
|
+ return property_exists($t, 'timestamp');
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
-// 分页参数
|
|
|
|
|
- $pageSize = 500; // 初始分页大小(区块数)
|
|
|
|
|
- $maxPages = 100; // 最大分页次数
|
|
|
|
|
- $allTransfers = [];
|
|
|
|
|
|
|
+ if (!empty($validTransfers)) {
|
|
|
|
|
+ usort($validTransfers, function($a, $b) {
|
|
|
|
|
+ return $b->timestamp - $a->timestamp;
|
|
|
|
|
+ });
|
|
|
|
|
+ $info = $validTransfers[0];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-// 分页查询
|
|
|
|
|
- for ($i = 0; $i < $maxPages; $i++) {
|
|
|
|
|
- $fromBlock = $startBlockEstimate + ($i * $pageSize);
|
|
|
|
|
- $toBlock = $fromBlock + $pageSize - 1;
|
|
|
|
|
|
|
+// 输出结果
|
|
|
|
|
+ if ($info) {
|
|
|
|
|
+ echo "找到最新转账: " . $info->transactionHash;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ echo "未找到符合条件的转账记录";
|
|
|
|
|
+ }
|
|
|
|
|
+// foreach ($info as $k => $v){
|
|
|
|
|
+// $value = $v->params['value']->toString();
|
|
|
|
|
+// var_dump($value);
|
|
|
|
|
+// $value = bcdiv($value, bcpow(10, get_token_info('bsc',$v['token'], 'decimal')), 12);
|
|
|
|
|
+// var_dump($value);die();
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+ var_dump($info);die();
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ function paginatedTransferQuery($service, $toAddress, $targetTimestamp) {
|
|
|
|
|
+ $BPS = 3; // BSC每秒区块数
|
|
|
|
|
+ $currentBlock = intval(time() * $BPS);
|
|
|
|
|
+ $startBlock = intval($targetTimestamp * $BPS);
|
|
|
|
|
+ $pageSize = 500;
|
|
|
|
|
+ $results = [];
|
|
|
|
|
+ $attempts = 0;
|
|
|
|
|
|
|
|
- // 确保不查询超过当前区块
|
|
|
|
|
- if ($fromBlock > $currentBlockEstimate) break;
|
|
|
|
|
|
|
+ while ($startBlock <= $currentBlock && $attempts < 50) {
|
|
|
|
|
+ $endBlock = min($startBlock + $pageSize - 1, $currentBlock);
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
$transfers = $service->getLastTransfer(
|
|
$transfers = $service->getLastTransfer(
|
|
|
[],
|
|
[],
|
|
|
[$toAddress],
|
|
[$toAddress],
|
|
|
- 0, // 禁用时间戳过滤
|
|
|
|
|
- $fromBlock,
|
|
|
|
|
- min($toBlock, $currentBlockEstimate)
|
|
|
|
|
|
|
+ 0,
|
|
|
|
|
+ $startBlock,
|
|
|
|
|
+ $endBlock
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- $allTransfers = array_merge($allTransfers, $transfers);
|
|
|
|
|
|
|
+ // 只有当有结果时才处理
|
|
|
|
|
+ if (!empty($transfers)) {
|
|
|
|
|
+ $results = array_merge($results, $transfers);
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否达到目标时间
|
|
|
|
|
+ $newest = end($transfers);
|
|
|
|
|
+ reset($transfers); // 重置数组指针
|
|
|
|
|
|
|
|
- // 成功时增大分页
|
|
|
|
|
|
|
+ // 确保有 timestamp 属性再检查
|
|
|
|
|
+ if (property_exists($newest, 'timestamp') && $newest->timestamp >= time() - 60) {
|
|
|
|
|
+ break; // 已查询到最新区块
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 成功时增加分页大小
|
|
|
$pageSize = min(5000, $pageSize * 2);
|
|
$pageSize = min(5000, $pageSize * 2);
|
|
|
|
|
+ $startBlock = $endBlock + 1;
|
|
|
|
|
|
|
|
} catch (RequestException $e) {
|
|
} catch (RequestException $e) {
|
|
|
if (strpos($e->getMessage(), '413') !== false) {
|
|
if (strpos($e->getMessage(), '413') !== false) {
|
|
|
- // 减小分页并重试当前范围
|
|
|
|
|
- $pageSize = max(100, intval($pageSize / 2));
|
|
|
|
|
- $i--; // 重试当前页
|
|
|
|
|
|
|
+ $pageSize = max(100, $pageSize / 2);
|
|
|
|
|
+ $attempts++;
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
throw $e;
|
|
throw $e;
|
|
|
|
|
+ } catch (\Throwable $e) {
|
|
|
|
|
+ // 捕获所有类型错误
|
|
|
|
|
+ error_log("查询错误: " . $e->getMessage());
|
|
|
|
|
+ $pageSize = max(100, $pageSize / 2);
|
|
|
|
|
+ $attempts++;
|
|
|
|
|
+ continue;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 添加延迟防止请求过密
|
|
|
|
|
- usleep(100000); // 100ms
|
|
|
|
|
-
|
|
|
|
|
- // 提前终止条件:已查询到足够新的区块
|
|
|
|
|
- $latestTransferTimestamp = !empty($transfers) ? max(array_column($transfers, 'timestamp')) : 0;
|
|
|
|
|
- if ($latestTransferTimestamp >= $currentTimestamp - 60) { // 最新1分钟内
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ usleep(100000);
|
|
|
|
|
+ $attempts++;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 时间戳过滤
|
|
|
|
|
- $filteredTransfers = array_filter($allTransfers, function($t) use ($targetTimestamp) {
|
|
|
|
|
- return $t->timestamp >= $targetTimestamp;
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
-// 排序并获取最新转账
|
|
|
|
|
- usort($filteredTransfers, function($a, $b) {
|
|
|
|
|
- return $b->timestamp - $a->timestamp;
|
|
|
|
|
|
|
+ return array_filter($results, function($t) use ($targetTimestamp) {
|
|
|
|
|
+ return property_exists($t, 'timestamp') && $t->timestamp >= $targetTimestamp;
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
- $info = $filteredTransfers[0] ?? null;
|
|
|
|
|
-
|
|
|
|
|
-// foreach ($info as $k => $v){
|
|
|
|
|
-// $value = $v->params['value']->toString();
|
|
|
|
|
-// var_dump($value);
|
|
|
|
|
-// $value = bcdiv($value, bcpow(10, get_token_info('bsc',$v['token'], 'decimal')), 12);
|
|
|
|
|
-// var_dump($value);die();
|
|
|
|
|
-// }
|
|
|
|
|
-
|
|
|
|
|
- var_dump($info);die();
|
|
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|