> For the complete documentation index, see [llms.txt](https://docs.catfee.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.catfee.io/getting-started/buy-energy-via-api-on-catfee/go.md).

# Go 调用示例

### **前提条件**

1. [您需要一个有效的 API Key 和 API Secret](/getting-started/buy-energy-via-api-on-catfee/api-overview.md#apply-api-info)。
2. 请确保您的 Go 环境已经安装了 `net/http` 和 `crypto/hmac` 等标准库。

### **示例代码**

```go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"net/http"
	"net/url"
	"time"
	"io/ioutil"
	"log"
)

const (
	APIKey    = "your_api_key"       // 请替换为您的API Key
	APISecret = "your_api_secret"    // 请替换为您的API Secret
	BaseURL   = "https://api.catfee.io"
)

// 生成当前的时间戳（ISO 8601格式）
func generateTimestamp() string {
	return time.Now().UTC().Format("2006-01-02T15:04:05.000Z")
}

// 构建请求路径，包括查询参数
func buildRequestPath(path string, queryParams map[string]string) string {
	if len(queryParams) == 0 {
		return path
	}

	queryString := "?"
	for key, value := range queryParams {
		queryString += fmt.Sprintf("%s=%s&", key, value)
	}

	// 去掉最后的"&"符号
	queryString = queryString[:len(queryString)-1]

	return path + queryString
}

// 使用 HMAC-SHA256 算法生成签名
func generateSignature(timestamp, method, requestPath string) string {
	signString := timestamp + method + requestPath
	mac := hmac.New(sha256.New, []byte(APISecret))
	mac.Write([]byte(signString))
	signature := mac.Sum(nil)
	return base64.StdEncoding.EncodeToString(signature)
}

// 创建 HTTP 请求
func createRequest(url, method, timestamp, signature string) (*http.Response, error) {
	client := &http.Client{}
	req, err := http.NewRequest(method, url, nil)
	if err != nil {
		return nil, err
	}

	// 设置请求头
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("CF-ACCESS-KEY", APIKey)
	req.Header.Add("CF-ACCESS-SIGN", signature)
	req.Header.Add("CF-ACCESS-TIMESTAMP", timestamp)

	return client.Do(req)
}

func main() {
	method := "POST" // 可以修改为 "GET", "PUT", "DELETE"
	path := "/v1/order"

	// 示例：创建订单
	queryParams := map[string]string{
		"quantity": "65000",
		"receiver": "TRON_ADDRESS",
		"duration": "1h",
	}

	// 生成请求头
	timestamp := generateTimestamp()
	requestPath := buildRequestPath(path, queryParams)
	signature := generateSignature(timestamp, method, requestPath)

	// 创建请求 URL
	url := BaseURL + requestPath

	// 发送请求
	resp, err := createRequest(url, method, timestamp, signature)
	if err != nil {
		log.Fatal("Error making request:", err)
	}

	// 读取并输出响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal("Error reading response:", err)
	}

	// 打印响应数据
	fmt.Println("Response Status:", resp.Status)
	fmt.Println("Response Body:", string(body))
}
```

### **代码解析**

1. **`generateTimestamp()`**：\
   使用 `time.Now().UTC().Format("2006-01-02T15:04:05.000Z")` 获取当前 UTC 时间，并格式化为 ISO 8601 时间戳。
2. **`buildRequestPath()`**：\
   该函数将传入的查询参数（`queryParams`）构建成 URL 查询字符串。每个查询参数用 `&` 连接，最后返回完整的请求路径。
3. **`generateSignature()`**：\
   通过 `timestamp`、`method` 和 `requestPath` 拼接生成签名字符串，然后使用 HMAC-SHA256 算法进行签名，并将结果进行 Base64 编码。最终返回签名。
4. **`createRequest()`**：\
   创建一个 HTTP 请求，使用 `http.NewRequest()` 创建请求对象，并通过 `req.Header.Add()` 添加必要的请求头，包括 `CF-ACCESS-KEY`、`CF-ACCESS-SIGN` 和 `CF-ACCESS-TIMESTAMP`。然后，发送请求并返回响应。
5. **`main()`**：\
   在 `main()` 函数中，设置请求方法为 `POST`，并传入需要的查询参数。调用 `generateTimestamp()`、`buildRequestPath()` 和 `generateSignature()` 来生成请求头信息。最后，使用 `createRequest()` 发送请求并打印响应内容。

### **注意事项**

* **API Key 和 Secret**：\
  请确保将 `APIKey` 和 `APISecret` 替换为您从 CatFee.IO 获取的实际值。
* **查询参数的顺序**：\
  本示例中，我们直接将查询参数拼接到请求路径中，并没有排序查询参数。如果需要对查询参数排序，请使用适当的排序方法。
* **响应处理**：\
  响应通过 `ioutil.ReadAll()` 读取并打印。如果响应体为 JSON 格式，您可以使用 `encoding/json` 库来解析 JSON 数据。
* **请求方法**：\
  当前示例支持 `POST`、`GET`、`PUT` 和 `DELETE` 方法，您可以根据实际需求修改请求方法。

### **总结**

这个示例展示了如何在 Go 中使用 CatFee.IO Rest API，通过 HMAC-SHA256 签名验证来确保请求的安全性。您可以根据实际需求修改代码，支持不同的 HTTP 方法（`GET`、`POST`、`PUT`、`DELETE`），并处理不同的 API 响应。
