Comprimi la stringa esadecimale della transazione
Mi sono reso conto che l'esadecimale della transazione può essere molto lungo e ne hai bisogno per trasmettere un tx usando l'API blockstream.info:
https://blockstream.info/testnet/api/tx
https://github.com/Blockstream/esplora/blob/master/API.md
Se l'utente desidera inviare questo esadecimale utilizzando un messaggio di testo che consente 160 caratteri in un messaggio, quale dovrebbe essere il modo migliore per risolvere questo problema? Ho provato a cercare come comprimerlo, inviare a un numero che inoltra al server web che esegue un codice PHP, la stringa esadecimale viene decompressa e inviata a blockstream.info per la trasmissione in tx. La codifica Base64 dopo gzcompress()non è riuscita a ridurre il numero di caratteri a meno di 160.
Esempio:
Esadecimale:
02000000000101e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee410100000000fdffffff02b0a90a000000000016001421e2f997b3bd36e273eaca365da8515a389444ae40420f0000000000160014829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e0247304402200f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346022062dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf0121020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa49f31b00
Compresso e codificato Base64:
eNpdkNmJBEAIRFPyarsNxzP/ENZZGBZW9Eew6pVA8C0EbGObIG4zw47Ie6bg5WUtZ0pHKnsuMxiv7cLOHFU0ut2yCl+xqfktoAA3cPiz0R0hbBqzGxzF2nS5PZ31lL+Dx/mZiHgLCMH8v35kTRU5GncYI42V2S7Otu7W4syzBpLLIAK0Mec197kcfcXSB01lzS7cmCNQTb04etdUk5ZLhtCYZh6x6EdDqZIB9oSyjqOFnJZrh858oCLlRcsUJ2EcN2+WxTRn58wBJITN8/altV4ZIUb9oHi1J9EqzomuR/qW8s3LaS3Ikes1ult3sU9mgB8sW3Vy
Risposte
Comprimere un numero casuale più o meno è inutile. La tua migliore opzione è semplicemente usare una codifica più compatta. Base64 è migliore di Hex ma esistono altre codifiche che funzionano meglio
Wikipedia ne elenca molti e li classifica in ordine di efficienza
Encoding Data type Efficiency
yEnc Arbitrary, mostly non-text ~98%
Ascii85 Arbitrary 80%
Base85 (RFC 1924) Arbitrary 80%
Base64 Arbitrary 75%
...
Ovviamente puoi fare di meglio se usi 8 bit (ad esempio punti di codice stampabili Unicode che hanno codifiche a byte singolo in UTF-8) ma poiché SMS utilizza un set di caratteri a 7 bit (per quanto ne so) non farai molto meglio
Se l'utente desidera inviare questo esadecimale utilizzando un messaggio di testo che consente 160 caratteri in un messaggio, quale dovrebbe essere il modo migliore per risolvere questo problema?
Trasformare 222 byte in 160 caratteri sarà molto impegnativo, quindi il nostro focus non può essere solo sulla codifica, ma dovrebbe essere diretto al 222 byte stesso. Poiché non è esattamente byte casuali e la struttura delle transazioni bitcoin non è esattamente la struttura più efficiente, ci sono opportunità per comprimere questi byte (o più accuratamente per sbarazzarsi di alcuni byte "inutili").
Analizziamolo prima e vediamo di quali byte possiamo sbarazzarci:
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
- La versione
potrebbe trasformarsi in 1 byte codificato come CompactInt ->02 - La bandiera del testimone
può essere saltata ->(funziona modificando # 6) - Conteggio input
Nessuna modifica ->01 - Hash della transazione di input
Nessuna modifica ->e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee41 - Indice di input
Un altro CompactInt ->01 - Script di firma
Di norma tutti gli script potrebbero iniziare con un flag 1 = P2PKH, 2 = P2WPKH, 3 = P2SH, ... 255 = non definito, e quando non sono definiti lo script esatto viene posizionato qui con la dimensione e tutto il resto. Come ogni altra parte, il destinatario deve costruire lo script correttamente (impostare il flag del testimone n. 2, spostarli sugli elementi del testimone n. 14 e # 15, aggiungere lunghezze per ogni push push, firma della codifica DER) Il
testimone diventa: <flag di 1 byte > <32-byte-r> <32-byte-s> <33-byte-pubkey>
<02><0f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346><62dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf><01><020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa>
Se pubkey non è stato compresso, il primo byte viene modificato in0x82=0b10000010(set di bit più significativo) per indicare che è necessario costruire pubkey non compresso. - La sequenza
può essere codificata come "StackInt" (un numero che viene inserito nello stack che può essere negativo)
1 = OP_1, 2 = OP_2 -1 = OP_NegativeOne -2 = 0x82, 321321 = 0x4e29e70400
Poiché 0xfdffffff è UInt32.Max-2 - >82 - Conteggio output
Nessuna modifica ->02 - Importo
comeCompactInt->feb0a90a00 - Script Pubkey
Simile allo script di firma potremmo usare flag per script standard, ad es. 0x03 potrebbe essere script P2WPKH ->0321e2f997b3bd36e273eaca365da8515a389444ae - Importo
comeCompactInt->fe40420f00 - Script Pubkey
Come prima03829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e - Conteggio elementi testimone
rimosso -> - Testimone
rimosso (è già posizionato in # 6) -> - Testimone
rimosso (è già posizionato in # 6) -> - Locktime
Nessuna modifica ->49f31b00
Ora i 222 byte vengono compressi in 192 byte (13,5%) che possono quindi essere codificati con una codifica più efficiente per ottenere il miglior risultato possibile.
Questo potrebbe anche essere più compresso se stai inviando questa transazione al destinatario effettivo dei fondi saltando i loro output. Ad esempio, quando avresti dovuto pagare 698800satoshi a bc1qy830n9anh5mwyul2egm9m2z3tgufg39wk4g0eu, il destinatario lo sa già e non devi dirglielo di nuovo. Ciò significa che 26 byte in # 11 e # 12 possono essere saltati riducendo la dimensione a 166 byte (25,2%) . Ma si deve concordare che l'uscita ricevente è la prima, ad esempio.
Questo potrebbe essere ulteriormente compresso elaborando più accordi:
- La versione Tx dovrebbe sempre essere 2 -> 165 byte
- SigHashType dovrebbe sempre essere SigHashAll -> 164 byte (rimuovere da ogni input # 6 qui)
- Ogni sequenza di input deve essere impostata su int predefinito -> 163 byte (salta # 7)
- Tx dovrebbe sempre avere 2 uscite -> 162 byte (salta # 8)
- Il tempo di blocco dovrebbe sempre essere 0 -> 158 byte (ignora # 16) ( 28,8% )