壓縮交易十六進製字元串
我意識到事務十六進制可能很長,您需要它來使用 blockstream.info API 廣播 tx:
https://blockstream.info/testnet/api/tx
<https://github.com/Blockstream/esplora/blob/master/API.md>
如果使用者想使用允許在一條消息中包含 160 個字元的文本消息發送此十六進制,那麼解決此問題的最佳方法應該是什麼?我嘗試研究壓縮它的方法,發送到一個轉發到執行 PHP 程式碼的 Web 伺服器的數字,將十六進製字元串解壓縮並發送到 blockstream.info 以廣播 tx。Base64 編碼後
gzcompress()
無法將字元數減少到 160 以下。例子:
十六進制:
02000000000101e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee410100000000fdffffff02b0a90a000000000016001421e2f997b3bd36e273eaca365da8515a389444ae40420f0000000000160014829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e0247304402200f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346022062dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf0121020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa49f31b00
壓縮和 Base64 編碼:
eNpdkNmJBEAIRFPyarsNxzP/ENZZGBZW9Eew6pVA8C0EbGObIG4zw47Ie6bg5WUtZ0pHKnsuMxiv7cLOHFU0ut2yCl+xqfktoAA3cPiz0R0hbBqzGxzF2nS5PZ31lL+Dx/mZiHgLCMH8v35kTRU5GncYI42V2S7Otu7W4syzBpLLIAK0Mec197kcfcXSB01lzS7cmCNQTb04etdUk5ZLhtCYZh6x6EdDqZIB9oSyjqOFnJZrh858oCLlRcsUJ2EcN2+WxTRn58wBJITN8/altV4ZIUb9oHi1J9EqzomuR/qW8s3LaS3Ikes1ult3sU9mgB8sW3Vy
壓縮或多或少的隨機數是徒勞的。您最好的選擇就是使用更緊湊的編碼。Base64 比 Hex 更好,但可能存在其他性能更好的編碼
維基百科列出了許多並按效率排序
Encoding Data type Efficiency yEnc Arbitrary, mostly non-text ~98% Ascii85 Arbitrary 80% Base85 (RFC 1924) Arbitrary 80% Base64 Arbitrary 75% ...
如果您使用 8 位(例如,在 UTF-8 中具有單字節編碼的 Unicode 可列印程式碼點),您顯然可以做得更好,但由於 SMS 使用 7 位字元集(據我所知),您不會做太多更好的
如果使用者想使用允許在一條消息中包含 160 個字元的文本消息發送此十六進制,那麼解決此問題的最佳方法應該是什麼?
將 222 字節轉換為 160 個字元將非常具有挑戰性,因此我們的重點不能只放在編碼上,而是應該針對 222 字節本身。由於它不完全是隨機字節,而且比特幣交易結構也不是最有效的結構,因此有機會壓縮這些字節(或更準確地說是去除一些“無用”字節)。
讓我們首先分解它,看看我們可以擺脫哪些字節:
1) 02000000 2) 0001 3) 01 4) e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee41 5) 01000000 6) 00 7) fdffffff 8) 02 9) b0a90a0000000000 10) 16001421e2f997b3bd36e273eaca365da8515a389444ae 11) 40420f0000000000 12) 160014829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e 13) 02 14) 47304402200f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346022062dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf01 15) 21020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa 16) 49f31b00
- 版本
可以變成 1 字節編碼為CompactInt ->
02
2. 見證標誌可以跳過-> (通過修改#6來工作) 3. 輸入計數
無變化 ->
01
4. 輸入交易雜湊無變化 ->
e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee41
5. 輸入索引另一個 CompactInt ->
01
6. 簽名腳本作為一項規則,所有腳本都可以以標記 1=P2PKH、2=P2WPKH、3=P2SH、… 255=未定義開始,並且當它們未定義時,將精確的腳本與大小和其他所有內容一起放置在此處。與其他所有部分一樣,接收者必須正確建構腳本(設置見證標誌 #2,將這些移動到見證項目#14 和#15,為每次推送添加長度,DER 編碼簽名)
見證變為:<1-byte-flag ><32-byte-r><32-byte-s><33-byte-pubkey>
<02><0f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346><62dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf><01><020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa>
如果 pubkey 未壓縮,則第一個字節更改為
0x82=0b10000010
(最高有效位集)以指示應構造未壓縮的 pubkey。 7. 序列可以編碼為“StackInt”(一個推入堆棧的數字,可以是負數)
1=OP_1, 2=OP_2 -1=OP_NegativeOne -2=0x82, 321321=0x4e29e70400
因為 0xfdffffff 是 UInt32.Max-2 - >
82
8. 輸出計數無變化 ->
02
9. 金額為
CompactInt
->feb0a90a00
10. 公鑰腳本與簽名腳本類似,我們可以為標準腳本使用標誌,例如。0x03 可能是 P2WPKH 腳本 ->
0321e2f997b3bd36e273eaca365da8515a389444ae
11. 金額為
CompactInt
->fe40420f00
12. 公鑰腳本和以前一樣
03829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e
13. 見證項目計數已刪除 -> 14. 已刪除見證
(它已被放置在 #6 中)-> 15. 已刪除見證
(它已被放置在 #6 中)-> 16. 鎖定時間
沒有變化->
49f31b00
現在 222 字節被壓縮成192 字節 (13.5%),然後可以使用更有效的編碼對其進行編碼以獲得最佳結果。如果您通過跳過其輸出將此交易發送給資金的實際接收者,
這也可能會被進一步*壓縮。*例如,當您應該向 支付
698800
satoshi 時bc1qy830n9anh5mwyul2egm9m2z3tgufg39wk4g0eu
,接收方已經知道這一點,您不必再告訴他們。這意味著可以跳過 #11 和 #12 中的 26 個字節,將大小減少到166 個字節 (25.2%)。但是必須同意,例如接收輸出是第一個輸出。這可以通過提出更多協議來進一步壓縮:
- Tx 版本應始終為 2 -> 165 字節
- SigHashType 應始終為 SigHashAll -> 164 字節(從此處的每個輸入 #6 中刪除)
- 每個輸入序列應設置為預定義的 int -> 163 字節(跳過 #7)
- Tx 應該總是有 2 個輸出 -> 162 字節(跳過 #8)
- 鎖定時間應始終為 0 -> 158 字節(跳過 #16)(28.8%)