Skip to main content
你提交一筆訂單,鏈會給它分配一個訂單 ID。那個 ID 是權威的,但你要等訂單接受之後才知道它;偏偏你要做的事,可能就是去撤掉一筆你根本沒看到有沒有被接受的訂單,這就成了問題。 用戶端訂單 ID 解決的就是這個。識別碼由你自己產生,在提交時附上,從你發出請求的那一刻起就可以用它來操作這筆訂單。

為什麼這件事比聽上去重要

設想一次提交逾時了。這筆訂單到鏈上了嗎?你不知道。沒有用戶端訂單 ID,你要麼去查最近的訂單,然後靠市場、方向、價格和數量去猜,要麼什麼都不做,賭運氣。 有了它,這種含糊就消失了。你用自己產生的識別碼撤單:訂單存在,就撤掉;訂單根本沒到,撤單請求什麼也找不到。無論哪一種,你都停在一個確定的狀態上,而沒有人盯著的系統,需要的正是這個。 對帳能做得下去,靠的也是這個。你自己的記錄以你分配的識別碼為鍵,把你這邊的視角和鏈上的視角對起來,是一次查表,不是一次啟發式猜測。

格式

識別碼是一個 16 位元組的值,提交時寫成 0x 前綴、小寫、共 32 個字元的十六進位字串。
協議強制執行三條規則:
  • 只接受小寫。 大寫十六進位會直接拒絕,不會幫你正規化。
  • 長度必須精確。 更短或更長的值都會被拒絕。
  • 全零值被保留。 0x00000000...0000 是表示不存在的哨兵值,不能用作識別碼。
這個欄位是選填的。沒帶識別碼的訂單,各方面都表現正常,只是不能靠用戶端訂單 ID 撤單,只能用鏈上分配的訂單 ID。

唯一性

唯一性的作用範圍是子帳戶:簽章地址與其下子帳戶的組合。 由此有兩個推論。同一地址底下的不同子帳戶可以用相同的識別碼而不衝突,跑幾套各自產生 ID 的獨立策略時很有用。而在同一個子帳戶內,重複使用一個還掛在未成交訂單上的識別碼,算是錯誤,不是替換。
識別碼要隨機產生,不要用遞增序號。計數器很誘人,因為它讓順序一目了然,但只要重新啟動一次、計數器掉了,就會和還掛著的未成交訂單撞號;而 16 個隨機位元組在實務上永遠不會碰撞。

你能用它做什麼

生命週期

識別碼屬於訂單,而不屬於你的會話。訂單成交或撤銷之後仍然查得到,事後對帳好用,靠的就是這一點。 它標識的那筆訂單一旦不再未成交,識別碼就可以重複使用。但實務上幾乎沒有理由這麼做:重新產生一個隨機值成本是零,還能免去「某條歷史記錄到底指哪筆訂單」的疑問。

後續閱讀

修改訂單

改動一筆未成交訂單,以及它的識別碼會怎樣。

訂單類型

你可以給哪些東西附上識別碼。

開發者

在程式碼中提交訂單並處理含糊的回應。

交易排序

為什麼同一區塊內提交的撤單會先於主動吃單執行。