Development

處理 psbt2 (BIP370) 的“有 SIGHASH_SINGLE”標誌

  • December 17, 2021

BIP370 在欄位中指定一個位標誌(位 2)PSBT_GLOBAL_TX_MODIFIABLE,“指示事務是否具有必須保留輸入和輸出配對的 SIGHASH_SINGLE 簽名”和“如果 Has SIGHASH_SINGLE 標誌為 True,則建構子必須遍歷輸入和找到具有使用 SIGHASH_SINGLE 簽名的輸入。必須在這些輸入及其相應的輸出之前添加相同數量的輸入和輸出“

BIP370 沒有指定在其他情況下如何處理此標誌,當標誌與其他欄位的不一致可能表明存在某些問題時,最好以某種方式對此問題做出反應而不是忽略它。

例如,解析 PSBTv2 的程式碼可能會發現 ‘Has SIGHASH_SINGLE flag’ 在 中為 false PSBT_GLOBAL_TX_MODIFIABLE,但後來在處理輸入欄位時,發現 psbt 輸入之一具有SIGHASH_SINGLE.

程式碼應該如何對此做出反應?這是明顯的不一致,如果忽略這種情況,並且儘管輸入中存在“有 SIGHASH_SINGLE 標誌”,但仍將其視為錯誤SIGHASH_SIGNGLE,則在移動輸入或輸出時簽名可能會失效。

同樣,如果標誌為真,但沒有輸入具有SIGHASH_SINGLEsighash 類型,是否應將其視為 PSBT 不一致的指示?

我們可以說“這個標誌總是等於any(input.has_sighash_single() for input in psbt.inputs)”(1)嗎?

PSBT_IN_SIGHASH_TYPE不需要存在,如果不存在,簽名者“可以使用他們希望的任何 sighash 類型”。但是讓我們想像一下,PSBT_IN_SIGHASH_TYPE如果要使用 BIP 文本,則必須始終存在SIGHASH_SINGLE。在這種情況下 (1) 是否成立?那麼我們甚至需要這個標誌嗎?

應該說如果有最終確定的輸入,則忽略“有 SIGHASH_SINGLE”標誌,因為必須在最終確定之前完成任何輸入的添加?

SIGHASH_SINGLE當自定義腳本以未知格式用於見證數據時,如何檢查最終輸入以使用簽名?

BIP174 表示,在完成時,已完成scriptSigscriptWitness應保留,並且“應從 PSBT 中清除除 UTXO 和輸入鍵值映射中的未知欄位之外的所有其他數據” *****。如果PSBT_IN_SIGHASH_TYPE被清除,則一般無法知道見證人是否具有帶有 的簽名SIGHASH_SINGLE,除非程式碼能夠以某種方式理解見證人的格式。

*****順便說一句,此措辭不僅應包括未知欄位,還應保留專有欄位。我應該做 PR 來添加這個嗎?

弄清楚如何在 PSBTv2 中處理 SIGHASH_SINGLE 輸入是設計時的主要問題之一。不幸的是,當這被提到郵件列表時,幾乎沒有回應,所以結果是我不得不自己嘗試想出一個解決方案,這可能有點不足。

例如,解析 PSBTv2 的程式碼可能會發現 ‘Has SIGHASH_SINGLE flag’ 在 中為 false PSBT_GLOBAL_TX_MODIFIABLE,但後來在處理輸入欄位時,發現 psbt 輸入之一具有SIGHASH_SINGLE.

期望不會發生這種不一致,因為確保在添加 SIGHASH_SINGLE 簽名時設置 Has SIGHASH_SINGLE 標誌符合 Sginer 的最大利益。無需任何人檢查是否沒有其他簽名是 SIGHASH_SINGLE,因此預期的操作是忽略不一致性。這可能會導致交易無效,但這是允許的結果。

同樣,如果標誌為真,但沒有輸入具有SIGHASH_SINGLEsighash 類型,是否應將其視為 PSBT 不一致的指示?

是的,但是在沒有 SIGHASH_SINGLE 簽名的情況下進行設置並不一定會造成傷害,除了會使添加額外的輸入變慢。

我們可以說“這個標誌總是等於any(input.has_sighash_single() for input in psbt.inputs)”(1)嗎?

這就是意圖。

PSBT_IN_SIGHASH_TYPE不需要存在,如果不存在,簽名者“可以使用他們希望的任何 sighash 類型”。但是讓我們想像一下,PSBT_IN_SIGHASH_TYPE如果要使用 BIP 文本,則必須始終存在SIGHASH_SINGLE。在這種情況下 (1) 是否成立?那麼我們甚至需要這個標誌嗎?

除了作為優化之外,沒有真正需要標誌。它的存在是為了允許建構子跳過檢查每個輸入,但如果標誌不存在,則可能只是建構子必須檢查每個輸入的 SIGHASH_SINGLE 簽名。因此,如果為每個輸入都提供了 PSBT_IN_SIGHASH_TYPE,那麼 Has SIGHASH_SINGLE 仍然會被使用。

應該說如果有最終確定的輸入,則忽略“有 SIGHASH_SINGLE”標誌,因為必須在最終確定之前完成任何輸入的添加?

不,有可能在添加其他輸入時最終確定輸入。使用 SIGHASH_SINGLE 和 SIGHASH_ANYONECANPAY 可以做到這一點。

SIGHASH_SINGLE當自定義腳本以未知格式用於見證數據時,如何檢查最終輸入以使用簽名?

需要一個腳本解釋器。該過程將使用簽名驗證器執行最終確定的 scriptSigs 和 scriptWitnesses,該簽名驗證器可以報告它是否必須驗證任何 SIGHASH_SINGLE 輸入。添加 Has SIGHASH_SINGLE 的部分原因是因為我認為建構子必須有一個腳本解釋器來確保他們沒有破壞任何 SIGHASH_SINGLE 東西是不合理的。

*****順便說一句,此措辭不僅應包括未知欄位,還應保留專有欄位。我應該做 PR 來添加這個嗎?

專有欄位通常與未知欄位混為一談,因為它們對於不實現那些特定專有欄位的實現是未知的。但是,是的,可以澄清案文。

引用自:https://bitcoin.stackexchange.com/questions/111286