diff --git a/.idea/misc.xml b/.idea/misc.xml
index 87a20fc..fc1f2cb 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/account/alice.pem b/account/alice.pem
index 10ef470..f5bc7c9 100644
--- a/account/alice.pem
+++ b/account/alice.pem
@@ -1,11 +1,11 @@
-----BEGIN PRIVATE KEY-----
-1120cf8793ccb6df2a4a4f371503e9699d1512d2e35d73daa3202c20c8e11731
+92cbe1d3631be230ee9541ee877985a90ad2b501b089e2f0a5a6f1b99580aaec
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
-6b68d579030462d7a0232b65a96c19a27bc98fd12ba8e5b09fdc83237ee54191ce8ff77d630341209d26bcd04640cf9e95f96af08718da3d258cef5e6e99bd08
+c13154e64419e5febe4c749d2070dea70aa83519ceac2a39da4efbcd9a9485121b202ffa9cc6a7822c046ec959d0a8ba738a5f0010f8863523ed6a386a837be9
-----END PUBLIC KEY-----
-----BEGIN ADDRESS-----
-0xfffecbb1ef05e897e8d7f9da10fa13255c5c7b17
+0x1664cc33e0c6e2c7573b9c2ff8438862ecd8dce8
-----END ADDRESS-----
-----BEGIN CRYPTO TYPE-----
1
diff --git a/account/bob.pem b/account/bob.pem
index 18e0066..c12d191 100644
--- a/account/bob.pem
+++ b/account/bob.pem
@@ -1,11 +1,11 @@
-----BEGIN PRIVATE KEY-----
-23230366ba1af4d9fe798a4891302e6f4d765f2cdb4e47836ceac4a3d5f50967
+391db7ce3e7f627656f44db9ec8bd3f2b8626537f90d464d6a87298abac18b32
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
-8bd59280cc6deee3de64d88c45227cf1342a6603607e30099371a0b5ab469e832dc2b72a00f7c3acbc5b40fc6a0fc298ae8545467e67dab4d3037b129c608ba9
+46c2de937ba38b9aa93efa9685ea846b54c0c38dda02725a9ecc46c3dbd8f9ccec849fa3f0c656031e5e3c6c572216f9864e591f1b94e7288451337e1cdb04bc
-----END PUBLIC KEY-----
-----BEGIN ADDRESS-----
-0x863a9a841c4242c7cab7ab3d5399f41ae21d05f9
+0xcfb8fd63efa74f85ae85cc8b1b90b6cab37527d2
-----END ADDRESS-----
-----BEGIN CRYPTO TYPE-----
1
diff --git a/account/charlie.pem b/account/charlie.pem
index 4c5f19f..be8fd75 100644
--- a/account/charlie.pem
+++ b/account/charlie.pem
@@ -1,11 +1,11 @@
-----BEGIN PRIVATE KEY-----
-3855d3f52955a2ff799d52996fa0828d077d8dbb19242e6bd1d7b3a6f8dfbf29
+3a84aba1875141cc011b2202f802fa8f7929dd371c00909af78ef267bbff29da
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
-aeb5629ca59d24e78f0aab53a03405fc6814316a1bdac4fba56385e8639b10d8ab04a53a7b7d94a5138f51ee02de7a7481ff8dc350c1b5d015dfa95273f48025
+72141f6b0d2147a91d994109b01885995b32f31d1c1b2b1ef3dcc6ec86f92e462568ad0c5f1bfb02afbb01bc682b15eb85dc2af7b61443e3feee23005ade12fd
-----END PUBLIC KEY-----
-----BEGIN ADDRESS-----
-0xdb52dabfe568e15331d302f4d9a411d6993c3606
+0x8931c1ede9b32a0e8d740707008a156af2adf985
-----END ADDRESS-----
-----BEGIN CRYPTO TYPE-----
1
diff --git a/account/user_pem.pem b/account/user_pem.pem
index 4b100c1..c9a7eb3 100644
--- a/account/user_pem.pem
+++ b/account/user_pem.pem
@@ -1,11 +1,11 @@
-----BEGIN PRIVATE KEY-----
-e9c890670f4af89b804ea94e4068f604170d6c39f428bc04b62e8e2b5d05fdf2
+19b62893e08eee9432c5a1f9703722634c6f12cf6ef84d49038eb672e0a72a1f
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
-f7e50297ef82600b324685265cae5b3e9030fd3c8d45b643a1c4316ecfae282b1a241c3f1d42d1d129a24d66f636dcb17b3e0a4ca34b3cb6475f774e1cb0b83a
+229e8d0b4d5519540fce3a030947a4e80ace4a8cfc73cc751abc82acf5e31f4a666bc7a9c8a3f64877be59b176e1cd1b5caf0fcc4e258cba8b122c2a1573faee
-----END PUBLIC KEY-----
-----BEGIN ADDRESS-----
-0x7843803067240dd872e50a26b254c83bc77d77ed
+0x90e1523ceb879f91c04dcf40453b82276ceb680a
-----END ADDRESS-----
-----BEGIN CRYPTO TYPE-----
1
diff --git a/build.gradle b/build.gradle
index fbe068a..7f27572 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,6 +6,12 @@ plugins {
group = 'org.example'
version = '1.0-SNAPSHOT'
+// 设置 Java 版本兼容性
+java {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+}
+
repositories {
mavenCentral()
}
@@ -27,5 +33,39 @@ test {
}
application {
- mainClass = 'com.org.fisco.AccountGenerator'
-}
\ No newline at end of file
+ mainClass = 'com.org.fisco.TPSTest'
+}
+
+// 创建 Fat JAR(包含所有依赖的可执行jar)
+tasks.register('fatJar', Jar) {
+ archiveClassifier = 'all'
+ archiveFileName = 'tps-test.jar'
+
+ manifest {
+ attributes(
+ 'Main-Class': 'com.org.fisco.TPSTest',
+ 'Implementation-Title': 'FISCO BCOS TPS Test Tool',
+ 'Implementation-Version': version
+ )
+ }
+
+ // 包含编译后的类
+ from sourceSets.main.output
+
+ // 包含所有运行时依赖
+ from {
+ configurations.runtimeClasspath.collect {
+ it.isDirectory() ? it : zipTree(it)
+ }
+ }
+
+ // 排除签名文件
+ exclude 'META-INF/*.SF'
+ exclude 'META-INF/*.DSA'
+ exclude 'META-INF/*.RSA'
+
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+}
+
+// 让 build 任务依赖 fatJar
+build.dependsOn fatJar
\ No newline at end of file
diff --git a/doc/FISCO_BCOS_TPS测试指南.md b/doc/FISCO_BCOS_TPS测试指南.md
new file mode 100644
index 0000000..3df4791
--- /dev/null
+++ b/doc/FISCO_BCOS_TPS测试指南.md
@@ -0,0 +1,607 @@
+# FISCO BCOS TPS压力测试指南
+
+> **文档版本**: v2.0
+> **更新日期**: 2026-02-10
+> **适用版本**: FISCO BCOS 2.x / 3.x
+
+---
+
+## 📋 目录
+
+1. [测试工具介绍](#测试工具介绍)
+2. [快速开始](#快速开始)
+3. [测试参数配置](#测试参数配置)
+4. [运行测试](#运行测试)
+5. [结果分析](#结果分析)
+6. [常见问题排查](#常见问题排查)
+7. [性能优化建议](#性能优化建议)
+
+---
+
+## 测试工具介绍
+
+### 🎯 TPSTest.java
+
+本项目提供的 `TPSTest.java` 是一个完整的TPS压测工具,具有以下特性:
+
+**核心功能:**
+- ✅ 自动连接FISCO BCOS节点
+- ✅ 使用 ParallelTransfer 合约进行并行转账测试
+- ✅ 支持多线程并发压测
+- ✅ 实时监控TPS、成功率
+- ✅ 自动生成详细测试报告
+- ✅ 支持QPS限流控制
+
+**测试原理:**
+```
+多线程并发 → 发送转账交易 → 统计响应时间 → 计算TPS和延迟
+```
+
+**文件位置:**
+```
+src/main/java/com/org/fisco/TPSTest.java
+```
+
+---
+
+## 快速开始
+
+### 前提条件
+
+1. **合约已部署**
+ - 合约地址:在代码第284行设置
+ - 默认使用:`0x06ac2fe406f1ae06494946ee281d58f1c79c39e4`
+
+2. **账户已初始化**
+ - 使用 `fisco/console/init_accounts.sh` 脚本初始化账户余额
+ - 或手动在控制台初始化至少100个账户
+
+3. **SDK配置正确**
+ - 配置文件:`src/main/resources/config.toml`
+ - 确保能连接到你的链节点
+
+### 5分钟快速测试
+
+```bash
+cd /Users/kiro/IdeaProjects/contract
+
+# 1. 编译项目
+./gradlew build
+
+# 2. 直接运行测试
+./gradlew run
+```
+
+测试会自动:
+1. 连接到链节点
+2. 初始化合约对象
+3. 生成测试账户
+4. 开始压测
+5. 输出测试报告
+
+---
+
+## 测试参数配置
+
+### 🔧 核心参数说明
+
+在 `TPSTest.java` 的 `main` 方法中(第277-281行)配置:
+
+```java
+tester.setTestParams(
+ threadCount, // 并发线程数
+ totalTransactions, // 总交易数
+ qpsLimit // QPS限制(0表示不限制)
+);
+```
+
+### 参数详解
+
+#### 1. 并发线程数 (threadCount)
+
+**作用:** 控制同时发送交易的线程数量
+
+**推荐值:**
+| 测试场景 | 推荐值 | 说明 |
+|---------|--------|------|
+| 基准测试 | 1 | 测试单笔交易延迟 |
+| 初步压测 | 50-100 | 找到基本TPS水平 |
+| 寻找峰值 | 100-200 | 逐步增加找峰值 |
+| 极限压测 | 200-500 | 测试系统极限 |
+
+**⚠️ 注意:**
+- 并发数过高会导致成功率下降
+- 并发数过低无法达到TPS峰值
+- **建议从小到大逐步测试**
+
+#### 2. 总交易数 (totalTransactions)
+
+**作用:** 本次测试发送的交易总数
+
+**推荐值:**
+| 测试类型 | 推荐值 | 测试时长(估算) |
+|---------|--------|----------------|
+| 快速验证 | 1,000 | 1-5秒 |
+| 基础测试 | 10,000 | 10-30秒 |
+| 标准测试 | 50,000 | 1-2分钟 |
+| 长期测试 | 100,000+ | 5分钟以上 |
+
+**原则:**
+- ✅ 测试时长至少30秒以上才准确
+- ✅ 交易数太少会受启动开销影响
+- ✅ 交易数太多会耗时过长
+
+#### 3. QPS限制 (qpsLimit)
+
+**作用:** 限制每秒发送的交易数
+
+**设置建议:**
+- `0`:不限制,全力压测(推荐)
+- `5000`:温和测试,适合生产环境验证
+- `10000+`:根据节点能力设置上限
+
+---
+
+## 运行测试
+
+### 方法1:使用默认参数运行
+
+```bash
+cd /Users/kiro/IdeaProjects/contract
+./gradlew run
+```
+
+### 方法2:修改参数后运行
+
+编辑 `src/main/java/com/org/fisco/TPSTest.java`:
+
+```java
+// 第277-281行
+tester.setTestParams(
+ 100, // 改为你想要的并发数
+ 10000, // 改为你想要的交易总数
+ 0 // 0表示不限速
+);
+```
+
+然后运行:
+```bash
+./gradlew build && ./gradlew run
+```
+
+### 观察实时输出
+
+测试运行时会显示:
+
+```
+========================================
+ FISCO BCOS TPS压力测试工具
+========================================
+
+连接FISCO BCOS节点成功
+当前区块高度: 12345
+使用已部署的合约地址: 0x06ac...
+合约对象初始化完成
+
+生成测试账户列表...
+已生成 100 个测试账户
+账户列表生成完成,账户余额已通过 init_accounts.sh 脚本初始化
+
+[3/3] 开始压力测试...
+测试配置:
+ - 并发线程数: 100
+ - 总交易数: 10000
+ - QPS限制: 无限制
+ - 预热交易数: 100
+
+正在预热 (100 笔交易)...
+预热完成!
+
+开始正式压测...
+实时TPS监控 (每5秒更新):
+ 当前进度: 2145/10000 | 实时TPS: 675.64 | 成功率: 99.87%
+ 当前进度: 4523/10000 | 实时TPS: 682.31 | 成功率: 99.91%
+ ...
+```
+
+---
+
+## 结果分析
+
+### 📊 测试报告解读
+
+测试完成后会自动生成报告(同时保存到文件):
+
+```
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 15:30:00
+ 结束时间: 2026-02-10 15:32:15
+ 测试时长: 135.45 秒
+ 并发线程数: 100
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9987
+ 失败交易: 13
+ 成功率: 99.87%
+
+性能指标:
+ ★ TPS (每秒交易数): 675.64
+ 平均延迟: 148.23 ms
+ 中位数延迟: 125 ms
+ P95延迟: 287 ms
+ P99延迟: 456 ms
+
+报告时间: 2026-02-10 15:32:15
+========================================
+```
+
+### 📈 核心指标说明
+
+#### 1. TPS(每秒交易数)
+
+**含义:** 每秒成功处理的交易数量
+
+**评判标准:**
+| TPS范围 | 评价 | 说明 |
+|---------|------|------|
+| > 1000 | 优秀 ✅ | 性能良好 |
+| 500-1000 | 良好 👍 | 基本满足需求 |
+| 100-500 | 一般 ⚠️ | 需要优化 |
+| < 100 | 较差 ❌ | 存在严重问题 |
+
+**影响因素:**
+- 节点配置(CPU、内存、磁盘)
+- 网络延迟
+- 并发线程数
+- 节点 config.ini 配置
+
+#### 2. 成功率
+
+**含义:** 成功交易数 / 总交易数
+
+**评判标准:**
+- ✅ ≥ 99%:健康状态
+- ⚠️ 95-99%:压力过大,需降低并发
+- ❌ < 95%:存在严重问题
+
+**低成功率原因:**
+- 并发数设置过高
+- 交易池容量不足
+- 节点资源不足
+- 账户余额不足
+
+#### 3. 延迟指标
+
+**平均延迟:** 所有交易的平均响应时间
+**P95延迟:** 95%的交易在此时间内完成
+**P99延迟:** 99%的交易在此时间内完成
+
+**评判标准:**
+| 指标 | 优秀 | 良好 | 一般 | 需优化 |
+|------|------|------|------|--------|
+| 平均延迟 | <100ms | 100-300ms | 300-500ms | >500ms |
+| P99延迟 | <500ms | 500-1000ms | 1-2s | >2s |
+
+---
+
+## 常见问题排查
+
+### ❌ 问题1:TPS很低(<100)
+
+**可能原因及解决方案:**
+
+1. **网络延迟过高**
+ ```bash
+ # 测试网络延迟
+ ping -c 10 121.196.226.157
+ ```
+ - 延迟 > 100ms:考虑在云服务器上直接运行测试
+ - 延迟 > 50ms:TPS会受明显影响
+
+2. **节点配置未优化**
+
+ SSH到云服务器检查 `config.ini`:
+ ```bash
+ cd ~/fisco/nodes/*/node0
+ cat config.ini | grep -A 3 "\[tx_execute\]"
+ cat config.ini | grep -A 3 "\[consensus\]"
+ ```
+
+ 确认配置:
+ ```ini
+ [tx_execute]
+ enable_parallel=true # 必须为true
+
+ [consensus]
+ max_trans_num_per_block=1000 # 建议≥1000
+ ```
+
+3. **日志级别过低**
+ ```ini
+ [log]
+ level=error # 改为error减少IO开销
+ ```
+
+### ❌ 问题2:成功率低(<99%)
+
+**排查步骤:**
+
+1. **检查错误日志**
+
+ 测试运行时会输出错误信息:
+ ```
+ 交易失败 - Status: 18, Message: ...
+ 交易异常: ContractException - ...
+ ```
+
+2. **降低并发数**
+
+ 如果成功率 < 99%,说明并发过高:
+ ```java
+ // 从当前并发数降低50%
+ tester.setTestParams(
+ 50, // 从100降到50
+ 10000,
+ 0
+ );
+ ```
+
+3. **检查账户余额**
+ ```bash
+ cd fisco/console
+ bash start.sh
+ # 在控制台执行
+ call ParallelTransfer 0x06ac... balanceOf "user_000000"
+ ```
+
+### ❌ 问题3:程序运行时资源耗尽
+
+**现象:** 出现大量线程创建失败错误
+
+**原因:** 之前的bug(每笔交易创建新合约对象)已修复
+
+**确认修复:** 检查代码第29行是否有:
+```java
+private ParallelTransfer contract; // 复用合约对象
+```
+
+### ❌ 问题4:程序一直不退出
+
+**原因:** SDK后台线程持续运行
+
+**解决:** 已在代码第318行添加:
+```java
+System.exit(0);
+```
+
+如果仍然卡住,按 `Ctrl+C` 强制终止。
+
+---
+
+## 性能优化建议
+
+### 🎯 找到准确TPS的方法
+
+**错误做法 ❌:**
+- 用最高并发数跑一次就认为是TPS
+- 忽略成功率指标
+- 测试时间过短(<10秒)
+
+**正确做法 ✅:**
+
+#### 阶段1:基准测试
+```java
+tester.setTestParams(1, 100, 0); // 单线程
+```
+记录:平均延迟 = X ms
+
+#### 阶段2:二分法找最佳并发
+
+逐步测试,找到成功率≥99%的最大并发数:
+
+| 轮次 | 并发数 | 交易数 | 观察 |
+|------|--------|--------|------|
+| 测试1 | 50 | 5000 | 成功率≥99%? |
+| 测试2 | 100 | 5000 | 成功率≥99%? |
+| 测试3 | 200 | 5000 | 成功率≥99%? |
+| 测试4 | 400 | 5000 | 成功率<99%则停止 |
+
+**结论:** 成功率≥99%的最大并发数 = 最佳并发数
+
+#### 阶段3:峰值测试
+```java
+tester.setTestParams(
+ [最佳并发数], // 从阶段2得到
+ 50000, // 大批量测试
+ 0
+);
+```
+
+**这就是你链的真实TPS!**
+
+### 🔧 节点优化Checklist
+
+#### 云服务器配置
+
+SSH到服务器,编辑 `config.ini`:
+
+```ini
+[tx_execute]
+enable_parallel=true # ✅ 开启并行
+
+[consensus]
+max_trans_num_per_block=1000 # ✅ 每块至少1000笔
+
+[tx_pool]
+limit=150000 # ✅ 交易池容量
+
+[log]
+level=error # ✅ 降低日志级别
+```
+
+重启节点:
+```bash
+cd ~/fisco/nodes/*/
+bash stop_all.sh
+bash start_all.sh
+```
+
+#### 系统优化
+
+```bash
+# 增加文件描述符
+ulimit -n 65535
+
+# 检查磁盘类型(必须是SSD)
+lsblk -d -o name,rota
+# rota=0 表示SSD
+```
+
+### 📊 并发数与TPS的关系
+
+**理论公式:**
+```
+TPS = 并发数 / 平均延迟(秒)
+```
+
+**示例:**
+- 平均延迟 = 100ms = 0.1秒
+- 并发数 = 100
+- 理论TPS = 100 / 0.1 = **1000**
+
+**实际调优:**
+
+| 并发数 | TPS | 成功率 | 决策 |
+|--------|-----|--------|------|
+| 50 | 400 | 100% | ⬆️ 继续增加 |
+| 100 | 700 | 99.8% | ⬆️ 可以继续 |
+| 200 | 850 | 99.2% | ⬆️ 接近最佳 |
+| 400 | 870 | 97% | ❌ 过高,回退 |
+
+**最佳并发数 = 200**
+
+---
+
+## 测试结果记录模板
+
+建议每次测试记录:
+
+```
+测试日期: 2026-02-10
+测试轮次: 第X次
+
+测试参数:
+- 并发线程数:
+- 总交易数:
+- QPS限制:
+
+测试环境:
+- 节点数量: 4个
+- 网络延迟: XXms
+- enable_parallel: true/false
+- max_trans_num_per_block: XXX
+
+测试结果:
+- TPS:
+- 成功率:
+- 平均延迟:
+- P99延迟:
+
+问题记录:
+
+
+优化措施:
+
+
+下次改进:
+
+```
+
+---
+
+## 快速参考
+
+### 常用命令
+
+```bash
+# 编译运行测试
+cd /Users/kiro/IdeaProjects/contract
+./gradlew build && ./gradlew run
+
+# 查看最近的测试报告
+ls -lt tps_test_report_*.txt | head -5
+cat tps_test_report_*.txt
+
+# 测试网络延迟
+ping -c 10 121.196.226.157
+
+# 检查节点配置(SSH到服务器)
+ssh root@121.196.226.157
+cd ~/fisco/nodes/*/node0
+cat config.ini | grep -E "enable_parallel|max_trans_num_per_block|limit|level"
+```
+
+### 推荐测试流程
+
+```bash
+# 1. 基准测试(修改代码为1线程100笔)
+./gradlew run
+
+# 2. 初步压测(修改代码为100线程10000笔)
+./gradlew run
+
+# 3. 根据成功率调整并发数
+# 成功率≥99% → 增加并发
+# 成功率<99% → 减少并发
+
+# 4. 峰值测试(用最佳并发数跑50000笔)
+./gradlew run
+```
+
+---
+
+## 常见TPS参考值
+
+| 区块链 | 单链TPS | 备注 |
+|--------|---------|------|
+| FISCO BCOS v2.x | 500-2000 | enable_parallel=true |
+| FISCO BCOS v3.x | 2000-5000 | 性能优化版 |
+| Hyperledger Fabric | 1000-3000 | 企业级联盟链 |
+| 以太坊 | 15-30 | 公链 |
+
+**你的目标:** 根据节点配置,达到 **500-1000 TPS** 即为良好水平。
+
+---
+
+## 总结
+
+### ✅ 正确的测试姿势
+
+1. **从小到大测试**:1线程 → 50线程 → 100线程 → 200线程
+2. **关注成功率**:必须≥99%,否则降低并发
+3. **测试足够久**:至少30秒以上
+4. **记录每次结果**:对比优化前后差异
+
+### ⚠️ 常见误区
+
+1. ❌ 用最高并发测出来的数字就是TPS
+2. ❌ 忽略成功率指标
+3. ❌ 测试时间太短
+4. ❌ 不检查节点配置
+5. ❌ 网络延迟过高还在本地测试
+
+### 🎯 核心原则
+
+**准确的TPS = 在成功率≥99%的前提下,能持续达到的最高TPS**
+
+---
+
+**祝测试顺利!** 🚀
+
+有问题请查看"常见问题排查"章节,或检查测试报告中的错误信息。
diff --git a/doc/服务器部署运行指南.md b/doc/服务器部署运行指南.md
new file mode 100644
index 0000000..61ea47f
--- /dev/null
+++ b/doc/服务器部署运行指南.md
@@ -0,0 +1,742 @@
+# 服务器部署运行指南
+
+> TPS测试工具服务器部署和使用说明
+
+---
+
+## 📦 打包部署包
+
+### 1. 在本地打包
+
+```bash
+cd /Users/kiro/IdeaProjects/contract
+
+# 清理并打包(使用 fatJar 任务)
+./gradlew clean fatJar
+
+# 查看生成的 jar 文件
+ls -lh build/libs/tps-test.jar
+```
+
+**输出:** `build/libs/tps-test.jar` (约 25MB,包含所有依赖)
+
+**注意:** 必须使用 `./gradlew fatJar` 命令打包,这样才会生成包含所有依赖的可执行jar文件。
+
+### 2. 准备部署文件
+
+需要上传到服务器的文件:
+
+```
+部署包/
+├── tps-test.jar # 可执行jar(必需)
+└── config.toml # 链连接配置(必需)
+```
+
+从本地复制配置文件:
+```bash
+# 复制配置文件到 build 目录
+cp src/main/resources/config.toml build/libs/
+```
+
+---
+
+## 🚀 上传到服务器
+
+### 方法1:使用 SCP 上传
+
+```bash
+# 1. 创建本地部署目录
+cd /Users/kiro/IdeaProjects/contract
+mkdir -p deploy
+cp build/libs/tps-test.jar deploy/
+cp src/main/resources/config.toml deploy/
+
+# 2. 上传到服务器
+scp -r deploy/* root@121.196.226.157:~/tps-test/
+
+# 如果需要上传到第二台服务器
+scp -r deploy/* root@8.137.93.11:~/tps-test/
+```
+
+### 方法2:使用 rsync 上传(推荐)
+
+```bash
+# 自动创建目录并上传
+rsync -avz --progress \
+ build/libs/tps-test.jar \
+ src/main/resources/config.toml \
+ root@121.196.226.157:~/tps-test/
+```
+
+---
+
+## ⚙️ 服务器端配置
+
+### 1. SSH 登录到服务器
+
+```bash
+ssh root@121.196.226.157
+```
+
+### 2. 检查 Java 环境
+
+```bash
+# 检查 Java 版本(需要 JDK 11+)
+java -version
+
+# 如果没有安装,安装 OpenJDK
+# Ubuntu/Debian
+sudo apt update && sudo apt install -y openjdk-11-jdk
+
+# CentOS/RHEL
+sudo yum install -y java-11-openjdk
+```
+
+### 3. 验证文件
+
+```bash
+cd ~/tps-test
+ls -lh
+
+# 应该看到:
+# tps-test.jar (约 30-40MB)
+# config.toml
+```
+
+### 4. 修改配置文件(如需要)
+
+```bash
+# 编辑配置文件,确保连接到本地节点
+vim config.toml
+```
+
+**如果在服务器上运行,建议使用本地地址:**
+```toml
+[network]
+peers=["127.0.0.1:20200"] # 使用本地节点,延迟最低
+```
+
+---
+
+## 🎯 运行测试
+
+### 基本用法
+
+```bash
+cd ~/tps-test
+
+# 查看帮助
+java -jar tps-test.jar --help
+
+# 使用默认参数(100线程,10000笔交易)
+java -jar tps-test.jar -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+```
+
+### 命令行参数说明
+
+| 参数 | 简写 | 说明 | 默认值 |
+|------|------|------|--------|
+| `--threads` | `-t` | 并发线程数 | 100 |
+| `--transactions` | `-n` | 总交易数 | 10000 |
+| `--qps` | `-q` | QPS限制,0表示不限 | 0 |
+| `--contract` | `-c` | **合约地址(必填)** | 无 |
+| `--accounts` | `-a` | 测试账户数 | 100 |
+| `--help` | `-h` | 显示帮助 | - |
+
+### 常用测试场景
+
+#### 场景1:快速验证(1000笔)
+
+```bash
+java -jar tps-test.jar \
+ -t 50 \
+ -n 1000 \
+ -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+```
+
+#### 场景2:标准压测(10000笔)
+
+```bash
+java -jar tps-test.jar \
+ -t 100 \
+ -n 10000 \
+ -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+```
+
+#### 场景3:大规模压测(50000笔)
+
+```bash
+java -jar tps-test.jar \
+ -t 200 \
+ -n 50000 \
+ -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+```
+
+#### 场景4:极限压测(100000笔)
+
+```bash
+java -jar tps-test.jar \
+ -t 500 \
+ -n 100000 \
+ -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+```
+
+#### 场景5:限速测试
+
+```bash
+# 限制 QPS 为 5000
+java -jar tps-test.jar \
+ -t 100 \
+ -n 50000 \
+ -q 5000 \
+ -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+```
+
+---
+
+## 📊 后台运行和日志管理
+
+### 1. 后台运行测试
+
+```bash
+# 使用 nohup 后台运行,输出重定向到日志文件
+nohup java -jar tps-test.jar \
+ -t 200 \
+ -n 100000 \
+ -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 \
+ > tps_test.log 2>&1 &
+
+# 查看进程
+ps aux | grep tps-test
+
+# 实时查看日志
+tail -f tps_test.log
+```
+
+### 2. 使用 screen(推荐)
+
+```bash
+# 安装 screen(如果没有)
+sudo apt install screen # Ubuntu/Debian
+sudo yum install screen # CentOS/RHEL
+
+# 创建新会话
+screen -S tps-test
+
+# 运行测试
+java -jar tps-test.jar -t 200 -n 100000 -c 0x06ac...
+
+# 断开会话(按键):Ctrl+A,然后按 D
+# 重新连接:screen -r tps-test
+# 查看所有会话:screen -ls
+```
+
+### 3. 查看测试报告
+
+```bash
+# 测试完成后,会生成报告文件
+ls -lt tps_test_report_*.txt | head -5
+
+# 查看最新报告
+cat $(ls -t tps_test_report_*.txt | head -1)
+```
+
+---
+
+## 🔧 批量测试脚本
+
+创建一个自动化测试脚本:
+
+```bash
+# 创建测试脚本
+cat > run_tps_tests.sh << 'EOF'
+#!/bin/bash
+
+# TPS 自动化测试脚本
+CONTRACT="0x06ac2fe406f1ae06494946ee281d58f1c79c39e4"
+JAR="tps-test.jar"
+
+echo "======================================"
+echo " FISCO BCOS TPS 自动化测试"
+echo "======================================"
+echo ""
+
+# 测试配置数组(线程数 交易数 描述)
+tests=(
+ "50:5000:快速验证"
+ "100:10000:基础压测"
+ "200:10000:中等压测"
+ "400:10000:高并发压测"
+)
+
+# 循环执行测试
+for test in "${tests[@]}"; do
+ IFS=':' read -r threads txs desc <<< "$test"
+
+ echo ""
+ echo "======================================"
+ echo "测试: $desc"
+ echo "并发数: $threads, 交易数: $txs"
+ echo "======================================"
+ echo ""
+
+ java -jar $JAR -t $threads -n $txs -c $CONTRACT
+
+ echo ""
+ echo "等待10秒后开始下一轮测试..."
+ sleep 10
+done
+
+echo ""
+echo "======================================"
+echo "所有测试完成!"
+echo "======================================"
+
+# 汇总报告
+echo ""
+echo "测试报告列表:"
+ls -lt tps_test_report_*.txt | head -10
+EOF
+
+# 给脚本添加执行权限
+chmod +x run_tps_tests.sh
+
+# 运行自动化测试
+./run_tps_tests.sh
+```
+
+---
+
+## 📈 分阶段找准确TPS的脚本
+
+基于文档中推荐的测试方法:
+
+```bash
+cat > find_optimal_tps.sh << 'EOF'
+#!/bin/bash
+
+# 二分法找最佳TPS脚本
+CONTRACT="0x06ac2fe406f1ae06494946ee281d58f1c79c39e4"
+JAR="tps-test.jar"
+
+echo "======================================"
+echo " 寻找最佳 TPS 配置"
+echo "======================================"
+echo ""
+
+# 阶段1:基准测试
+echo "[阶段1] 基准测试(单线程)"
+java -jar $JAR -t 1 -n 100 -c $CONTRACT
+echo ""
+read -p "按 Enter 继续..."
+
+# 阶段2:逐步增加并发
+threads_list=(50 100 200 400)
+
+for threads in "${threads_list[@]}"; do
+ echo ""
+ echo "======================================"
+ echo "[阶段2] 测试 $threads 线程"
+ echo "======================================"
+ echo ""
+
+ java -jar $JAR -t $threads -n 5000 -c $CONTRACT
+
+ echo ""
+ read -p "成功率是否 ≥99%?(y/n): " answer
+
+ if [ "$answer" != "y" ]; then
+ echo "成功率低于99%,建议使用上一个并发数"
+ last_good=$((threads / 2))
+ echo "建议最佳并发数: $last_good"
+
+ echo ""
+ read -p "是否用最佳并发数运行峰值测试?(y/n): " peak_test
+
+ if [ "$peak_test" = "y" ]; then
+ echo ""
+ echo "======================================"
+ echo "[阶段3] 峰值测试"
+ echo "======================================"
+ echo ""
+ java -jar $JAR -t $last_good -n 50000 -c $CONTRACT
+ fi
+
+ break
+ fi
+done
+
+echo ""
+echo "======================================"
+echo "测试完成!"
+echo "======================================"
+EOF
+
+chmod +x find_optimal_tps.sh
+./find_optimal_tps.sh
+```
+
+---
+
+## 🔍 监控和诊断
+
+### 1. 实时监控测试进程
+
+```bash
+# 监控 CPU 和内存
+top -p $(pgrep -f tps-test.jar)
+
+# 监控网络连接
+watch -n 1 'netstat -antp | grep 20200'
+```
+
+### 2. 查看节点日志
+
+```bash
+# 查看节点日志
+tail -f ~/fisco/nodes/*/node0/log/log* | grep -E "ERROR|TPS"
+
+# 查看交易池状态
+cd ~/fisco/console
+bash start.sh
+# 执行:getPendingTxSize
+```
+
+### 3. 系统资源监控
+
+```bash
+# 整体系统监控
+htop
+
+# 磁盘 IO
+iostat -x 1
+
+# 网络流量
+iftop -i eth0
+```
+
+---
+
+## ⚠️ 常见问题
+
+### 问题1:找不到或无法加载主类
+
+**错误信息:**
+```
+Error: Could not find or load main class com.org.fisco.TPSTest
+```
+
+**原因:** jar文件打包不正确,缺少依赖类
+
+**解决:**
+```bash
+# 1. 必须使用 fatJar 任务打包
+cd /Users/kiro/IdeaProjects/contract
+./gradlew clean fatJar
+
+# 2. 验证jar文件可以运行
+java -jar build/libs/tps-test.jar --help
+
+# 3. 重新上传到服务器
+scp build/libs/tps-test.jar root@服务器IP:~/tps-test/
+```
+
+**注意:** 不要使用 `./gradlew build`,必须使用 `./gradlew fatJar`
+
+### 问题2:找不到 config.toml
+
+**错误信息:**
+```
+错误: 找不到配置文件 config.toml
+```
+
+**解决:**
+```bash
+# 确保 config.toml 在当前目录
+cd ~/tps-test
+ls config.toml
+
+# 或者从 console 复制
+cp ~/fisco/console/conf/config.toml .
+```
+
+### 问题3:连接节点失败
+
+**错误信息:**
+```
+连接FISCO BCOS节点失败
+```
+
+**解决:**
+```bash
+# 1. 检查节点是否运行
+ps aux | grep fisco-bcos
+
+# 2. 检查端口是否监听
+netstat -tlnp | grep 20200
+
+# 3. 测试连接
+telnet 127.0.0.1 20200
+
+# 4. 修改 config.toml 使用正确的地址
+vim config.toml
+```
+
+### 问题4:内存不足
+
+**错误信息:**
+```
+java.lang.OutOfMemoryError
+```
+
+**解决:**
+```bash
+# 增加 JVM 内存
+java -Xmx4g -Xms2g -jar tps-test.jar -t 200 -n 50000 -c 0x06ac...
+```
+
+### 问题5:程序卡住不动
+
+**排查:**
+```bash
+# 1. 查看是否有错误日志
+tail -100 tps_test.log
+
+# 2. 检查网络连接
+netstat -antp | grep 20200
+
+# 3. 检查节点是否正常
+cd ~/fisco/nodes/*/node0
+tail -50 log/log*
+```
+
+---
+
+## 🎯 最佳实践
+
+### 1. 在服务器上测试的优势
+
+✅ **延迟更低**:本地网络延迟通常 < 1ms
+✅ **TPS更高**:网络不是瓶颈
+✅ **结果更准**:排除网络抖动影响
+
+### 2. 推荐的测试流程
+
+```bash
+# 第一步:快速验证
+java -jar tps-test.jar -t 50 -n 1000 -c 0x06ac...
+
+# 第二步:基础测试
+java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac...
+
+# 第三步:根据成功率调整
+# 如果成功率 ≥ 99%,增加并发到 200
+# 如果成功率 < 99%,保持或降低并发
+
+# 第四步:峰值测试
+java -jar tps-test.jar -t [最佳并发] -n 50000 -c 0x06ac...
+```
+
+### 3. 参数选择建议
+
+| 节点配置 | 推荐并发数 | 推荐交易数 |
+|---------|----------|----------|
+| 2C4G | 50-100 | 10000 |
+| 4C8G | 100-200 | 50000 |
+| 8C16G | 200-500 | 100000 |
+
+---
+
+## 📝 测试记录模板
+
+建议每次测试记录:
+
+```bash
+# 创建测试记录文件
+cat > test_record_$(date +%Y%m%d).md << 'EOF'
+# TPS测试记录
+
+## 测试日期
+2026-02-10
+
+## 测试环境
+- 服务器: 121.196.226.157
+- 节点配置: 4C8G SSD
+- enable_parallel: true
+- max_trans_num_per_block: 1000
+
+## 测试结果
+
+### 测试1
+- 命令: java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac...
+- TPS:
+- 成功率:
+- 平均延迟:
+
+### 测试2
+- 命令:
+- TPS:
+- 成功率:
+- 平均延迟:
+
+## 结论
+最佳并发数:
+峰值TPS:
+
+## 优化建议
+
+EOF
+
+vim test_record_$(date +%Y%m%d).md
+```
+
+---
+
+## 🔄 更新部署
+
+当代码有更新时:
+
+```bash
+# 本地重新打包
+cd /Users/kiro/IdeaProjects/contract
+./gradlew clean fatJar
+
+# 验证jar可以运行
+java -jar build/libs/tps-test.jar --help
+
+# 上传到服务器(覆盖旧版本)
+scp build/libs/tps-test.jar root@121.196.226.157:~/tps-test/
+
+# 服务器上重新运行测试
+ssh root@121.196.226.157
+cd ~/tps-test
+java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac...
+```
+
+---
+
+## 📞 快速命令参考
+
+```bash
+# 本地打包
+cd /Users/kiro/IdeaProjects/contract
+./gradlew clean fatJar
+
+# 验证打包(本地测试)
+java -jar build/libs/tps-test.jar --help
+
+# 上传到服务器
+scp build/libs/tps-test.jar src/main/resources/config.toml root@121.196.226.157:~/tps-test/
+
+# SSH到服务器运行
+ssh root@121.196.226.157
+cd ~/tps-test
+
+# 测试帮助
+java -jar tps-test.jar --help
+
+# 运行测试
+java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+
+# 查看报告
+cat $(ls -t tps_test_report_*.txt | head -1)
+```
+
+---
+
+## 🎓 完整部署示例
+
+### 从零开始的完整流程
+
+```bash
+# ========================================
+# 第一步:在本地打包
+# ========================================
+cd /Users/kiro/IdeaProjects/contract
+
+# 清理并打包
+./gradlew clean fatJar
+
+# 验证jar文件
+java -jar build/libs/tps-test.jar --help
+# 应该显示帮助信息,如果报错说明打包有问题
+
+
+# ========================================
+# 第二步:准备部署文件
+# ========================================
+mkdir -p deploy
+cp build/libs/tps-test.jar deploy/
+cp src/main/resources/config.toml deploy/
+
+# 查看文件
+ls -lh deploy/
+# 应该看到:
+# tps-test.jar (约 25MB)
+# config.toml
+
+
+# ========================================
+# 第三步:上传到服务器
+# ========================================
+# 方式1:使用 scp
+scp deploy/tps-test.jar deploy/config.toml root@121.196.226.157:~/tps-test/
+
+# 方式2:使用 rsync(推荐)
+rsync -avz --progress deploy/* root@121.196.226.157:~/tps-test/
+
+
+# ========================================
+# 第四步:SSH到服务器配置
+# ========================================
+ssh root@121.196.226.157
+
+# 进入目录
+cd ~/tps-test
+
+# 检查文件
+ls -lh
+# 应该看到 tps-test.jar 和 config.toml
+
+# 检查Java版本(需要JDK 11+)
+java -version
+
+# 编辑配置文件,使用本地节点地址
+vim config.toml
+# 修改为:peers=["127.0.0.1:20200"]
+
+# 测试jar文件
+java -jar tps-test.jar --help
+# 应该显示帮助信息
+
+
+# ========================================
+# 第五步:运行测试
+# ========================================
+
+# 快速验证(1000笔)
+java -jar tps-test.jar -t 50 -n 1000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+
+# 如果上面的测试成功,运行正式测试
+java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4
+
+# 查看生成的报告
+cat $(ls -t tps_test_report_*.txt | head -1)
+```
+
+---
+
+## 🔍 验证清单
+
+部署后请按此清单验证:
+
+- [ ] jar文件大小约25MB(太小说明没打包依赖)
+- [ ] 本地能运行 `java -jar build/libs/tps-test.jar --help`
+- [ ] 服务器上能显示帮助信息
+- [ ] config.toml 配置了正确的节点地址
+- [ ] 能连接到节点(显示区块高度)
+- [ ] 测试能正常运行并生成报告
+
+---
+
+**祝测试顺利!** 🚀
diff --git a/src/main/java/com/org/fisco/ParallelTransfer.java b/src/main/java/com/org/fisco/ParallelTransfer.java
new file mode 100644
index 0000000..a808ed1
--- /dev/null
+++ b/src/main/java/com/org/fisco/ParallelTransfer.java
@@ -0,0 +1,252 @@
+package org.com.fisco;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
+import org.fisco.bcos.sdk.abi.TypeReference;
+import org.fisco.bcos.sdk.abi.datatypes.Bool;
+import org.fisco.bcos.sdk.abi.datatypes.Event;
+import org.fisco.bcos.sdk.abi.datatypes.Function;
+import org.fisco.bcos.sdk.abi.datatypes.Type;
+import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
+import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
+import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
+import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
+import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple3;
+import org.fisco.bcos.sdk.client.Client;
+import org.fisco.bcos.sdk.contract.Contract;
+import org.fisco.bcos.sdk.crypto.CryptoSuite;
+import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
+import org.fisco.bcos.sdk.eventsub.EventCallback;
+import org.fisco.bcos.sdk.model.CryptoType;
+import org.fisco.bcos.sdk.model.TransactionReceipt;
+import org.fisco.bcos.sdk.model.callback.TransactionCallback;
+import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
+
+@SuppressWarnings("unchecked")
+public class ParallelTransfer extends Contract {
+ public static final String[] BINARY_ARRAY = {"608060405234801561001057600080fd5b5061067f806100206000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806335ee5f871461005c5780638a42ebe9146100d95780639b80b05014610164575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610235565b6040518082815260200191505060405180910390f35b3480156100e557600080fd5b5061014a600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506102a9565b604051808215151515815260200191505060405180910390f35b34801561017057600080fd5b5061021b600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506103c9565b604051808215151515815260200191505060405180910390f35b600080826040518082805190602001908083835b60208310151561026e5780518252602082019150602081019050602083039250610249565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b6000816000846040518082805190602001908083835b6020831015156102e457805182526020820191506020810190506020830392506102bf565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020819055507fedf5e4fbc41240253887c57b73bdead5653cd408f92653efbb6cb02835878f1d83836040518080602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610384578082015181840152602081019050610369565b50505050905090810190601f1680156103b15780820380516001836020036101000a031916815260200191505b50935050505060405180910390a16001905092915050565b6000816000856040518082805190602001908083835b60208310151561040457805182526020820191506020810190506020830392506103df565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020541015151561044557600080fd5b816000856040518082805190602001908083835b60208310151561047e5780518252602082019150602081019050602083039250610459565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060008282540392505081905550816000846040518082805190602001908083835b6020831015156104f757805182526020820191506020810190506020830392506104d2565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600082825401925050819055507f0330d309c76066247312f39e9d58dd5b00d4746f169284ac6e3835f6ea07484b848484604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156105a557808201518184015260208101905061058a565b50505050905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561060b5780820151818401526020810190506105f0565b50505050905090810190601f1680156106385780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a16001905093925050505600a165627a7a723058201e9804ebdeb9c0397abfc6f7eeadb97d2565b57eb91245f4864623800f25aa2e0029"};
+
+ public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY);
+
+ public static final String[] SM_BINARY_ARRAY = {"608060405234801561001057600080fd5b5061067f806100206000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063612d2bff1461005c578063cd93c25d1461012d578063f2f4ee6d146101aa575b600080fd5b34801561006857600080fd5b50610113600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610235565b604051808215151515815260200191505060405180910390f35b34801561013957600080fd5b50610194600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506104bf565b6040518082815260200191505060405180910390f35b3480156101b657600080fd5b5061021b600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610533565b604051808215151515815260200191505060405180910390f35b6000816000856040518082805190602001908083835b602083101515610270578051825260208201915060208101905060208303925061024b565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902054101515156102b157600080fd5b816000856040518082805190602001908083835b6020831015156102ea57805182526020820191506020810190506020830392506102c5565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060008282540392505081905550816000846040518082805190602001908083835b602083101515610363578051825260208201915060208101905060208303925061033e565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600082825401925050819055507fc2a2916bcd9b97e315313bf3748b5c215a3a399633f7d1cde7b55db8e500c784848484604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156104115780820151818401526020810190506103f6565b50505050905090810190601f16801561043e5780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561047757808201518184015260208101905061045c565b50505050905090810190601f1680156104a45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600190509392505050565b600080826040518082805190602001908083835b6020831015156104f857805182526020820191506020810190506020830392506104d3565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b6000816000846040518082805190602001908083835b60208310151561056e5780518252602082019150602081019050602083039250610549565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020819055507f0596d2b9710318c05b80b92422c73d44ef236e2d1e4f7c6f9122213d2d21216083836040518080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561060e5780820151818401526020810190506105f3565b50505050905090810190601f16801561063b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a160019050929150505600a165627a7a72305820e98be5dd9ae36682f9e427b573d5a836e23a6a087c94d68f7bc42e7e432559840029"};
+
+ public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);
+
+ public static final String[] ABI_ARRAY = {"[{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"string\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"string\"},{\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"string\"},{\"name\":\"to\",\"type\":\"string\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"from\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"to\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"user\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"SetEvent\",\"type\":\"event\"}]"};
+
+ public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY);
+
+ public static final String FUNC_BALANCEOF = "balanceOf";
+
+ public static final String FUNC_SET = "set";
+
+ public static final String FUNC_TRANSFER = "transfer";
+
+ public static final Event TRANSFEREVENT_EVENT = new Event("TransferEvent",
+ Arrays.>asList(new TypeReference() {}, new TypeReference() {}, new TypeReference() {}));
+ ;
+
+ public static final Event SETEVENT_EVENT = new Event("SetEvent",
+ Arrays.>asList(new TypeReference() {}, new TypeReference() {}));
+ ;
+
+ protected ParallelTransfer(String contractAddress, Client client, CryptoKeyPair credential) {
+ super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
+ }
+
+ public static String getBinary(CryptoSuite cryptoSuite) {
+ return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
+ }
+
+ public BigInteger balanceOf(String user) throws ContractException {
+ final Function function = new Function(FUNC_BALANCEOF,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user)),
+ Arrays.>asList(new TypeReference() {}));
+ return executeCallWithSingleValueReturn(function, BigInteger.class);
+ }
+
+ public TransactionReceipt set(String user, BigInteger balance) {
+ final Function function = new Function(
+ FUNC_SET,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user),
+ new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(balance)),
+ Collections.>emptyList());
+ return executeTransaction(function);
+ }
+
+ public byte[] set(String user, BigInteger balance, TransactionCallback callback) {
+ final Function function = new Function(
+ FUNC_SET,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user),
+ new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(balance)),
+ Collections.>emptyList());
+ return asyncExecuteTransaction(function, callback);
+ }
+
+ public String getSignedTransactionForSet(String user, BigInteger balance) {
+ final Function function = new Function(
+ FUNC_SET,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user),
+ new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(balance)),
+ Collections.>emptyList());
+ return createSignedTransaction(function);
+ }
+
+ public Tuple2 getSetInput(TransactionReceipt transactionReceipt) {
+ String data = transactionReceipt.getInput().substring(10);
+ final Function function = new Function(FUNC_SET,
+ Arrays.asList(),
+ Arrays.>asList(new TypeReference() {}, new TypeReference() {}));
+ List results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
+ return new Tuple2(
+
+ (String) results.get(0).getValue(),
+ (BigInteger) results.get(1).getValue()
+ );
+ }
+
+ public Tuple1 getSetOutput(TransactionReceipt transactionReceipt) {
+ String data = transactionReceipt.getOutput();
+ final Function function = new Function(FUNC_SET,
+ Arrays.asList(),
+ Arrays.>asList(new TypeReference() {}));
+ List results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
+ return new Tuple1(
+
+ (Boolean) results.get(0).getValue()
+ );
+ }
+
+ public TransactionReceipt transfer(String from, String to, BigInteger amount) {
+ final Function function = new Function(
+ FUNC_TRANSFER,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from),
+ new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to),
+ new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)),
+ Collections.>emptyList());
+ return executeTransaction(function);
+ }
+
+ public byte[] transfer(String from, String to, BigInteger amount, TransactionCallback callback) {
+ final Function function = new Function(
+ FUNC_TRANSFER,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from),
+ new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to),
+ new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)),
+ Collections.>emptyList());
+ return asyncExecuteTransaction(function, callback);
+ }
+
+ public String getSignedTransactionForTransfer(String from, String to, BigInteger amount) {
+ final Function function = new Function(
+ FUNC_TRANSFER,
+ Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from),
+ new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to),
+ new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)),
+ Collections.>emptyList());
+ return createSignedTransaction(function);
+ }
+
+ public Tuple3 getTransferInput(TransactionReceipt transactionReceipt) {
+ String data = transactionReceipt.getInput().substring(10);
+ final Function function = new Function(FUNC_TRANSFER,
+ Arrays.asList(),
+ Arrays.>asList(new TypeReference() {}, new TypeReference() {}, new TypeReference() {}));
+ List results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
+ return new Tuple3(
+
+ (String) results.get(0).getValue(),
+ (String) results.get(1).getValue(),
+ (BigInteger) results.get(2).getValue()
+ );
+ }
+
+ public Tuple1 getTransferOutput(TransactionReceipt transactionReceipt) {
+ String data = transactionReceipt.getOutput();
+ final Function function = new Function(FUNC_TRANSFER,
+ Arrays.asList(),
+ Arrays.>asList(new TypeReference() {}));
+ List results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
+ return new Tuple1(
+
+ (Boolean) results.get(0).getValue()
+ );
+ }
+
+ public List getTransferEventEvents(TransactionReceipt transactionReceipt) {
+ List valueList = extractEventParametersWithLog(TRANSFEREVENT_EVENT, transactionReceipt);
+ ArrayList responses = new ArrayList(valueList.size());
+ for (Contract.EventValuesWithLog eventValues : valueList) {
+ TransferEventEventResponse typedResponse = new TransferEventEventResponse();
+ typedResponse.log = eventValues.getLog();
+ typedResponse.from = (String) eventValues.getNonIndexedValues().get(0).getValue();
+ typedResponse.to = (String) eventValues.getNonIndexedValues().get(1).getValue();
+ typedResponse.amount = (BigInteger) eventValues.getNonIndexedValues().get(2).getValue();
+ responses.add(typedResponse);
+ }
+ return responses;
+ }
+
+ public void subscribeTransferEventEvent(String fromBlock, String toBlock, List otherTopics, EventCallback callback) {
+ String topic0 = eventEncoder.encode(TRANSFEREVENT_EVENT);
+ subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
+ }
+
+ public void subscribeTransferEventEvent(EventCallback callback) {
+ String topic0 = eventEncoder.encode(TRANSFEREVENT_EVENT);
+ subscribeEvent(ABI,BINARY,topic0,callback);
+ }
+
+ public List getSetEventEvents(TransactionReceipt transactionReceipt) {
+ List valueList = extractEventParametersWithLog(SETEVENT_EVENT, transactionReceipt);
+ ArrayList responses = new ArrayList(valueList.size());
+ for (Contract.EventValuesWithLog eventValues : valueList) {
+ SetEventEventResponse typedResponse = new SetEventEventResponse();
+ typedResponse.log = eventValues.getLog();
+ typedResponse.user = (String) eventValues.getNonIndexedValues().get(0).getValue();
+ typedResponse.balance = (BigInteger) eventValues.getNonIndexedValues().get(1).getValue();
+ responses.add(typedResponse);
+ }
+ return responses;
+ }
+
+ public void subscribeSetEventEvent(String fromBlock, String toBlock, List otherTopics, EventCallback callback) {
+ String topic0 = eventEncoder.encode(SETEVENT_EVENT);
+ subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
+ }
+
+ public void subscribeSetEventEvent(EventCallback callback) {
+ String topic0 = eventEncoder.encode(SETEVENT_EVENT);
+ subscribeEvent(ABI,BINARY,topic0,callback);
+ }
+
+ public static ParallelTransfer load(String contractAddress, Client client, CryptoKeyPair credential) {
+ return new ParallelTransfer(contractAddress, client, credential);
+ }
+
+ public static ParallelTransfer deploy(Client client, CryptoKeyPair credential) throws ContractException {
+ return deploy(ParallelTransfer.class, client, credential, getBinary(client.getCryptoSuite()), "");
+ }
+
+ public static class TransferEventEventResponse {
+ public TransactionReceipt.Logs log;
+
+ public String from;
+
+ public String to;
+
+ public BigInteger amount;
+ }
+
+ public static class SetEventEventResponse {
+ public TransactionReceipt.Logs log;
+
+ public String user;
+
+ public BigInteger balance;
+ }
+}
diff --git a/src/main/java/com/org/fisco/TPSTest.java b/src/main/java/com/org/fisco/TPSTest.java
new file mode 100644
index 0000000..7fbe0cc
--- /dev/null
+++ b/src/main/java/com/org/fisco/TPSTest.java
@@ -0,0 +1,436 @@
+package com.org.fisco;
+
+import org.fisco.bcos.sdk.BcosSDK;
+import org.fisco.bcos.sdk.client.Client;
+import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
+import org.fisco.bcos.sdk.model.TransactionReceipt;
+import org.com.fisco.ParallelTransfer; // 导入ParallelTransfer合约类
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * FISCO BCOS TPS压力测试工具
+ *
+ * 使用方法:
+ * 1. 先部署合约: TPSTest.deployContract()
+ * 2. 初始化账户: TPSTest.initAccounts()
+ * 3. 运行压测: TPSTest.runStressTest()
+ */
+public class TPSTest {
+
+ private BcosSDK sdk;
+ private Client client;
+ private String contractAddress;
+ private ParallelTransfer contract; // 复用合约对象,避免每次都创建
+
+ // 测试配置
+ private int threadCount = 20; // 并发线程数
+ private int totalTransactions = 100000; // 总交易数
+ private int qpsLimit = 0; // QPS限制,0表示不限制
+ private int warmupTransactions = 100; // 预热交易数
+
+ // 账户池
+ private List accountPool = new ArrayList<>();
+ private AtomicInteger accountIndex = new AtomicInteger(0);
+
+ public TPSTest(String configFile) throws Exception {
+ this.sdk = BcosSDK.build(configFile);
+ this.client = sdk.getClient(1); // v2.x使用群组ID数字,默认群组1
+ System.out.println("连接FISCO BCOS节点成功");
+ System.out.println("当前区块高度: " + client.getBlockNumber());
+ }
+
+ /**
+ * 设置测试参数
+ */
+ public void setTestParams(int threadCount, int totalTransactions, int qpsLimit) {
+ this.threadCount = threadCount;
+ this.totalTransactions = totalTransactions;
+ this.qpsLimit = qpsLimit;
+ }
+
+ /**
+ * 步骤1: 部署压测合约
+ */
+ public String deployContract() throws Exception {
+ System.out.println("\n[1/3] 部署ParallelTransfer合约...");
+
+ CryptoKeyPair keyPair = client.getCryptoSuite().getCryptoKeyPair();
+
+ // 注意: 需要先使用控制台编译合约生成Java类
+ // 这里假设已经生成了ParallelTransfer.java
+ // ParallelTransfer contract = ParallelTransfer.deploy(client, keyPair);
+ // this.contractAddress = contract.getContractAddress();
+
+ // 如果手动已经部署,可以直接设置地址
+ this.contractAddress = "0x06ac2fe406f1ae06494946ee281d58f1c79c39e4";
+
+ System.out.println("合约部署成功!");
+ System.out.println("合约地址: " + contractAddress);
+
+ return contractAddress;
+ }
+
+ /**
+ * 步骤2: 初始化测试账户
+ */
+ public void initAccounts(int accountCount) {
+ System.out.println("\n[2/3] 初始化测试账户...");
+ System.out.println("生成 " + accountCount + " 个测试账户...");
+
+ for (int i = 0; i < accountCount; i++) {
+ accountPool.add("user_" + String.format("%06d", i));
+ }
+
+ System.out.println("账户初始化完成! 账户数: " + accountPool.size());
+ }
+
+ /**
+ * 生成账户列表(不初始化余额,用于已通过脚本初始化的场景)
+ */
+ public void generateAccountList(int accountCount) {
+ for (int i = 0; i < accountCount; i++) {
+ accountPool.add("user_" + String.format("%06d", i));
+ }
+ System.out.println("已生成 " + accountPool.size() + " 个测试账户");
+ }
+
+ /**
+ * 步骤3: 运行压力测试
+ */
+ public TPSTestResult runStressTest() throws Exception {
+ System.out.println("\n[3/3] 开始压力测试...");
+ System.out.println("测试配置:");
+ System.out.println(" - 并发线程数: " + threadCount);
+ System.out.println(" - 总交易数: " + totalTransactions);
+ System.out.println(" - QPS限制: " + (qpsLimit > 0 ? qpsLimit : "无限制"));
+ System.out.println(" - 预热交易数: " + warmupTransactions);
+
+ TPSTestResult result = new TPSTestResult(threadCount, qpsLimit);
+
+ // 预热
+ if (warmupTransactions > 0) {
+ System.out.println("\n正在预热 (" + warmupTransactions + " 笔交易)...");
+ runTestPhase(warmupTransactions, result, true);
+ System.out.println("预热完成!");
+ }
+
+ // 正式测试
+ System.out.println("\n开始正式压测...");
+ System.out.println("实时TPS监控 (每5秒更新):");
+
+ // 重置统计
+ TPSTestResult finalResult = new TPSTestResult(threadCount, qpsLimit);
+ final int finalTotalTx = totalTransactions;
+
+ // 启动监控线程
+ ScheduledExecutorService monitor = Executors.newScheduledThreadPool(1);
+ monitor.scheduleAtFixedRate(() -> {
+ System.out.printf(" 当前进度: %d/%d | 实时TPS: %.2f | 成功率: %.2f%%\n",
+ finalResult.getTotalTransactions(), finalTotalTx,
+ finalResult.getRealtimeTPS(), finalResult.calculateSuccessRate());
+ }, 5, 5, TimeUnit.SECONDS);
+
+ // 执行测试
+ runTestPhase(totalTransactions, finalResult, false);
+
+ // 停止监控
+ monitor.shutdown();
+
+ finalResult.markEnd();
+
+ return finalResult;
+ }
+
+ /**
+ * 执行测试阶段
+ */
+ private void runTestPhase(int txCount, TPSTestResult result, boolean isWarmup) throws Exception {
+ ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+ CountDownLatch latch = new CountDownLatch(txCount);
+
+ // QPS限流器
+ Semaphore rateLimiter = qpsLimit > 0 ? new Semaphore(qpsLimit) : null;
+
+ if (qpsLimit > 0) {
+ // 启动令牌补充线程
+ ScheduledExecutorService refiller = Executors.newScheduledThreadPool(1);
+ refiller.scheduleAtFixedRate(() -> {
+ int available = rateLimiter.availablePermits();
+ if (available < qpsLimit) {
+ rateLimiter.release(qpsLimit - available);
+ }
+ }, 0, 1, TimeUnit.SECONDS);
+ }
+
+ Random random = new Random();
+
+ // 提交所有交易任务
+ for (int i = 0; i < txCount; i++) {
+ executor.submit(() -> {
+ try {
+ // QPS限流
+ if (rateLimiter != null) {
+ rateLimiter.acquire();
+ }
+
+ long startTime = System.currentTimeMillis();
+
+ // 随机选择两个账户进行转账
+ String fromAccount = getRandomAccount();
+ String toAccount = getRandomAccount();
+ int amount = random.nextInt(100) + 1;
+
+ // 发送交易
+ boolean success = sendTransferTransaction(fromAccount, toAccount, amount);
+
+ long endTime = System.currentTimeMillis();
+ long latency = endTime - startTime;
+
+ if (!isWarmup) {
+ if (success) {
+ result.recordSuccess(latency);
+ } else {
+ result.recordFailure("交易执行失败");
+ }
+ }
+
+ } catch (Exception e) {
+ if (!isWarmup) {
+ result.recordFailure(e.getMessage());
+ }
+ } finally {
+ latch.countDown();
+ }
+ });
+ }
+
+ // 等待所有交易完成
+ latch.await();
+ executor.shutdown();
+ executor.awaitTermination(10, TimeUnit.MINUTES);
+ }
+
+ /**
+ * 初始化合约对象(只调用一次)
+ */
+ private void initContract() throws Exception {
+ CryptoKeyPair keyPair = client.getCryptoSuite().getCryptoKeyPair();
+ this.contract = ParallelTransfer.load(contractAddress, client, keyPair);
+ System.out.println("合约对象初始化完成");
+ }
+
+ /**
+ * 发送转账交易(复用contract对象)
+ */
+ private boolean sendTransferTransaction(String from, String to, int amount) {
+ try {
+ TransactionReceipt receipt = contract.transfer(from, to, BigInteger.valueOf(amount));
+ if (!receipt.isStatusOK()) {
+ System.err.println("交易失败 - Status: " + receipt.getStatus() +
+ ", Message: " + receipt.getMessage());
+ }
+ return receipt.isStatusOK();
+ } catch (Exception e) {
+ System.err.println("交易异常: " + e.getClass().getSimpleName() + " - " + e.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * 随机获取一个账户
+ */
+ private String getRandomAccount() {
+ int index = accountIndex.getAndIncrement() % accountPool.size();
+ return accountPool.get(index);
+ }
+
+ /**
+ * 关闭连接
+ */
+ public void close() {
+ // SDK 2.x不需要显式关闭,会自动清理资源
+ // 如果需要,可以让JVM自动回收
+ }
+
+ /**
+ * 打印使用帮助
+ */
+ private static void printUsage() {
+ System.out.println("用法: java -jar tps-test.jar [选项]");
+ System.out.println();
+ System.out.println("选项:");
+ System.out.println(" -t, --threads <数量> 并发线程数 (默认: 100)");
+ System.out.println(" -n, --transactions <数量> 总交易数 (默认: 10000)");
+ System.out.println(" -q, --qps <限制> QPS限制,0表示不限制 (默认: 0)");
+ System.out.println(" -c, --contract <地址> 合约地址 (必填)");
+ System.out.println(" -a, --accounts <数量> 测试账户数 (默认: 100)");
+ System.out.println(" -h, --help 显示此帮助信息");
+ System.out.println();
+ System.out.println("示例:");
+ System.out.println(" # 使用默认参数");
+ System.out.println(" java -jar tps-test.jar -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4");
+ System.out.println();
+ System.out.println(" # 自定义参数");
+ System.out.println(" java -jar tps-test.jar -t 200 -n 50000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4");
+ System.out.println();
+ System.out.println(" # 使用 gradlew 运行");
+ System.out.println(" ./gradlew run --args=\"-t 200 -n 50000 -c 0x06ac...\"");
+ }
+
+ /**
+ * 主测试流程(支持命令行参数)
+ */
+ public static void main(String[] args) {
+ TPSTest tester = null;
+ try {
+ // 解析命令行参数
+ int threadCount = 100; // 默认并发数
+ int totalTransactions = 10000; // 默认交易总数
+ int qpsLimit = 0; // 默认不限速
+ String contractAddress = null; // 合约地址(必填)
+ int accountCount = 100; // 默认账户数
+
+ // 解析参数
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+
+ if (arg.equals("-h") || arg.equals("--help")) {
+ printUsage();
+ return;
+ }
+
+ if (i + 1 < args.length) {
+ String value = args[i + 1];
+
+ switch (arg) {
+ case "-t":
+ case "--threads":
+ threadCount = Integer.parseInt(value);
+ i++;
+ break;
+ case "-n":
+ case "--transactions":
+ totalTransactions = Integer.parseInt(value);
+ i++;
+ break;
+ case "-q":
+ case "--qps":
+ qpsLimit = Integer.parseInt(value);
+ i++;
+ break;
+ case "-c":
+ case "--contract":
+ contractAddress = value;
+ i++;
+ break;
+ case "-a":
+ case "--accounts":
+ accountCount = Integer.parseInt(value);
+ i++;
+ break;
+ default:
+ System.err.println("未知参数: " + arg);
+ printUsage();
+ System.exit(1);
+ }
+ }
+ }
+
+ // 验证必填参数
+ if (contractAddress == null || contractAddress.isEmpty()) {
+ System.err.println("错误: 必须指定合约地址 (-c 或 --contract)");
+ System.err.println();
+ printUsage();
+ System.exit(1);
+ }
+
+ // 验证参数范围
+ if (threadCount <= 0 || threadCount > 10000) {
+ System.err.println("错误: 并发线程数必须在 1-10000 之间");
+ System.exit(1);
+ }
+ if (totalTransactions <= 0) {
+ System.err.println("错误: 交易总数必须大于 0");
+ System.exit(1);
+ }
+
+ System.out.println("========================================");
+ System.out.println(" FISCO BCOS TPS压力测试工具");
+ System.out.println("========================================\n");
+
+ System.out.println("测试参数:");
+ System.out.println(" 并发线程数: " + threadCount);
+ System.out.println(" 总交易数: " + totalTransactions);
+ System.out.println(" QPS限制: " + (qpsLimit > 0 ? qpsLimit : "无限制"));
+ System.out.println(" 合约地址: " + contractAddress);
+ System.out.println(" 测试账户数: " + accountCount);
+ System.out.println();
+
+ // 1. 初始化(支持从当前目录或resources目录读取配置)
+ String configFile = "config.toml";
+ if (!new java.io.File(configFile).exists()) {
+ configFile = "src/main/resources/config.toml";
+ }
+ if (!new java.io.File(configFile).exists()) {
+ System.err.println("错误: 找不到配置文件 config.toml");
+ System.err.println("请确保当前目录或 src/main/resources/ 目录下有 config.toml 文件");
+ System.exit(1);
+ }
+
+ tester = new TPSTest(configFile);
+
+ // 2. 设置测试参数
+ tester.setTestParams(threadCount, totalTransactions, qpsLimit);
+
+ // 3. 设置合约地址
+ tester.contractAddress = contractAddress;
+ System.out.println("使用合约地址: " + tester.contractAddress);
+
+ // 4. 初始化合约对象(重要:只创建一次,避免资源泄漏)
+ tester.initContract();
+
+ // 5. 生成测试账户列表(账户余额已通过脚本初始化)
+ System.out.println("\n生成测试账户列表...");
+ tester.generateAccountList(accountCount);
+ System.out.println("账户列表生成完成,账户余额应已通过 init_accounts.sh 脚本初始化");
+
+ // 6. 运行压测
+ TPSTestResult result = tester.runStressTest();
+
+ // 7. 输出报告
+ System.out.println("\n" + result.generateReport());
+
+ // 8. 保存报告到文件
+ String reportFile = "tps_test_report_" + System.currentTimeMillis() + ".txt";
+ java.nio.file.Files.write(
+ java.nio.file.Paths.get(reportFile),
+ result.generateReport().getBytes()
+ );
+ System.out.println("测试报告已保存到: " + reportFile);
+
+ } catch (NumberFormatException e) {
+ System.err.println("错误: 参数格式不正确");
+ System.err.println(e.getMessage());
+ printUsage();
+ System.exit(1);
+ } catch (Exception e) {
+ System.err.println("测试失败: " + e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ } finally {
+ if (tester != null) {
+ tester.close();
+ }
+ // 强制退出程序,避免SDK的后台线程一直运行
+ System.out.println("\n测试完成,退出程序...");
+ System.exit(0);
+ }
+ }
+}
+
diff --git a/src/main/java/com/org/fisco/TPSTestResult.java b/src/main/java/com/org/fisco/TPSTestResult.java
new file mode 100644
index 0000000..49319ad
--- /dev/null
+++ b/src/main/java/com/org/fisco/TPSTestResult.java
@@ -0,0 +1,184 @@
+package com.org.fisco;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * TPS测试结果统计类
+ */
+public class TPSTestResult {
+
+ private long startTime;
+ private long endTime;
+ private int threadCount;
+ private int qpsLimit;
+
+ // 交易统计
+ private AtomicInteger totalTransactions = new AtomicInteger(0);
+ private AtomicInteger successTransactions = new AtomicInteger(0);
+ private AtomicInteger failedTransactions = new AtomicInteger(0);
+
+ // 延迟统计
+ private List latencies = Collections.synchronizedList(new ArrayList<>());
+ private AtomicLong totalLatency = new AtomicLong(0);
+
+ // 错误信息
+ private List errors = Collections.synchronizedList(new ArrayList<>());
+
+ public TPSTestResult(int threadCount, int qpsLimit) {
+ this.threadCount = threadCount;
+ this.qpsLimit = qpsLimit;
+ this.startTime = System.currentTimeMillis();
+ }
+
+ /**
+ * 记录成功交易
+ */
+ public void recordSuccess(long latency) {
+ totalTransactions.incrementAndGet();
+ successTransactions.incrementAndGet();
+ latencies.add(latency);
+ totalLatency.addAndGet(latency);
+ }
+
+ /**
+ * 记录失败交易
+ */
+ public void recordFailure(String errorMsg) {
+ totalTransactions.incrementAndGet();
+ failedTransactions.incrementAndGet();
+ if (errors.size() < 100) { // 只保存前100条错误
+ errors.add(errorMsg);
+ }
+ }
+
+ /**
+ * 标记测试结束
+ */
+ public void markEnd() {
+ this.endTime = System.currentTimeMillis();
+ }
+
+ /**
+ * 计算TPS
+ */
+ public double calculateTPS() {
+ if (endTime == 0) {
+ endTime = System.currentTimeMillis();
+ }
+ double duration = (endTime - startTime) / 1000.0;
+ return duration > 0 ? successTransactions.get() / duration : 0;
+ }
+
+ /**
+ * 计算实时TPS
+ */
+ public double getRealtimeTPS() {
+ long currentTime = System.currentTimeMillis();
+ double duration = (currentTime - startTime) / 1000.0;
+ return duration > 0 ? successTransactions.get() / duration : 0;
+ }
+
+ /**
+ * 计算成功率
+ */
+ public double calculateSuccessRate() {
+ int total = totalTransactions.get();
+ return total > 0 ? (successTransactions.get() * 100.0 / total) : 0;
+ }
+
+ /**
+ * 计算平均延迟
+ */
+ public double calculateAverageLatency() {
+ int count = successTransactions.get();
+ return count > 0 ? totalLatency.get() / (double)count : 0;
+ }
+
+ /**
+ * 计算百分位延迟
+ */
+ public long calculatePercentileLatency(int percentile) {
+ if (latencies.isEmpty()) {
+ return 0;
+ }
+
+ List sortedLatencies = new ArrayList<>(latencies);
+ Collections.sort(sortedLatencies);
+
+ int index = (int)Math.ceil(sortedLatencies.size() * percentile / 100.0) - 1;
+ index = Math.max(0, Math.min(index, sortedLatencies.size() - 1));
+
+ return sortedLatencies.get(index);
+ }
+
+ /**
+ * 获取总交易数
+ */
+ public int getTotalTransactions() {
+ return totalTransactions.get();
+ }
+
+ /**
+ * 生成测试报告
+ */
+ public String generateReport() {
+ StringBuilder report = new StringBuilder();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ double duration = (endTime - startTime) / 1000.0;
+ double tps = calculateTPS();
+ double successRate = calculateSuccessRate();
+ double avgLatency = calculateAverageLatency();
+
+ report.append("========================================\n");
+ report.append(" FISCO BCOS TPS测试报告\n");
+ report.append("========================================\n\n");
+
+ report.append("测试配置:\n");
+ report.append(" 开始时间: ").append(sdf.format(new Date(startTime))).append("\n");
+ report.append(" 结束时间: ").append(sdf.format(new Date(endTime))).append("\n");
+ report.append(" 测试时长: ").append(String.format("%.2f", duration)).append(" 秒\n");
+ report.append(" 并发线程数: ").append(threadCount).append("\n");
+ report.append(" QPS限制: ").append(qpsLimit > 0 ? qpsLimit : "无限制").append("\n");
+ report.append("\n");
+
+ report.append("交易统计:\n");
+ report.append(" 总交易数: ").append(totalTransactions.get()).append("\n");
+ report.append(" 成功交易: ").append(successTransactions.get()).append("\n");
+ report.append(" 失败交易: ").append(failedTransactions.get()).append("\n");
+ report.append(" 成功率: ").append(String.format("%.2f%%", successRate)).append("\n");
+ report.append("\n");
+
+ report.append("性能指标:\n");
+ report.append(" ★ TPS (每秒交易数): ").append(String.format("%.2f", tps)).append("\n");
+ report.append(" 平均延迟: ").append(String.format("%.2f", avgLatency)).append(" ms\n");
+
+ if (!latencies.isEmpty()) {
+ report.append(" 中位数延迟: ").append(calculatePercentileLatency(50)).append(" ms\n");
+ report.append(" P95延迟: ").append(calculatePercentileLatency(95)).append(" ms\n");
+ report.append(" P99延迟: ").append(calculatePercentileLatency(99)).append(" ms\n");
+ }
+
+ report.append("\n");
+ report.append("报告时间: ").append(sdf.format(new Date())).append("\n");
+ report.append("========================================\n");
+
+ // 如果有错误,显示前10条
+ if (!errors.isEmpty()) {
+ report.append("\n错误示例 (前10条):\n");
+ int count = Math.min(10, errors.size());
+ for (int i = 0; i < count; i++) {
+ report.append(" ").append(i + 1).append(". ").append(errors.get(i)).append("\n");
+ }
+ }
+
+ return report.toString();
+ }
+}
+
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..67d15fd
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tps/tps_test_report_1770703533286.txt b/tps/tps_test_report_1770703533286.txt
new file mode 100644
index 0000000..2f2b29e
--- /dev/null
+++ b/tps/tps_test_report_1770703533286.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:04:09
+ 结束时间: 2026-02-10 14:05:33
+ 测试时长: 83.62 秒
+ 并发线程数: 100
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 119.59
+ 平均延迟: 827.52 ms
+ 中位数延迟: 651 ms
+ P95延迟: 1503 ms
+ P99延迟: 4310 ms
+
+报告时间: 2026-02-10 14:05:33
+========================================
diff --git a/tps/tps_test_report_1770703614878.txt b/tps/tps_test_report_1770703614878.txt
new file mode 100644
index 0000000..0a96e34
--- /dev/null
+++ b/tps/tps_test_report_1770703614878.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:06:06
+ 结束时间: 2026-02-10 14:06:54
+ 测试时长: 48.66 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 205.51
+ 平均延迟: 1553.64 ms
+ 中位数延迟: 940 ms
+ P95延迟: 3028 ms
+ P99延迟: 16673 ms
+
+报告时间: 2026-02-10 14:06:54
+========================================
diff --git a/tps/tps_test_report_1770703670003.txt b/tps/tps_test_report_1770703670003.txt
new file mode 100644
index 0000000..59ca46f
--- /dev/null
+++ b/tps/tps_test_report_1770703670003.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:07:12
+ 结束时间: 2026-02-10 14:07:49
+ 测试时长: 37.26 秒
+ 并发线程数: 1000
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9611
+ 失败交易: 389
+ 成功率: 96.11%
+
+性能指标:
+ ★ TPS (每秒交易数): 257.98
+ 平均延迟: 2229.50 ms
+ 中位数延迟: 1436 ms
+ P95延迟: 5189 ms
+ P99延迟: 24093 ms
+
+报告时间: 2026-02-10 14:07:50
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770703725649.txt b/tps/tps_test_report_1770703725649.txt
new file mode 100644
index 0000000..7d1d735
--- /dev/null
+++ b/tps/tps_test_report_1770703725649.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:08:12
+ 结束时间: 2026-02-10 14:08:45
+ 测试时长: 33.02 秒
+ 并发线程数: 600
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9963
+ 失败交易: 37
+ 成功率: 99.63%
+
+性能指标:
+ ★ TPS (每秒交易数): 301.69
+ 平均延迟: 1378.41 ms
+ 中位数延迟: 838 ms
+ P95延迟: 2297 ms
+ P99延迟: 21355 ms
+
+报告时间: 2026-02-10 14:08:45
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770703784697.txt b/tps/tps_test_report_1770703784697.txt
new file mode 100644
index 0000000..132b344
--- /dev/null
+++ b/tps/tps_test_report_1770703784697.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:09:10
+ 结束时间: 2026-02-10 14:09:44
+ 测试时长: 33.79 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9974
+ 失败交易: 26
+ 成功率: 99.74%
+
+性能指标:
+ ★ TPS (每秒交易数): 295.14
+ 平均延迟: 1494.69 ms
+ 中位数延迟: 823 ms
+ P95延迟: 2672 ms
+ P99延迟: 20214 ms
+
+报告时间: 2026-02-10 14:09:44
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770703851041.txt b/tps/tps_test_report_1770703851041.txt
new file mode 100644
index 0000000..a10e7a5
--- /dev/null
+++ b/tps/tps_test_report_1770703851041.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:09:59
+ 结束时间: 2026-02-10 14:10:51
+ 测试时长: 51.05 秒
+ 并发线程数: 400
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 195.90
+ 平均延迟: 1424.86 ms
+ 中位数延迟: 765 ms
+ P95延迟: 1565 ms
+ P99延迟: 19399 ms
+
+报告时间: 2026-02-10 14:10:51
+========================================
diff --git a/tps/tps_test_report_1770703907344.txt b/tps/tps_test_report_1770703907344.txt
new file mode 100644
index 0000000..0754315
--- /dev/null
+++ b/tps/tps_test_report_1770703907344.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:11:09
+ 结束时间: 2026-02-10 14:11:47
+ 测试时长: 37.77 秒
+ 并发线程数: 450
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 264.80
+ 平均延迟: 1437.83 ms
+ 中位数延迟: 748 ms
+ P95延迟: 4032 ms
+ P99延迟: 14454 ms
+
+报告时间: 2026-02-10 14:11:47
+========================================
diff --git a/tps/tps_test_report_1770703956143.txt b/tps/tps_test_report_1770703956143.txt
new file mode 100644
index 0000000..e149b87
--- /dev/null
+++ b/tps/tps_test_report_1770703956143.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:12:06
+ 结束时间: 2026-02-10 14:12:36
+ 测试时长: 29.63 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 337.52
+ 平均延迟: 1453.46 ms
+ 中位数延迟: 963 ms
+ P95延迟: 1863 ms
+ P99延迟: 20871 ms
+
+报告时间: 2026-02-10 14:12:36
+========================================
diff --git a/tps/tps_test_report_1770703997870.txt b/tps/tps_test_report_1770703997870.txt
new file mode 100644
index 0000000..024b6b2
--- /dev/null
+++ b/tps/tps_test_report_1770703997870.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:12:45
+ 结束时间: 2026-02-10 14:13:17
+ 测试时长: 32.47 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9973
+ 失败交易: 27
+ 成功率: 99.73%
+
+性能指标:
+ ★ TPS (每秒交易数): 307.19
+ 平均延迟: 1366.54 ms
+ 中位数延迟: 739 ms
+ P95延迟: 2044 ms
+ P99延迟: 19454 ms
+
+报告时间: 2026-02-10 14:13:17
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770704037174.txt b/tps/tps_test_report_1770704037174.txt
new file mode 100644
index 0000000..90f958e
--- /dev/null
+++ b/tps/tps_test_report_1770704037174.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:13:30
+ 结束时间: 2026-02-10 14:13:57
+ 测试时长: 26.30 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 380.26
+ 平均延迟: 1285.29 ms
+ 中位数延迟: 881 ms
+ P95延迟: 2683 ms
+ P99延迟: 15799 ms
+
+报告时间: 2026-02-10 14:13:57
+========================================
diff --git a/tps/tps_test_report_1770704089881.txt b/tps/tps_test_report_1770704089881.txt
new file mode 100644
index 0000000..43ed924
--- /dev/null
+++ b/tps/tps_test_report_1770704089881.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:14:17
+ 结束时间: 2026-02-10 14:14:49
+ 测试时长: 32.00 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9948
+ 失败交易: 52
+ 成功率: 99.48%
+
+性能指标:
+ ★ TPS (每秒交易数): 310.87
+ 平均延迟: 1362.70 ms
+ 中位数延迟: 870 ms
+ P95延迟: 1553 ms
+ P99延迟: 21603 ms
+
+报告时间: 2026-02-10 14:14:49
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770704145861.txt b/tps/tps_test_report_1770704145861.txt
new file mode 100644
index 0000000..a159345
--- /dev/null
+++ b/tps/tps_test_report_1770704145861.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:15:18
+ 结束时间: 2026-02-10 14:15:45
+ 测试时长: 27.54 秒
+ 并发线程数: 450
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 363.17
+ 平均延迟: 1137.05 ms
+ 中位数延迟: 755 ms
+ P95延迟: 1664 ms
+ P99延迟: 13455 ms
+
+报告时间: 2026-02-10 14:15:45
+========================================
diff --git a/tps/tps_test_report_1770704200012.txt b/tps/tps_test_report_1770704200012.txt
new file mode 100644
index 0000000..3363203
--- /dev/null
+++ b/tps/tps_test_report_1770704200012.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:15:55
+ 结束时间: 2026-02-10 14:16:39
+ 测试时长: 44.96 秒
+ 并发线程数: 450
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 222.42
+ 平均延迟: 1618.69 ms
+ 中位数延迟: 817 ms
+ P95延迟: 6077 ms
+ P99延迟: 20877 ms
+
+报告时间: 2026-02-10 14:16:40
+========================================
diff --git a/tps/tps_test_report_1770704258358.txt b/tps/tps_test_report_1770704258358.txt
new file mode 100644
index 0000000..6006125
--- /dev/null
+++ b/tps/tps_test_report_1770704258358.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:16:51
+ 结束时间: 2026-02-10 14:17:38
+ 测试时长: 47.00 秒
+ 并发线程数: 450
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 212.76
+ 平均延迟: 1825.84 ms
+ 中位数延迟: 885 ms
+ P95延迟: 5084 ms
+ P99延迟: 16504 ms
+
+报告时间: 2026-02-10 14:17:38
+========================================
diff --git a/tps/tps_test_report_1770704309502.txt b/tps/tps_test_report_1770704309502.txt
new file mode 100644
index 0000000..c3527b2
--- /dev/null
+++ b/tps/tps_test_report_1770704309502.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:17:49
+ 结束时间: 2026-02-10 14:18:29
+ 测试时长: 40.11 秒
+ 并发线程数: 450
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 249.33
+ 平均延迟: 1341.90 ms
+ 中位数延迟: 738 ms
+ P95延迟: 3098 ms
+ P99延迟: 12218 ms
+
+报告时间: 2026-02-10 14:18:29
+========================================
diff --git a/tps/tps_test_report_1770704940931.txt b/tps/tps_test_report_1770704940931.txt
new file mode 100644
index 0000000..abb7fb4
--- /dev/null
+++ b/tps/tps_test_report_1770704940931.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:23:37
+ 结束时间: 2026-02-10 14:29:00
+ 测试时长: 323.22 秒
+ 并发线程数: 400
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 309.38
+ 平均延迟: 1289.31 ms
+ 中位数延迟: 782 ms
+ P95延迟: 2880 ms
+ P99延迟: 13821 ms
+
+报告时间: 2026-02-10 14:29:00
+========================================
diff --git a/tps/tps_test_report_1770705295952.txt b/tps/tps_test_report_1770705295952.txt
new file mode 100644
index 0000000..77b98a4
--- /dev/null
+++ b/tps/tps_test_report_1770705295952.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:29:13
+ 结束时间: 2026-02-10 14:34:55
+ 测试时长: 342.83 秒
+ 并发线程数: 400
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 291.69
+ 平均延迟: 1336.06 ms
+ 中位数延迟: 772 ms
+ P95延迟: 4855 ms
+ P99延迟: 11606 ms
+
+报告时间: 2026-02-10 14:34:56
+========================================
diff --git a/tps/tps_test_report_1770705629081.txt b/tps/tps_test_report_1770705629081.txt
new file mode 100644
index 0000000..d5340d2
--- /dev/null
+++ b/tps/tps_test_report_1770705629081.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:35:06
+ 结束时间: 2026-02-10 14:40:29
+ 测试时长: 322.86 秒
+ 并发线程数: 400
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 309.73
+ 平均延迟: 1272.72 ms
+ 中位数延迟: 767 ms
+ P95延迟: 2771 ms
+ P99延迟: 12284 ms
+
+报告时间: 2026-02-10 14:40:29
+========================================
diff --git a/tps/tps_test_report_1770705915424.txt b/tps/tps_test_report_1770705915424.txt
new file mode 100644
index 0000000..2ad52ef
--- /dev/null
+++ b/tps/tps_test_report_1770705915424.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:41:15
+ 结束时间: 2026-02-10 14:45:15
+ 测试时长: 240.15 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 416.41
+ 平均延迟: 1170.71 ms
+ 中位数延迟: 772 ms
+ P95延迟: 1779 ms
+ P99延迟: 12080 ms
+
+报告时间: 2026-02-10 14:45:15
+========================================
diff --git a/tps/tps_test_report_1770706188440.txt b/tps/tps_test_report_1770706188440.txt
new file mode 100644
index 0000000..0e8da46
--- /dev/null
+++ b/tps/tps_test_report_1770706188440.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:45:27
+ 结束时间: 2026-02-10 14:49:48
+ 测试时长: 260.41 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 384.01
+ 平均延迟: 1241.56 ms
+ 中位数延迟: 757 ms
+ P95延迟: 2237 ms
+ P99延迟: 13599 ms
+
+报告时间: 2026-02-10 14:49:48
+========================================
diff --git a/tps/tps_test_report_1770706244570.txt b/tps/tps_test_report_1770706244570.txt
new file mode 100644
index 0000000..e371055
--- /dev/null
+++ b/tps/tps_test_report_1770706244570.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:49:59
+ 结束时间: 2026-02-10 14:50:44
+ 测试时长: 45.36 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 220.48
+ 平均延迟: 1668.52 ms
+ 中位数延迟: 829 ms
+ P95延迟: 3114 ms
+ P99延迟: 17204 ms
+
+报告时间: 2026-02-10 14:50:44
+========================================
diff --git a/tps/tps_test_report_1770706296093.txt b/tps/tps_test_report_1770706296093.txt
new file mode 100644
index 0000000..372ebfd
--- /dev/null
+++ b/tps/tps_test_report_1770706296093.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:50:54
+ 结束时间: 2026-02-10 14:51:36
+ 测试时长: 41.70 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 239.84
+ 平均延迟: 1534.05 ms
+ 中位数延迟: 806 ms
+ P95延迟: 4673 ms
+ P99延迟: 15583 ms
+
+报告时间: 2026-02-10 14:51:36
+========================================
diff --git a/tps/tps_test_report_1770706337416.txt b/tps/tps_test_report_1770706337416.txt
new file mode 100644
index 0000000..9da635e
--- /dev/null
+++ b/tps/tps_test_report_1770706337416.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:51:52
+ 结束时间: 2026-02-10 14:52:17
+ 测试时长: 24.52 秒
+ 并发线程数: 600
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 407.90
+ 平均延迟: 1313.38 ms
+ 中位数延迟: 805 ms
+ P95延迟: 2667 ms
+ P99延迟: 16736 ms
+
+报告时间: 2026-02-10 14:52:17
+========================================
diff --git a/tps/tps_test_report_1770706383079.txt b/tps/tps_test_report_1770706383079.txt
new file mode 100644
index 0000000..f9b2b22
--- /dev/null
+++ b/tps/tps_test_report_1770706383079.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:52:37
+ 结束时间: 2026-02-10 14:53:03
+ 测试时长: 25.28 秒
+ 并发线程数: 600
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 395.65
+ 平均延迟: 1393.95 ms
+ 中位数延迟: 884 ms
+ P95延迟: 2074 ms
+ P99延迟: 17573 ms
+
+报告时间: 2026-02-10 14:53:03
+========================================
diff --git a/tps/tps_test_report_1770706440306.txt b/tps/tps_test_report_1770706440306.txt
new file mode 100644
index 0000000..8b8bb2a
--- /dev/null
+++ b/tps/tps_test_report_1770706440306.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:53:19
+ 结束时间: 2026-02-10 14:54:00
+ 测试时长: 40.41 秒
+ 并发线程数: 1000
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9396
+ 失败交易: 604
+ 成功率: 93.96%
+
+性能指标:
+ ★ TPS (每秒交易数): 232.53
+ 平均延迟: 1836.32 ms
+ 中位数延迟: 869 ms
+ P95延迟: 7908 ms
+ P99延迟: 22325 ms
+
+报告时间: 2026-02-10 14:54:00
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770706497453.txt b/tps/tps_test_report_1770706497453.txt
new file mode 100644
index 0000000..e27cd35
--- /dev/null
+++ b/tps/tps_test_report_1770706497453.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:54:24
+ 结束时间: 2026-02-10 14:54:57
+ 测试时长: 32.47 秒
+ 并发线程数: 800
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 9988
+ 失败交易: 12
+ 成功率: 99.88%
+
+性能指标:
+ ★ TPS (每秒交易数): 307.64
+ 平均延迟: 1746.19 ms
+ 中位数延迟: 916 ms
+ P95延迟: 3013 ms
+ P99延迟: 25522 ms
+
+报告时间: 2026-02-10 14:54:57
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770706529950.txt b/tps/tps_test_report_1770706529950.txt
new file mode 100644
index 0000000..186268c
--- /dev/null
+++ b/tps/tps_test_report_1770706529950.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:55:09
+ 结束时间: 2026-02-10 14:55:29
+ 测试时长: 20.70 秒
+ 并发线程数: 600
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 483.14
+ 平均延迟: 1142.64 ms
+ 中位数延迟: 775 ms
+ P95延迟: 1565 ms
+ P99延迟: 12320 ms
+
+报告时间: 2026-02-10 14:55:29
+========================================
diff --git a/tps/tps_test_report_1770706574616.txt b/tps/tps_test_report_1770706574616.txt
new file mode 100644
index 0000000..0e73606
--- /dev/null
+++ b/tps/tps_test_report_1770706574616.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:55:47
+ 结束时间: 2026-02-10 14:56:14
+ 测试时长: 27.47 秒
+ 并发线程数: 600
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 10000
+ 成功交易: 10000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 364.07
+ 平均延迟: 1467.61 ms
+ 中位数延迟: 809 ms
+ P95延迟: 2798 ms
+ P99延迟: 22015 ms
+
+报告时间: 2026-02-10 14:56:14
+========================================
diff --git a/tps/tps_test_report_1770706999829.txt b/tps/tps_test_report_1770706999829.txt
new file mode 100644
index 0000000..503bd12
--- /dev/null
+++ b/tps/tps_test_report_1770706999829.txt
@@ -0,0 +1,38 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 14:58:44
+ 结束时间: 2026-02-10 15:03:19
+ 测试时长: 275.23 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 99822
+ 失败交易: 178
+ 成功率: 99.82%
+
+性能指标:
+ ★ TPS (每秒交易数): 362.68
+ 平均延迟: 1299.76 ms
+ 中位数延迟: 807 ms
+ P95延迟: 2194 ms
+ P99延迟: 14605 ms
+
+报告时间: 2026-02-10 15:03:19
+========================================
+
+错误示例 (前10条):
+ 1. 交易执行失败
+ 2. 交易执行失败
+ 3. 交易执行失败
+ 4. 交易执行失败
+ 5. 交易执行失败
+ 6. 交易执行失败
+ 7. 交易执行失败
+ 8. 交易执行失败
+ 9. 交易执行失败
+ 10. 交易执行失败
diff --git a/tps/tps_test_report_1770707384682.txt b/tps/tps_test_report_1770707384682.txt
new file mode 100644
index 0000000..14765f2
--- /dev/null
+++ b/tps/tps_test_report_1770707384682.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 15:04:54
+ 结束时间: 2026-02-10 15:09:44
+ 测试时长: 290.01 秒
+ 并发线程数: 400
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 344.81
+ 平均延迟: 1146.03 ms
+ 中位数延迟: 755 ms
+ P95延迟: 1997 ms
+ P99延迟: 10785 ms
+
+报告时间: 2026-02-10 15:09:44
+========================================
diff --git a/tps/tps_test_report_1770707638802.txt b/tps/tps_test_report_1770707638802.txt
new file mode 100644
index 0000000..a82d0f5
--- /dev/null
+++ b/tps/tps_test_report_1770707638802.txt
@@ -0,0 +1,26 @@
+========================================
+ FISCO BCOS TPS测试报告
+========================================
+
+测试配置:
+ 开始时间: 2026-02-10 15:09:55
+ 结束时间: 2026-02-10 15:13:58
+ 测试时长: 243.54 秒
+ 并发线程数: 500
+ QPS限制: 无限制
+
+交易统计:
+ 总交易数: 100000
+ 成功交易: 100000
+ 失败交易: 0
+ 成功率: 100.00%
+
+性能指标:
+ ★ TPS (每秒交易数): 410.61
+ 平均延迟: 1198.27 ms
+ 中位数延迟: 780 ms
+ P95延迟: 2089 ms
+ P99延迟: 10839 ms
+
+报告时间: 2026-02-10 15:13:58
+========================================