From 8201356476794354c3f6e6c43cd106b223af7453 Mon Sep 17 00:00:00 2001 From: lzx <393768033@qq.com> Date: Tue, 18 Nov 2025 17:26:07 +0800 Subject: [PATCH] integration wordpress --- go.sum | 2 - integration/wordpress/INSTALL.md | 128 +++++++ integration/wordpress/README.md | 202 +++++++++++ integration/wordpress/api-bridge/README.md | 78 +++++ integration/wordpress/api-bridge/go.mod | 8 + integration/wordpress/api-bridge/go.sum | 4 + integration/wordpress/api-bridge/main.go | 241 +++++++++++++ .../includes/class-m2pool-eth-api.php | 160 +++++++++ .../includes/class-m2pool-eth-gateway.php | 320 ++++++++++++++++++ .../includes/class-m2pool-eth-listener.php | 255 ++++++++++++++ integration/wordpress/m2pool-eth-payment.php | 275 +++++++++++++++ .../templates/payment-instructions.php | 136 ++++++++ integration/wordpress/templates/settings.php | 81 +++++ internal/blockchain/tron/tron.go | 13 + internal/blockchain/tron/tron_prv.go | 1 + 15 files changed, 1902 insertions(+), 2 deletions(-) create mode 100644 integration/wordpress/INSTALL.md create mode 100644 integration/wordpress/README.md create mode 100644 integration/wordpress/api-bridge/README.md create mode 100644 integration/wordpress/api-bridge/go.mod create mode 100644 integration/wordpress/api-bridge/go.sum create mode 100644 integration/wordpress/api-bridge/main.go create mode 100644 integration/wordpress/includes/class-m2pool-eth-api.php create mode 100644 integration/wordpress/includes/class-m2pool-eth-gateway.php create mode 100644 integration/wordpress/includes/class-m2pool-eth-listener.php create mode 100644 integration/wordpress/m2pool-eth-payment.php create mode 100644 integration/wordpress/templates/payment-instructions.php create mode 100644 integration/wordpress/templates/settings.php create mode 100644 internal/blockchain/tron/tron.go create mode 100644 internal/blockchain/tron/tron_prv.go diff --git a/go.sum b/go.sum index 05d20ca..c0d0770 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= diff --git a/integration/wordpress/INSTALL.md b/integration/wordpress/INSTALL.md new file mode 100644 index 0000000..72eccf0 --- /dev/null +++ b/integration/wordpress/INSTALL.md @@ -0,0 +1,128 @@ +# 安装指南 + +## 前置要求 + +1. WordPress 5.0 或更高版本 +2. WooCommerce 3.0 或更高版本 +3. PHP 7.4 或更高版本 +4. M2Pool 支付系统后端(Go 服务) + +## 安装步骤 + +### 1. 安装 WordPress 插件 + +1. 将 `integration/wordpress` 文件夹复制到 WordPress 的插件目录: + ``` + wp-content/plugins/m2pool-eth-payment/ + ``` + +2. 在 WordPress 后台激活插件: + - 进入 `插件 > 已安装的插件` + - 找到 "M2Pool ETH Payment Gateway" + - 点击 "启用" + +### 2. 配置插件 + +1. 进入 `设置 > M2Pool ETH 支付` +2. 配置以下选项: + - **API 地址**: 支付系统的 API 地址(如果使用 API Bridge,则为 `http://localhost:8080`) + - **API 密钥**: 与后端系统的 `msgKey` 对应的密钥 + - **接收地址**: 用于接收支付的以太坊地址 + - **监听间隔**: 检查支付状态的间隔时间(建议 30-60 秒) + +3. 保存设置 + +### 3. 配置 WooCommerce 支付网关 + +1. 进入 `WooCommerce > 设置 > 支付` +2. 找到 "M2Pool ETH 支付" +3. 点击 "管理" +4. 启用支付方式并配置: + - **标题**: 客户看到的支付方式名称 + - **描述**: 支付方式说明 + - **发送地址**: 发送支付的地址(可选) + - **接收地址**: 接收支付的地址 + - **链名称**: 选择 ETH + - **代币符号**: 选择 ETH 或 USDT + +5. 保存更改 + +### 4. 设置 API Bridge(可选) + +如果您的后端系统只支持 RabbitMQ,需要运行 API Bridge 服务: + +1. 进入 `integration/wordpress/api-bridge` 目录 +2. 安装依赖: + ```bash + go mod download + ``` +3. 编译: + ```bash + go build -o api-bridge main.go + ``` +4. 运行: + ```bash + ./api-bridge + ``` + +5. 在 WordPress 插件设置中,将 API 地址设置为 `http://localhost:8080` + +## 测试支付 + +1. 在 WooCommerce 创建一个测试订单 +2. 选择 "ETH 支付" 作为支付方式 +3. 完成订单后,您会看到支付说明页面 +4. 向显示的地址支付指定金额的 ETH +5. 系统会自动检测支付并更新订单状态 + +## Webhook 配置(推荐) + +为了实时接收支付状态更新,建议配置 Webhook: + +1. 在 WordPress 插件设置页面找到 Webhook URL +2. 将此 URL 配置到您的支付系统中 +3. 当支付状态更新时,系统会自动通知 WordPress + +Webhook URL 格式: +``` +https://your-site.com/wp-json/m2pool-eth/v1/webhook +``` + +## 故障排除 + +### 支付状态不更新 + +1. 检查 API 地址是否正确 +2. 检查 API 密钥是否匹配 +3. 查看 WordPress 错误日志 +4. 确认后端服务正常运行 + +### 无法创建支付请求 + +1. 检查 API Bridge 是否运行(如果使用) +2. 检查 RabbitMQ 连接是否正常 +3. 查看后端服务日志 + +### 订单状态不更新 + +1. 检查定时任务是否运行: + - 进入 `工具 > 计划任务` + - 查找 `m2pool_eth_check_payments` +2. 手动触发支付检查(通过 AJAX) +3. 检查数据库表 `wp_m2pool_eth_payments` 中的数据 + +## 数据库表 + +插件会自动创建以下数据库表: + +- `wp_m2pool_eth_payments`: 存储支付记录 + +您可以通过 phpMyAdmin 或 WordPress 数据库工具查看和管理这些表。 + +## 支持 + +如有问题,请查看: +- README.md - 详细文档 +- WordPress 错误日志 +- 后端服务日志 + diff --git a/integration/wordpress/README.md b/integration/wordpress/README.md new file mode 100644 index 0000000..5986f78 --- /dev/null +++ b/integration/wordpress/README.md @@ -0,0 +1,202 @@ +# M2Pool ETH Payment Gateway for WordPress + +WordPress 支付网关插件,支持以太坊 (ETH) 交易的支付、监听和返回支付结果。 + +## 功能特性 + +- ✅ 集成 WooCommerce 支付网关 +- ✅ 支持 ETH 和 USDT 支付 +- ✅ 自动监听支付状态 +- ✅ 支持 Webhook 回调 +- ✅ 支付状态实时更新 +- ✅ 完整的订单管理 + +## 安装要求 + +- WordPress 5.0+ +- WooCommerce 3.0+ +- PHP 7.4+ + +## 安装步骤 + +1. 将插件文件夹上传到 `/wp-content/plugins/` 目录 +2. 在 WordPress 后台激活插件 +3. 进入 `设置 > M2Pool ETH 支付` 配置 API 地址和密钥 +4. 在 `WooCommerce > 设置 > 支付` 中启用并配置支付网关 + +## 配置说明 + +### 基本设置 + +1. **API 地址**: 支付系统的 API 地址(例如: `http://localhost:8080`) +2. **API 密钥**: 用于签名验证的密钥(与后端系统的 `msgKey` 对应) +3. **接收地址**: 用于接收支付的以太坊地址 +4. **监听间隔**: 检查支付状态的间隔时间(秒) + +### Webhook 配置 + +Webhook URL: `https://your-site.com/wp-json/m2pool-eth/v1/webhook` + +将此 URL 配置到您的支付系统中,以便接收支付状态更新。 + +## API 接口说明 + +插件需要与后端支付系统通信。如果后端系统只支持 RabbitMQ,您需要创建一个中间 API 服务。 + +### 需要的 API 接口 + +#### 1. 创建支付请求 + +``` +POST /api/payment/create +``` + +请求体: +```json +{ + "queue_id": "wp_123_1234567890", + "chain": "ETH", + "symbol": "ETH", + "from_address": "0x...", + "to_address": "0x...", + "amount": 0.1, + "fee": 0, + "timestamp": 1234567890, + "sign": "signature_hash" +} +``` + +响应: +```json +{ + "success": true, + "queue_id": "wp_123_1234567890" +} +``` + +#### 2. 查询支付状态 + +``` +GET /api/payment/status/{queue_id} +``` + +响应: +```json +{ + "queue_id": "wp_123_1234567890", + "status": 1, + "tx_hash": "0x...", + "block_height": 12345, + "amount": 0.1 +} +``` + +状态码说明: +- `0`: 待支付 +- `1`: 支付成功 +- `2`: 待确认 +- `3`: 支付失败 + +## 中间 API 服务 + +如果您的后端系统只支持 RabbitMQ,可以创建一个简单的 HTTP API 服务来桥接 WordPress 和 RabbitMQ。 + +示例代码(Go): + +```go +package main + +import ( + "encoding/json" + "log" + "net/http" + "github.com/streadway/amqp" +) + +func createPaymentHandler(w http.ResponseWriter, r *http.Request) { + var req PaymentRequest + json.NewDecoder(r.Body).Decode(&req) + + // 发送到 RabbitMQ + conn, _ := amqp.Dial("amqp://guest:guest@localhost:5672/") + ch, _ := conn.Channel() + + body, _ := json.Marshal(req) + ch.Publish("pay.exchange", "pay.auto.routing.key", false, false, amqp.Publishing{ + ContentType: "application/json", + Body: body, + }) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]bool{"success": true}) +} + +func main() { + http.HandleFunc("/api/payment/create", createPaymentHandler) + log.Fatal(http.ListenAndServe(":8080", nil)) +} +``` + +## 数据库结构 + +插件会自动创建以下数据库表: + +- `wp_m2pool_eth_payments`: 存储支付记录 + +表结构: +- `id`: 主键 +- `order_id`: WooCommerce 订单 ID +- `queue_id`: 支付队列 ID +- `from_address`: 发送地址 +- `to_address`: 接收地址 +- `amount`: 支付金额 +- `fee`: 手续费 +- `chain`: 链名称 +- `symbol`: 代币符号 +- `tx_hash`: 交易哈希 +- `block_height`: 区块高度 +- `status`: 支付状态 +- `created_at`: 创建时间 +- `updated_at`: 更新时间 + +## 使用流程 + +1. 客户选择 ETH 支付方式 +2. 系统生成支付地址和金额 +3. 客户向指定地址支付 +4. 系统自动监听支付状态 +5. 支付确认后自动更新订单状态 + +## 开发说明 + +### 文件结构 + +``` +m2pool-eth-payment/ +├── m2pool-eth-payment.php # 主插件文件 +├── includes/ +│ ├── class-m2pool-eth-gateway.php # 支付网关类 +│ ├── class-m2pool-eth-api.php # API 客户端 +│ └── class-m2pool-eth-listener.php # 支付监听器 +├── templates/ +│ ├── settings.php # 设置页面模板 +│ └── payment-instructions.php # 支付说明模板 +└── README.md +``` + +### 扩展开发 + +要添加新的功能,可以: + +1. 扩展 `M2Pool_ETH_Gateway` 类添加新的支付方式 +2. 扩展 `M2Pool_ETH_API` 类添加新的 API 接口 +3. 修改 `M2Pool_ETH_Listener` 类自定义监听逻辑 + +## 许可证 + +MIT License + +## 支持 + +如有问题,请提交 Issue 或联系开发团队。 + diff --git a/integration/wordpress/api-bridge/README.md b/integration/wordpress/api-bridge/README.md new file mode 100644 index 0000000..66a0117 --- /dev/null +++ b/integration/wordpress/api-bridge/README.md @@ -0,0 +1,78 @@ +# M2Pool API Bridge + +这是一个中间 API 服务,用于连接 WordPress 插件和基于 RabbitMQ 的支付系统。 + +## 功能 + +- 接收 WordPress 插件的 HTTP 请求 +- 将请求转换为 RabbitMQ 消息 +- 监听 RabbitMQ 响应并返回给 WordPress + +## 安装 + +```bash +cd api-bridge +go mod download +go build -o api-bridge main.go +``` + +## 配置 + +修改 `main.go` 中的 RabbitMQ 配置: + +```go +rmqConfig = RabbitMQConfig{ + URL: "amqp://m2pool:m2pool@localhost:5672", + Exchange: "pay.exchange", + Queues: map[string]string{ + "pay": "pay.auto.routing.key", + "topup": "pay.recharge.routing.key", + "status": "pay.auto.return.routing.key", + }, +} +``` + +## 运行 + +```bash +./api-bridge +``` + +服务将在 `http://localhost:8080` 启动。 + +## API 接口 + +### 创建支付请求 + +``` +POST /api/payment/create +``` + +### 查询支付状态 + +``` +GET /api/payment/status/{queue_id} +``` + +### 创建充值请求 + +``` +POST /api/topup/create +``` + +### 查询充值状态 + +``` +GET /api/topup/status/{queue_id} +``` + +## 注意事项 + +当前实现是基础版本,实际使用中需要: + +1. 实现状态缓存(Redis 或数据库) +2. 监听 RabbitMQ 响应队列 +3. 实现签名验证 +4. 添加错误处理和日志记录 +5. 添加认证和授权 + diff --git a/integration/wordpress/api-bridge/go.mod b/integration/wordpress/api-bridge/go.mod new file mode 100644 index 0000000..c796a1c --- /dev/null +++ b/integration/wordpress/api-bridge/go.mod @@ -0,0 +1,8 @@ +module m2pool-api-bridge + +go 1.21 + +require ( + github.com/gorilla/mux v1.8.1 + github.com/streadway/amqp v1.1.0 +) diff --git a/integration/wordpress/api-bridge/go.sum b/integration/wordpress/api-bridge/go.sum new file mode 100644 index 0000000..a59082d --- /dev/null +++ b/integration/wordpress/api-bridge/go.sum @@ -0,0 +1,4 @@ +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM= +github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg= diff --git a/integration/wordpress/api-bridge/main.go b/integration/wordpress/api-bridge/main.go new file mode 100644 index 0000000..91ee596 --- /dev/null +++ b/integration/wordpress/api-bridge/main.go @@ -0,0 +1,241 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" + + "github.com/gorilla/mux" + "github.com/streadway/amqp" +) + +// PaymentRequest 支付请求 +type PaymentRequest struct { + QueueID string `json:"queue_id"` + Chain string `json:"chain"` + Symbol string `json:"symbol"` + FromAddress string `json:"from_address"` + ToAddress string `json:"to_address"` + Amount float64 `json:"amount"` + Fee float64 `json:"fee"` + Timestamp uint64 `json:"timestamp"` + Sign string `json:"sign"` +} + +// TopupRequest 充值请求 +type TopupRequest struct { + QueueID string `json:"queue_id"` + Chain string `json:"chain"` + Symbol string `json:"symbol"` + Address string `json:"address"` + Timestamp uint64 `json:"timestamp"` + Sign string `json:"sign"` +} + +// APIResponse API 响应 +type APIResponse struct { + Success bool `json:"success"` + Data interface{} `json:"data,omitempty"` + Message string `json:"message,omitempty"` +} + +// RabbitMQConfig RabbitMQ 配置 +type RabbitMQConfig struct { + URL string + Exchange string + Queues map[string]string +} + +var rmqConfig RabbitMQConfig +var rmqConn *amqp.Connection +var rmqCh *amqp.Channel + +func main() { + // 初始化 RabbitMQ 配置 + rmqConfig = RabbitMQConfig{ + URL: "amqp://m2pool:m2pool@localhost:5672", + Exchange: "pay.exchange", + Queues: map[string]string{ + "pay": "pay.auto.routing.key", + "topup": "pay.recharge.routing.key", + "status": "pay.auto.return.routing.key", + }, + } + + // 连接 RabbitMQ + var err error + rmqConn, err = amqp.Dial(rmqConfig.URL) + if err != nil { + log.Fatalf("Failed to connect to RabbitMQ: %v", err) + } + defer rmqConn.Close() + + rmqCh, err = rmqConn.Channel() + if err != nil { + log.Fatalf("Failed to open channel: %v", err) + } + defer rmqCh.Close() + + // 设置路由 + r := mux.NewRouter() + + // 支付相关接口 + r.HandleFunc("/api/payment/create", createPaymentHandler).Methods("POST") + r.HandleFunc("/api/payment/status/{queue_id}", getPaymentStatusHandler).Methods("GET") + + // 充值相关接口 + r.HandleFunc("/api/topup/create", createTopupHandler).Methods("POST") + r.HandleFunc("/api/topup/status/{queue_id}", getTopupStatusHandler).Methods("GET") + + // 健康检查 + r.HandleFunc("/health", healthCheckHandler).Methods("GET") + + log.Println("API Bridge Server starting on :8080") + log.Fatal(http.ListenAndServe(":8888", r)) +} + +// createPaymentHandler 创建支付请求 +func createPaymentHandler(w http.ResponseWriter, r *http.Request) { + var req PaymentRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + respondJSON(w, http.StatusBadRequest, APIResponse{ + Success: false, + Message: "Invalid request body", + }) + return + } + + // 发送到 RabbitMQ + body, err := json.Marshal(req) + if err != nil { + respondJSON(w, http.StatusInternalServerError, APIResponse{ + Success: false, + Message: "Failed to marshal request", + }) + return + } + + err = rmqCh.Publish( + rmqConfig.Exchange, + rmqConfig.Queues["pay"], + false, + false, + amqp.Publishing{ + ContentType: "application/json", + Body: body, + }, + ) + + if err != nil { + log.Printf("Failed to publish payment request: %v", err) + respondJSON(w, http.StatusInternalServerError, APIResponse{ + Success: false, + Message: "Failed to send payment request", + }) + return + } + + respondJSON(w, http.StatusOK, APIResponse{ + Success: true, + Data: map[string]string{ + "queue_id": req.QueueID, + }, + }) +} + +// getPaymentStatusHandler 查询支付状态 +func getPaymentStatusHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + queueID := vars["queue_id"] + + // 这里应该从数据库或缓存中查询状态 + // 为了演示,我们返回一个模拟响应 + // 实际实现中,应该监听 RabbitMQ 的响应队列并存储状态 + + respondJSON(w, http.StatusOK, APIResponse{ + Success: true, + Data: map[string]interface{}{ + "queue_id": queueID, + "status": 0, // 0=待支付, 1=成功, 2=待确认, 3=失败 + }, + }) +} + +// createTopupHandler 创建充值请求 +func createTopupHandler(w http.ResponseWriter, r *http.Request) { + var req TopupRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + respondJSON(w, http.StatusBadRequest, APIResponse{ + Success: false, + Message: "Invalid request body", + }) + return + } + + // 发送到 RabbitMQ + body, err := json.Marshal(req) + if err != nil { + respondJSON(w, http.StatusInternalServerError, APIResponse{ + Success: false, + Message: "Failed to marshal request", + }) + return + } + + err = rmqCh.Publish( + rmqConfig.Exchange, + rmqConfig.Queues["topup"], + false, + false, + amqp.Publishing{ + ContentType: "application/json", + Body: body, + }, + ) + + if err != nil { + log.Printf("Failed to publish topup request: %v", err) + respondJSON(w, http.StatusInternalServerError, APIResponse{ + Success: false, + Message: "Failed to send topup request", + }) + return + } + + respondJSON(w, http.StatusOK, APIResponse{ + Success: true, + Data: map[string]string{ + "queue_id": req.QueueID, + }, + }) +} + +// getTopupStatusHandler 查询充值状态 +func getTopupStatusHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + queueID := vars["queue_id"] + + // 这里应该从数据库或缓存中查询状态 + respondJSON(w, http.StatusOK, APIResponse{ + Success: true, + Data: map[string]interface{}{ + "queue_id": queueID, + "status": 0, + }, + }) +} + +// healthCheckHandler 健康检查 +func healthCheckHandler(w http.ResponseWriter, r *http.Request) { + respondJSON(w, http.StatusOK, APIResponse{ + Success: true, + Message: "API Bridge is running", + }) +} + +// respondJSON 返回 JSON 响应 +func respondJSON(w http.ResponseWriter, status int, data interface{}) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + json.NewEncoder(w).Encode(data) +} diff --git a/integration/wordpress/includes/class-m2pool-eth-api.php b/integration/wordpress/includes/class-m2pool-eth-api.php new file mode 100644 index 0000000..7734ab8 --- /dev/null +++ b/integration/wordpress/includes/class-m2pool-eth-api.php @@ -0,0 +1,160 @@ +api_url = get_option('m2pool_eth_api_url', 'http://localhost:8080'); + $this->api_key = get_option('m2pool_eth_api_key', ''); + } + + /** + * 生成签名 + */ + private function generate_sign($timestamp) { + if (empty($this->api_key)) { + return ''; + } + return hash('sha256', dechex($timestamp) . $this->api_key); + } + + /** + * 发送 HTTP 请求 + */ + private function request($endpoint, $method = 'GET', $data = array()) { + $url = rtrim($this->api_url, '/') . '/' . ltrim($endpoint, '/'); + + $args = array( + 'method' => $method, + 'timeout' => 30, + 'headers' => array( + 'Content-Type' => 'application/json', + ), + ); + + if (!empty($data)) { + $args['body'] = json_encode($data); + } + + $response = wp_remote_request($url, $args); + + if (is_wp_error($response)) { + return $response; + } + + $body = wp_remote_retrieve_body($response); + $code = wp_remote_retrieve_response_code($response); + + if ($code >= 200 && $code < 300) { + $data = json_decode($body, true); + return $data; + } else { + return new WP_Error('api_error', sprintf(__('API 错误: %s', 'm2pool-eth-payment'), $body), array('status' => $code)); + } + } + + /** + * 创建支付请求 + * + * 注意:这个方法假设有一个 HTTP API 接口。 + * 如果后端系统只支持 RabbitMQ,需要创建一个中间 API 服务。 + */ + public function create_payment($queue_id, $from_address, $to_address, $amount, $chain = 'ETH', $symbol = 'ETH') { + $timestamp = time(); + $sign = $this->generate_sign($timestamp); + + $data = array( + 'queue_id' => $queue_id, + 'chain' => $chain, + 'symbol' => $symbol, + 'from_address' => $from_address, + 'to_address' => $to_address, + 'amount' => $amount, + 'fee' => 0, + 'timestamp' => $timestamp, + 'sign' => $sign, + ); + + // 发送到支付 API + // 注意:这里需要根据实际的后端 API 接口调整 + // 如果后端只支持 RabbitMQ,需要创建一个中间 API 服务来处理 + $result = $this->request('/api/payment/create', 'POST', $data); + + if (is_wp_error($result)) { + return $result; + } + + return $result; + } + + /** + * 查询支付状态 + */ + public function get_payment_status($queue_id) { + $result = $this->request('/api/payment/status/' . $queue_id, 'GET'); + + if (is_wp_error($result)) { + return $result; + } + + return $result; + } + + /** + * 创建充值监听请求 + */ + public function create_topup($queue_id, $address, $chain = 'ETH', $symbol = 'ETH') { + $timestamp = time(); + $sign = $this->generate_sign($timestamp); + + $data = array( + 'queue_id' => $queue_id, + 'chain' => $chain, + 'symbol' => $symbol, + 'address' => $address, + 'timestamp' => $timestamp, + 'sign' => $sign, + ); + + $result = $this->request('/api/topup/create', 'POST', $data); + + if (is_wp_error($result)) { + return $result; + } + + return $result; + } + + /** + * 查询充值状态 + */ + public function get_topup_status($queue_id) { + $result = $this->request('/api/topup/status/' . $queue_id, 'GET'); + + if (is_wp_error($result)) { + return $result; + } + + return $result; + } +} + diff --git a/integration/wordpress/includes/class-m2pool-eth-gateway.php b/integration/wordpress/includes/class-m2pool-eth-gateway.php new file mode 100644 index 0000000..098b9c6 --- /dev/null +++ b/integration/wordpress/includes/class-m2pool-eth-gateway.php @@ -0,0 +1,320 @@ +id = 'm2pool_eth'; + $this->icon = apply_filters('woocommerce_m2pool_eth_icon', ''); + $this->has_fields = false; + $this->method_title = __('M2Pool ETH 支付', 'm2pool-eth-payment'); + $this->method_description = __('接受以太坊 (ETH) 支付', 'm2pool-eth-payment'); + $this->supports = array( + 'products', + ); + + // 加载设置 + $this->init_form_fields(); + $this->init_settings(); + + // 定义用户可见的设置 + $this->title = $this->get_option('title', __('ETH 支付', 'm2pool-eth-payment')); + $this->description = $this->get_option('description', __('使用以太坊进行支付', 'm2pool-eth-payment')); + $this->enabled = $this->get_option('enabled', 'no'); + + // 保存设置 + add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); + + // 支付完成页面 + add_action('woocommerce_thankyou_' . $this->id, array($this, 'thankyou_page')); + + // 订单详情页面 + add_action('woocommerce_order_details_after_order_table', array($this, 'order_details'), 10, 1); + + // 确保在结账页面显示 + add_filter('woocommerce_available_payment_gateways', array($this, 'ensure_available'), 100); + } + + /** + * 确保支付网关可用(强制显示) + */ + public function ensure_available($available_gateways) { + // 如果已启用且配置正确,确保在列表中 + if ($this->enabled === 'yes') { + $to_address = $this->get_option('to_address', get_option('m2pool_eth_to_address', '')); + if (!empty($to_address) && $this->is_available()) { + // 确保网关在可用列表中 + if (!isset($available_gateways[$this->id])) { + $available_gateways[$this->id] = $this; + } + } + } + return $available_gateways; + } + + /** + * 检查支付网关是否可用 + */ + public function is_available() { + // 检查是否启用 + if ($this->enabled !== 'yes') { + if (defined('WP_DEBUG') && WP_DEBUG) { + error_log('M2Pool ETH Gateway: Not enabled'); + } + return false; + } + + // 检查是否有接收地址 + $to_address = $this->get_option('to_address', get_option('m2pool_eth_to_address', '')); + if (empty($to_address)) { + if (defined('WP_DEBUG') && WP_DEBUG) { + error_log('M2Pool ETH Gateway: No receive address configured'); + } + return false; + } + + // 检查是否有订单(在结账页面) + if (is_checkout() || is_checkout_pay_page()) { + // 在结账页面,确保有订单 + $order_id = absint(get_query_var('order-pay')); + if ($order_id > 0) { + $order = wc_get_order($order_id); + if (!$order || $order->get_total() <= 0) { + if (defined('WP_DEBUG') && WP_DEBUG) { + error_log('M2Pool ETH Gateway: Invalid order or zero amount'); + } + return false; + } + } + } + + // 调用父类方法 + $parent_available = parent::is_available(); + + // 如果父类返回 false,记录原因(用于调试) + if (!$parent_available && defined('WP_DEBUG') && WP_DEBUG) { + $order = WC()->cart; + $total = $order ? $order->get_total() : 0; + error_log(sprintf( + 'M2Pool ETH Gateway: Parent is_available() returned false. Cart total: %s, Enabled: %s, Address: %s', + $total, + $this->enabled, + !empty($to_address) ? 'set' : 'empty' + )); + } + + return $parent_available; + } + + /** + * 初始化表单字段 + */ + public function init_form_fields() { + $this->form_fields = array( + 'enabled' => array( + 'title' => __('启用/禁用', 'm2pool-eth-payment'), + 'type' => 'checkbox', + 'label' => __('启用 M2Pool ETH 支付', 'm2pool-eth-payment'), + 'default' => 'no', + ), + 'title' => array( + 'title' => __('标题', 'm2pool-eth-payment'), + 'type' => 'text', + 'description' => __('客户在结账时看到的支付方式标题', 'm2pool-eth-payment'), + 'default' => __('ETH 支付', 'm2pool-eth-payment'), + 'desc_tip' => true, + ), + 'description' => array( + 'title' => __('描述', 'm2pool-eth-payment'), + 'type' => 'textarea', + 'description' => __('客户在结账时看到的支付方式描述', 'm2pool-eth-payment'), + 'default' => __('使用以太坊 (ETH) 进行支付', 'm2pool-eth-payment'), + 'desc_tip' => true, + ), + 'from_address' => array( + 'title' => __('发送地址', 'm2pool-eth-payment'), + 'type' => 'text', + 'description' => __('用于接收支付的以太坊地址', 'm2pool-eth-payment'), + 'default' => get_option('m2pool_eth_from_address', ''), + 'desc_tip' => true, + ), + 'to_address' => array( + 'title' => __('接收地址', 'm2pool-eth-payment'), + 'type' => 'text', + 'description' => __('用于接收支付的以太坊地址', 'm2pool-eth-payment'), + 'default' => get_option('m2pool_eth_to_address', ''), + 'desc_tip' => true, + ), + 'chain' => array( + 'title' => __('链名称', 'm2pool-eth-payment'), + 'type' => 'select', + 'options' => array( + 'ETH' => 'Ethereum', + ), + 'default' => 'ETH', + ), + 'symbol' => array( + 'title' => __('代币符号', 'm2pool-eth-payment'), + 'type' => 'select', + 'options' => array( + 'ETH' => 'ETH', + 'USDT' => 'USDT', + ), + 'default' => 'ETH', + ), + ); + } + + /** + * 处理支付 + */ + public function process_payment($order_id) { + $order = wc_get_order($order_id); + + if (!$order) { + wc_add_notice(__('订单不存在', 'm2pool-eth-payment'), 'error'); + return; + } + + // 获取 API 客户端 + $api = new M2Pool_ETH_API(); + + // 准备支付请求 + $amount = floatval($order->get_total()); + $from_address = $this->get_option('from_address', get_option('m2pool_eth_from_address', '')); + $to_address = $this->get_option('to_address', get_option('m2pool_eth_to_address', '')); + $chain = $this->get_option('chain', 'ETH'); + $symbol = $this->get_option('symbol', 'ETH'); + + if (empty($to_address)) { + wc_add_notice(__('支付网关配置错误:接收地址未设置', 'm2pool-eth-payment'), 'error'); + return; + } + + // 生成队列 ID + $queue_id = 'wp_' . $order_id . '_' . time(); + + // 发送支付请求 + $result = $api->create_payment($queue_id, $from_address, $to_address, $amount, $chain, $symbol); + + if (is_wp_error($result)) { + wc_add_notice($result->get_error_message(), 'error'); + return; + } + + // 保存支付信息到数据库 + global $wpdb; + $table_name = $wpdb->prefix . 'm2pool_eth_payments'; + + $wpdb->insert( + $table_name, + array( + 'order_id' => $order_id, + 'queue_id' => $queue_id, + 'from_address' => $from_address, + 'to_address' => $to_address, + 'amount' => $amount, + 'fee' => isset($result['fee']) ? $result['fee'] : 0, + 'chain' => $chain, + 'symbol' => $symbol, + 'status' => 0, // 待支付 + ), + array('%d', '%s', '%s', '%s', '%f', '%f', '%s', '%s', '%d') + ); + + // 更新订单元数据 + $order->update_meta_data('_m2pool_queue_id', $queue_id); + $order->update_meta_data('_m2pool_payment_address', $to_address); + $order->update_meta_data('_m2pool_payment_amount', $amount); + $order->update_meta_data('_m2pool_payment_chain', $chain); + $order->update_meta_data('_m2pool_payment_symbol', $symbol); + $order->save(); + + // 将订单状态设置为待支付 + $order->update_status('pending', __('等待 ETH 支付', 'm2pool-eth-payment')); + + // 启动支付监听 + $listener = new M2Pool_ETH_Listener(); + $listener->start_listening($order_id); + + // 返回成功 + return array( + 'result' => 'success', + 'redirect' => $this->get_return_url($order), + ); + } + + /** + * 感谢页面 + */ + public function thankyou_page($order_id) { + $order = wc_get_order($order_id); + + if (!$order || $order->get_payment_method() !== $this->id) { + return; + } + + $payment_address = $order->get_meta('_m2pool_payment_address'); + $payment_amount = $order->get_meta('_m2pool_payment_amount'); + $payment_symbol = $order->get_meta('_m2pool_payment_symbol'); + $queue_id = $order->get_meta('_m2pool_queue_id'); + + if (!$payment_address || !$payment_amount) { + return; + } + + include M2POOL_ETH_PLUGIN_DIR . 'templates/payment-instructions.php'; + } + + /** + * 订单详情页面 + */ + public function order_details($order) { + if ($order->get_payment_method() !== $this->id) { + return; + } + + $payment_address = $order->get_meta('_m2pool_payment_address'); + $payment_amount = $order->get_meta('_m2pool_payment_amount'); + $payment_symbol = $order->get_meta('_m2pool_payment_symbol'); + $tx_hash = $order->get_meta('_m2pool_tx_hash'); + + if (!$payment_address || !$payment_amount) { + return; + } + + ?> +
+

+ + + + + + + + + + + + + + + + + +
:
:
:
+
+ api = new M2Pool_ETH_API(); + } + + /** + * 开始监听订单支付 + */ + public function start_listening($order_id) { + // 创建定时任务检查支付状态 + if (!wp_next_scheduled('m2pool_eth_check_payments')) { + $interval = get_option('m2pool_eth_listen_interval', 30); + wp_schedule_event(time(), 'm2pool_eth_interval', 'm2pool_eth_check_payments'); + } + + // 添加自定义间隔 + add_filter('cron_schedules', array($this, 'add_cron_interval')); + } + + /** + * 添加自定义 Cron 间隔 + */ + public function add_cron_interval($schedules) { + $interval = get_option('m2pool_eth_listen_interval', 30); + + $schedules['m2pool_eth_interval'] = array( + 'interval' => $interval, + 'display' => sprintf(__('每 %d 秒', 'm2pool-eth-payment'), $interval), + ); + + return $schedules; + } + + /** + * 检查支付状态 + */ + public function check_payment_status($order_id) { + $order = wc_get_order($order_id); + + if (!$order) { + return array( + 'success' => false, + 'message' => __('订单不存在', 'm2pool-eth-payment'), + ); + } + + $queue_id = $order->get_meta('_m2pool_queue_id'); + + if (empty($queue_id)) { + return array( + 'success' => false, + 'message' => __('未找到支付队列 ID', 'm2pool-eth-payment'), + ); + } + + // 从数据库获取支付记录 + global $wpdb; + $table_name = $wpdb->prefix . 'm2pool_eth_payments'; + $payment = $wpdb->get_row($wpdb->prepare( + "SELECT * FROM $table_name WHERE order_id = %d AND queue_id = %s", + $order_id, + $queue_id + )); + + if (!$payment) { + return array( + 'success' => false, + 'message' => __('未找到支付记录', 'm2pool-eth-payment'), + ); + } + + // 如果已经成功,直接返回 + if ($payment->status == 1) { + return array( + 'success' => true, + 'status' => 'completed', + 'message' => __('支付已完成', 'm2pool-eth-payment'), + ); + } + + // 查询 API 获取最新状态 + $result = $this->api->get_payment_status($queue_id); + + if (is_wp_error($result)) { + return array( + 'success' => false, + 'message' => $result->get_error_message(), + ); + } + + // 更新支付状态 + $this->update_payment_status($order_id, $result); + + return array( + 'success' => true, + 'status' => $this->get_status_text($result['status']), + 'data' => $result, + ); + } + + /** + * 处理 Webhook + */ + public function process_webhook($data) { + if (!isset($data['queue_id'])) { + return false; + } + + $queue_id = $data['queue_id']; + + // 从数据库查找订单 + global $wpdb; + $table_name = $wpdb->prefix . 'm2pool_eth_payments'; + $payment = $wpdb->get_row($wpdb->prepare( + "SELECT * FROM $table_name WHERE queue_id = %s", + $queue_id + )); + + if (!$payment) { + return false; + } + + // 更新支付状态 + $this->update_payment_status($payment->order_id, $data); + + return true; + } + + /** + * 更新支付状态 + */ + private function update_payment_status($order_id, $data) { + $order = wc_get_order($order_id); + + if (!$order) { + return; + } + + global $wpdb; + $table_name = $wpdb->prefix . 'm2pool_eth_payments'; + + $status = isset($data['status']) ? intval($data['status']) : 0; + $tx_hash = isset($data['tx_hash']) ? $data['tx_hash'] : null; + $block_height = isset($data['block_height']) ? $data['block_height'] : null; + $amount = isset($data['amount']) ? floatval($data['amount']) : null; + + // 更新数据库 + $update_data = array( + 'status' => $status, + ); + + if ($tx_hash) { + $update_data['tx_hash'] = $tx_hash; + } + + if ($block_height) { + $update_data['block_height'] = $block_height; + } + + if ($amount !== null) { + $update_data['amount'] = $amount; + } + + $wpdb->update( + $table_name, + $update_data, + array('order_id' => $order_id), + array('%d', '%s', '%d', '%f'), + array('%d') + ); + + // 更新订单状态 + if ($status == 1) { + // 支付成功 + $order->update_meta_data('_m2pool_tx_hash', $tx_hash); + $order->payment_complete(); + $order->add_order_note(__('ETH 支付成功', 'm2pool-eth-payment')); + } elseif ($status == 2) { + // 待确认 + $order->update_status('on-hold', __('ETH 支付待确认', 'm2pool-eth-payment')); + if ($tx_hash) { + $order->update_meta_data('_m2pool_tx_hash', $tx_hash); + $order->add_order_note(sprintf(__('ETH 支付待确认,交易哈希: %s', 'm2pool-eth-payment'), $tx_hash)); + } + } elseif ($status == 0 || $status == 3) { + // 支付失败 + $order->update_status('failed', __('ETH 支付失败', 'm2pool-eth-payment')); + $order->add_order_note(__('ETH 支付失败', 'm2pool-eth-payment')); + } + + $order->save(); + } + + /** + * 获取状态文本 + */ + private function get_status_text($status) { + $statuses = array( + 0 => 'pending', + 1 => 'completed', + 2 => 'processing', + 3 => 'failed', + ); + + return isset($statuses[$status]) ? $statuses[$status] : 'unknown'; + } + + /** + * 批量检查所有待支付订单 + */ + public function check_all_pending_payments() { + global $wpdb; + $table_name = $wpdb->prefix . 'm2pool_eth_payments'; + + // 获取所有待支付和待确认的订单 + $payments = $wpdb->get_results( + "SELECT * FROM $table_name WHERE status IN (0, 2) ORDER BY created_at ASC LIMIT 50" + ); + + foreach ($payments as $payment) { + $this->check_payment_status($payment->order_id); + + // 避免请求过快 + sleep(1); + } + } +} + +// 注册定时任务处理函数 +add_action('m2pool_eth_check_payments', 'm2pool_eth_check_all_payments'); + +// 定时任务处理函数 +function m2pool_eth_check_all_payments() { + $listener = new M2Pool_ETH_Listener(); + $listener->check_all_pending_payments(); +} + diff --git a/integration/wordpress/m2pool-eth-payment.php b/integration/wordpress/m2pool-eth-payment.php new file mode 100644 index 0000000..1137090 --- /dev/null +++ b/integration/wordpress/m2pool-eth-payment.php @@ -0,0 +1,275 @@ +init_hooks(); + } + + /** + * 初始化钩子 + */ + private function init_hooks() { + // 激活插件时创建数据库表 + register_activation_hook(__FILE__, array($this, 'activate')); + + // 停用插件时清理 + register_deactivation_hook(__FILE__, array($this, 'deactivate')); + + // 在 WooCommerce 加载后初始化 + add_action('plugins_loaded', array($this, 'init'), 11); + + // 添加管理菜单 + add_action('admin_menu', array($this, 'add_admin_menu')); + + // 注册 AJAX 处理 + add_action('wp_ajax_m2pool_check_payment', array($this, 'ajax_check_payment')); + add_action('wp_ajax_nopriv_m2pool_check_payment', array($this, 'ajax_check_payment')); + + // 注册 Webhook 端点 + add_action('rest_api_init', array($this, 'register_webhook_routes')); + + // 加载文本域 + add_action('init', array($this, 'load_textdomain')); + } + + /** + * 初始化插件 + */ + public function init() { + // 检查 WooCommerce 是否激活 + if (!class_exists('WooCommerce')) { + add_action('admin_notices', array($this, 'woocommerce_missing_notice')); + return; + } + + // 加载支付网关类 + require_once M2POOL_ETH_PLUGIN_DIR . 'includes/class-m2pool-eth-gateway.php'; + require_once M2POOL_ETH_PLUGIN_DIR . 'includes/class-m2pool-eth-api.php'; + require_once M2POOL_ETH_PLUGIN_DIR . 'includes/class-m2pool-eth-listener.php'; + + // 注册支付网关(必须在类加载后) + add_filter('woocommerce_payment_gateways', array($this, 'add_gateway')); + } + + /** + * WooCommerce 缺失通知 + */ + public function woocommerce_missing_notice() { + ?> +
+

+
+ get_charset_collate(); + $table_name = $wpdb->prefix . 'm2pool_eth_payments'; + + $sql = "CREATE TABLE IF NOT EXISTS $table_name ( + id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, + order_id bigint(20) UNSIGNED NOT NULL, + queue_id varchar(255) NOT NULL, + from_address varchar(255) NOT NULL, + to_address varchar(255) NOT NULL, + amount decimal(20,8) NOT NULL, + fee decimal(20,8) DEFAULT 0, + chain varchar(50) DEFAULT 'ETH', + symbol varchar(50) DEFAULT 'ETH', + tx_hash varchar(255) DEFAULT NULL, + block_height bigint(20) UNSIGNED DEFAULT NULL, + status int(11) DEFAULT 0 COMMENT '0=待支付,1=成功,2=待确认,3=失败', + created_at datetime DEFAULT CURRENT_TIMESTAMP, + updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY queue_id (queue_id), + KEY order_id (order_id), + KEY tx_hash (tx_hash), + KEY status (status) + ) $charset_collate;"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + + // 设置默认选项 + if (!get_option('m2pool_eth_api_url')) { + update_option('m2pool_eth_api_url', 'http://localhost:8080'); + } + if (!get_option('m2pool_eth_api_key')) { + update_option('m2pool_eth_api_key', ''); + } + if (!get_option('m2pool_eth_listen_interval')) { + update_option('m2pool_eth_listen_interval', 30); // 30秒轮询一次 + } + } + + /** + * 停用插件 + */ + public function deactivate() { + // 清理定时任务 + wp_clear_scheduled_hook('m2pool_eth_check_payments'); + } + + /** + * 添加管理菜单 + */ + public function add_admin_menu() { + add_options_page( + __('M2Pool ETH 支付设置', 'm2pool-eth-payment'), + __('M2Pool ETH 支付', 'm2pool-eth-payment'), + 'manage_options', + 'm2pool-eth-settings', + array($this, 'settings_page') + ); + } + + /** + * 设置页面 + */ + public function settings_page() { + if (isset($_POST['m2pool_eth_save_settings'])) { + check_admin_referer('m2pool_eth_settings'); + + update_option('m2pool_eth_api_url', sanitize_text_field($_POST['api_url'])); + update_option('m2pool_eth_api_key', sanitize_text_field($_POST['api_key'])); + update_option('m2pool_eth_listen_interval', intval($_POST['listen_interval'])); + update_option('m2pool_eth_from_address', sanitize_text_field($_POST['from_address'])); + update_option('m2pool_eth_to_address', sanitize_text_field($_POST['to_address'])); + + echo '

' . esc_html__('设置已保存', 'm2pool-eth-payment') . '

'; + } + + $api_url = get_option('m2pool_eth_api_url', 'http://localhost:8080'); + $api_key = get_option('m2pool_eth_api_key', ''); + $listen_interval = get_option('m2pool_eth_listen_interval', 30); + $from_address = get_option('m2pool_eth_from_address', ''); + $to_address = get_option('m2pool_eth_to_address', ''); + + include M2POOL_ETH_PLUGIN_DIR . 'templates/settings.php'; + } + + /** + * AJAX 检查支付状态 + */ + public function ajax_check_payment() { + check_ajax_referer('m2pool_eth_check', 'nonce'); + + $order_id = intval($_POST['order_id']); + $order = wc_get_order($order_id); + + if (!$order) { + wp_send_json_error(array('message' => __('订单不存在', 'm2pool-eth-payment'))); + } + + $listener = new M2Pool_ETH_Listener(); + $result = $listener->check_payment_status($order_id); + + if ($result['success']) { + wp_send_json_success($result); + } else { + wp_send_json_error($result); + } + } + + /** + * 注册 Webhook 路由 + */ + public function register_webhook_routes() { + register_rest_route('m2pool-eth/v1', '/webhook', array( + 'methods' => 'POST', + 'callback' => array($this, 'handle_webhook'), + 'permission_callback' => '__return_true', + )); + } + + /** + * 处理 Webhook + */ + public function handle_webhook($request) { + $data = $request->get_json_params(); + + if (!isset($data['queue_id'])) { + return new WP_Error('invalid_data', __('无效的数据', 'm2pool-eth-payment'), array('status' => 400)); + } + + $listener = new M2Pool_ETH_Listener(); + $result = $listener->process_webhook($data); + + if ($result) { + return new WP_REST_Response(array('success' => true), 200); + } else { + return new WP_Error('processing_failed', __('处理失败', 'm2pool-eth-payment'), array('status' => 500)); + } + } + + /** + * 加载文本域 + */ + public function load_textdomain() { + load_plugin_textdomain('m2pool-eth-payment', false, dirname(plugin_basename(__FILE__)) . '/languages'); + } +} + +// 初始化插件 +M2Pool_ETH_Payment::get_instance(); + diff --git a/integration/wordpress/templates/payment-instructions.php b/integration/wordpress/templates/payment-instructions.php new file mode 100644 index 0000000..dba4545 --- /dev/null +++ b/integration/wordpress/templates/payment-instructions.php @@ -0,0 +1,136 @@ + + +
+

+ +
+

+
+ + +
+ +

+

+ +
+

+
+
+ +
+

+ +
+
+ + + + + diff --git a/integration/wordpress/templates/settings.php b/integration/wordpress/templates/settings.php new file mode 100644 index 0000000..20a9b0b --- /dev/null +++ b/integration/wordpress/templates/settings.php @@ -0,0 +1,81 @@ + + +
+

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

+
+ + + +

+
+ + + +

+
+ + + +

+
+ + + +

+
+ +

+ +

+
+ +
+ +

+

+ +

+
+ diff --git a/internal/blockchain/tron/tron.go b/internal/blockchain/tron/tron.go new file mode 100644 index 0000000..2c066e2 --- /dev/null +++ b/internal/blockchain/tron/tron.go @@ -0,0 +1,13 @@ +package tron + +// 区块 +// { +// "blockID":, +// "block_header": map, +// "transactions": map, +//} + +type TRONNode struct { + decodeKey string + ConfirmHeight uint64 +} diff --git a/internal/blockchain/tron/tron_prv.go b/internal/blockchain/tron/tron_prv.go new file mode 100644 index 0000000..5590747 --- /dev/null +++ b/internal/blockchain/tron/tron_prv.go @@ -0,0 +1 @@ +package tron