Kompres string hex transaksi

Sep 06 2020

Saya menyadari hex transaksi bisa sangat panjang dan Anda membutuhkannya untuk menyiarkan tx menggunakan API blockstream.info:

https://blockstream.info/testnet/api/tx

https://github.com/Blockstream/esplora/blob/master/API.md

Jika pengguna ingin mengirim hex ini menggunakan pesan teks yang memungkinkan 160 karakter dalam satu pesan, apa cara terbaik untuk mengatasi masalah ini? Saya mencoba mencari cara untuk mengkompresnya, mengirim ke nomor yang diteruskan ke server web menjalankan kode PHP, string hex didekompresi dan dikirim ke blockstream.info untuk penyiaran tx. Pengkodean Base64 setelahnya gzcompress()tidak dapat mengurangi jumlah karakter menjadi kurang dari 160.

Contoh:

Hex:

02000000000101e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee410100000000fdffffff02b0a90a000000000016001421e2f997b3bd36e273eaca365da8515a389444ae40420f0000000000160014829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e0247304402200f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346022062dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf0121020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa49f31b00

Dikompresi dan dikodekan Base64:

eNpdkNmJBEAIRFPyarsNxzP/ENZZGBZW9Eew6pVA8C0EbGObIG4zw47Ie6bg5WUtZ0pHKnsuMxiv7cLOHFU0ut2yCl+xqfktoAA3cPiz0R0hbBqzGxzF2nS5PZ31lL+Dx/mZiHgLCMH8v35kTRU5GncYI42V2S7Otu7W4syzBpLLIAK0Mec197kcfcXSB01lzS7cmCNQTb04etdUk5ZLhtCYZh6x6EdDqZIB9oSyjqOFnJZrh858oCLlRcsUJ2EcN2+WxTRn58wBJITN8/altV4ZIUb9oHi1J9EqzomuR/qW8s3LaS3Ikes1ult3sU9mgB8sW3Vy

Jawaban

2 RedGrittyBrick Sep 06 2020 at 23:44

Mengompresi lebih banyak atau lebih sedikit nomor acak itu sia-sia. Pilihan terbaik Anda adalah menggunakan pengkodean yang lebih ringkas. Base64 lebih baik daripada Hex tetapi mungkin ada pengkodean lain yang berperforma lebih baik

Wikipedia mendaftar banyak dan mengurutkan mereka dalam urutan efisiensi

Encoding            Data type                    Efficiency
yEnc                Arbitrary, mostly non-text   ~98%
Ascii85             Arbitrary                     80%
Base85 (RFC 1924)   Arbitrary                     80%
Base64              Arbitrary                     75%
...

Anda jelas dapat melakukan lebih baik jika Anda menggunakan 8-bit (misalnya poin kode Unicode yang dapat dicetak yang memiliki pengkodean byte tunggal dalam UTF-8) tetapi karena SMS menggunakan set karakter 7-bit (sejauh yang saya tahu) Anda tidak akan berbuat banyak lebih baik

CodingEnthusiast Sep 07 2020 at 13:50

Jika pengguna ingin mengirim hex ini menggunakan pesan teks yang memungkinkan 160 karakter dalam satu pesan, apa cara terbaik untuk mengatasi masalah ini?

Mengubah 222 byte menjadi 160 karakter akan menjadi sangat menantang sehingga fokus kita tidak hanya pada pengkodean tetapi harus diarahkan pada 222 byte itu sendiri. Karena ini bukan byte acak dan struktur transaksi bitcoin bukanlah struktur yang paling efisien, ada peluang untuk memampatkan byte ini (atau lebih akurat untuk menghilangkan beberapa byte "tidak berguna").
Pertama-tama mari kita hancurkan dan lihat byte mana yang dapat kita hilangkan:

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. Versi
    Bisa berubah menjadi 1 byte dikodekan sebagai CompactInt ->02
  2. Bendera saksi
    Dapat dilewati -> (berfungsi dengan memodifikasi # 6)
  3. Jumlah input
    Tidak ada perubahan ->01
  4. Masukkan hash transaksi
    Tidak ada perubahan ->e939fb23e9991ebbc75fd08c736da32ca12d98a4ff1b8e970e97f5661927ee41
  5. Indeks masukan
    Another CompactInt ->01
  6. Skrip tanda tangan
    Sebagai aturan, semua skrip dapat dimulai dengan bendera 1 = P2PKH, 2 = P2WPKH, 3 = P2SH, ... 255 = tidak ditentukan, dan jika tidak ditentukan, skrip yang tepat ditempatkan di sini dengan ukuran dan yang lainnya. Seperti setiap bagian lainnya, penerima harus membuat skrip dengan benar (setel bendera saksi # 2, pindahkan ini ke item saksi # 14 & # 15, tambahkan panjang untuk setiap dorongan, DER menyandikan tanda tangan)
    Saksi menjadi: <1-byte-flag > <32-byte-r> <32-byte-s> <33-byte-pubkey>
    <02><0f8e3e573be749caf1964a85707bf540de2e7b367ae46c23bd4f21932ff82346><62dc3007072cd5a19b45e479525f4829bc48be4fd3c21b5a9ae34bcf9a3a3ccf><01><020f88c7db36cbb492e80d3062fc19db55bed82687498f8cfe6d0cf47adf6687aa>
    Jika kunci pub tidak dikompresi, byte pertama diubah menjadi 0x82=0b10000010(kumpulan bit paling signifikan) untuk menunjukkan kunci pub yang tidak dikompresi harus dibuat.
  7. Urutan
    dapat dikodekan sebagai "StackInt" (angka yang didorong ke tumpukan yang bisa menjadi negatif)
    1 = OP_1, 2 = OP_2 -1 = OP_NegativeOne -2 = 0x82, 321321 = 0x4e29e70400
    Karena 0xfdffffff adalah UInt32.Max-2 - >82
  8. Jumlah keluaran
    Tidak ada perubahan ->02
  9. Jumlah
    Sebagai CompactInt->feb0a90a00
  10. Skrip pubkey
    Mirip dengan skrip tanda tangan, kita bisa menggunakan bendera untuk skrip standar, misalnya. 0x03 bisa berupa skrip P2WPKH ->0321e2f997b3bd36e273eaca365da8515a389444ae
  11. Jumlah
    Sebagai CompactInt->fe40420f00
  12. Skrip pubkey
    Sama seperti sebelumnya03829e2dbcf6b7f31bc93633971f71f6f6b9b5f89e
  13. Jumlah item saksi
    Dihapus ->
  14. Saksi
    Dihapus (sudah ditempatkan di # 6) ->
  15. Saksi
    Dihapus (sudah ditempatkan di # 6) ->
  16. Locktime
    Tidak ada perubahan ->49f31b00

Sekarang 222 byte dikompresi menjadi 192 byte (13,5%) yang kemudian dapat dikodekan dengan pengkodean yang lebih efisien untuk mendapatkan hasil terbaik.
Ini juga dapat dikompresi lebih banyak jika Anda mengirim transaksi ini ke penerima dana yang sebenarnya dengan melewatkan keluarannya. Misalnya ketika Anda seharusnya membayar 698800satoshi ke bc1qy830n9anh5mwyul2egm9m2z3tgufg39wk4g0eu, penerima sudah mengetahui hal ini dan Anda tidak perlu memberi tahu mereka lagi. Itu berarti 26 byte dalam # 11 dan # 12 dapat dilewati, mengurangi ukuran menjadi 166 byte (25,2%) . Tetapi harus disepakati bahwa output penerima adalah yang pertama misalnya.
Ini bisa lebih dikompresi dengan menghasilkan lebih banyak kesepakatan:

  • Versi tx harus selalu 2 -> 165 byte
  • SigHashType harus selalu SigHashAll -> 164 byte (hapus dari setiap masukan # 6 di sini)
  • Setiap urutan masukan harus diatur ke int -> 163 byte yang telah ditentukan (lewati # 7)
  • Tx harus selalu memiliki 2 keluaran -> 162 byte (lewati # 8)
  • Waktu penguncian harus selalu 0 -> 158 byte (lewati # 16) ( 28,8% )