exchange.Encode
签名加密计算。
exchange.Encode(algo, inputFormat, outputFormat, data)
exchange.Encode(algo, inputFormat, outputFormat, data, keyFormat, key)示例
-
用交易所对象配置的secretKey对请求参数做HMAC-SHA256签名。
javascriptfunction main() { var query = "symbol=BTCUSDT×tamp=" + Date.now() var signature = exchange.Encode("sha256", "raw", "hex", query, "raw", "{{secretkey}}") Log(signature) // 输出:64个字符的十六进制签名 }pythonimport time def main(): query = "symbol=BTCUSDT×tamp=" + str(int(time.time() * 1000)) signature = exchange.Encode("sha256", "raw", "hex", query, "raw", "{{secretkey}}") Log(signature) # 输出:64个字符的十六进制签名rustfn main() { let query = format!("symbol=BTCUSDT×tamp={}", Unix() * 1000); let signature = exchange.Encode("sha256", "raw", "hex", &query, "raw", "{{secretkey}}"); Log!(signature); // 输出:64个字符的十六进制签名 } -
Bybit v5私有WebSocket鉴权并订阅仓位推送(wss协议)示例:传入
key时按HMAC计算,签名为HMAC_SHA256(secretKey, "GET/realtime" + expires)的hex编码,expires为毫秒时间戳;"{{secretkey}}"引用交易所对象中配置的secretKey(按字符串使用,所以keyFormat为string),策略代码中不出现明文密钥。javascriptfunction main() { var APIKEY = "your Bybit API Key" // expires为毫秒时间戳;签名 = HMAC_SHA256(secretKey, "GET/realtime" + expires),hex编码 var expires = Date.now() + 10000 var signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + expires, "string", "{{secretkey}}") var client = Dial("wss://stream.bybit.com/v5/private", 60) if (!client) { Log("连接失败") return } client.write(JSON.stringify({op: "auth", args: [APIKEY, expires, signature]})) client.write(JSON.stringify({op: "subscribe", args: ["position"]})) var positions = {} var lastPing = Date.now() while (true) { // Bybit建议每20秒发送一次心跳 if (Date.now() - lastPing >= 20000) { client.write(JSON.stringify({op: "ping"})) lastPing = Date.now() } var buf = client.read(1000) if (buf === "") { break // 连接已断开 } if (!buf) { continue } var msg = JSON.parse(buf) if (msg.op == "auth" && !msg.success) { Log("auth failed", msg.ret_msg) break } if (msg.topic == "position") { msg.data.forEach(function(p) { var key = p.symbol + "/" + p.positionIdx var now = p.side + " " + p.size if (positions[key] !== now) { Log("position change", key, positions[key], "->", now, "@") positions[key] = now } }) } } }pythonimport time import json def main(): APIKEY = "your Bybit API Key" # expires为毫秒时间戳;签名 = HMAC_SHA256(secretKey, "GET/realtime" + expires),hex编码 expires = int(time.time() * 1000) + 10000 signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + str(expires), "string", "{{secretkey}}") client = Dial("wss://stream.bybit.com/v5/private", 60) if not client: Log("连接失败") return client.write(json.dumps({"op": "auth", "args": [APIKEY, expires, signature]})) client.write(json.dumps({"op": "subscribe", "args": ["position"]})) positions = {} lastPing = time.time() while True: # Bybit建议每20秒发送一次心跳 if time.time() - lastPing >= 20: client.write(json.dumps({"op": "ping"})) lastPing = time.time() buf = client.read(1000) if buf == "": break # 连接已断开 if not buf: continue msg = json.loads(buf) if msg.get("op") == "auth" and not msg.get("success"): Log("auth failed", msg.get("ret_msg")) break if msg.get("topic") == "position": for p in msg["data"]: key = "%s/%s" % (p["symbol"], p["positionIdx"]) now = p["side"] + " " + p["size"] if positions.get(key) != now: Log("position change", key, positions.get(key), "->", now, "@") positions[key] = nowrustuse std::collections::HashMap; fn main() { let apikey = "your Bybit API Key"; // expires为毫秒时间戳;签名 = HMAC_SHA256(secretKey, "GET/realtime" + expires),hex编码 let expires = Unix() * 1000 + 10000; let signature = exchange.Encode("sha256", "string", "hex", &format!("GET/realtime{}", expires), "string", "{{secretkey}}"); let mut client = Dial::new("wss://stream.bybit.com/v5/private", 60); if !client.Valid() { Log!("连接失败"); return; } // Rust SDK没有JSON序列化功能,用字符串拼接构造请求 client.write(&format!(r#"{{"op":"auth","args":["{}",{},"{}"]}}"#, apikey, expires, signature), 0); client.write(r#"{"op":"subscribe","args":["position"]}"#, 0); let mut positions: HashMap<String, String> = HashMap::new(); let mut last_ping = Unix(); while !client.IsClosed() { // Bybit建议每20秒发送一次心跳 if Unix() - last_ping >= 20 { client.write(r#"{"op":"ping"}"#, 0); last_ping = Unix(); } let buf = client.read(1000); if buf == "" { continue; } let msg = match JSONParse(&buf) { Some(v) => v, None => continue, }; if msg["op"].as_str() == Some("auth") && msg["success"].as_bool() != Some(true) { Log!("auth failed", msg["ret_msg"].as_str().unwrap_or("")); break; } if msg["topic"].as_str() == Some("position") { if let Some(arr) = msg["data"].as_array() { for p in arr { let key = format!("{}/{}", p["symbol"].as_str().unwrap_or(""), p["positionIdx"].as_i64().unwrap_or(0)); let now = format!("{} {}", p["side"].as_str().unwrap_or(""), p["size"].as_str().unwrap_or("0")); if positions.get(&key) != Some(&now) { Log!("position change", &key, &now, "@"); positions.insert(key, now); } } } } } }
返回值
| 类型 | 描述 |
string | 计算出来的哈希值编码。 |
参数
| 名称 | 类型 | 必填 | 描述 |
algo | string | 是 | 签名或哈希使用的算法,例如 |
inputFormat | string | 是 | 用于指定 |
outputFormat | string | 是 | 用于指定输出的数据格式。 |
data | string | 是 | 所要处理的数据。 |
keyFormat | string | 否 | 用于指定 |
key | string | 否 | 签名计算时使用的密钥,可以使用明文字符串。也可以使用 |
参考
备注
仅实盘支持调用exchange.Encode()函数。"{{accesskey}}"、"{{secretkey}}"的引用方式仅在exchange.Encode()函数使用时有效。
algo参数的取值:
| 类别 | 取值 |
|---|---|
| 不使用算法 | raw |
| 签名 | sign、signTx |
| 哈希(MD、SHA-1、SHA-2) | md4、md5、sha1、sha256、sha512、sha512.384、sha512.256、sha512.224 |
| 哈希(SHA-3、Keccak) | keccak256、sha3.224、sha3.256、sha3.384、sha3.512、sha3.keccak256、sha3.keccak512 |
| 哈希(其它) | ripemd160、blake2b.256、blake2b.512、blake2s.128、blake2s.256 |
| 字符串编码、解码 | text.encoder.utf8、text.decoder.utf8、text.encoder.gbk、text.decoder.gbk |
| Ed25519 | ed25519、ed25519.seed;可以指定哈希算法,例如ed25519.md5、ed25519.sha512 |