BLOG |
Nasıl yapılır
Tohum ve durum yedekleriyle 100 bin sat geri kazanma.
Spark ağından gerçek anlamda tek taraflı bir çıkış: rakamlar, başarısızlıklar ve çıkarılan dersler. Aşağıda anlatılan her şey Bitcoin ana ağında gerçekleşmiştir ve zincir üzerinde herkes tarafından doğrulanabilir.
Bitcoin ana ağında (Spark kullanarak) bir non-custodial Blink cüzdanından zorla çıkış yaptım. Çıkış işlemi için gereken her şey cüzdan tohumundan türetildi: ücret finansmanı, işlem imzalaması ve son temizleme. Tek ek unsur ise bir kurtarma paketi; bu, Spark ağına hâlâ erişilebilirken kaydedilen cüzdanın çıkış verilerinin bir anlık görüntüsüdür. Bu paket elimdeyken, çıkış işlemi için kimsenin işbirliğine gerek kalmadı.
100.000 sat'lık bir cüzdanın gerçek rakamları:
“Gözaltında tutulmama” durumu, istediğiniz zaman ayrılabileceğiniz anlamına gelir. Ancak yangın merdiveni dardır. İşte maliyetleri, başarısızlıkları ve çıkarılan dersleri içeren hikayenin tamamı.
"Saklama hizmeti sunmayan" ifadesi, pazarlama metinlerine kolayca eklenebilen bir terimdir. Biz bunun, size inanmanızın istendiği bir şey değil, doğrulayabileceğiniz bir şey olmasını istedik. Bu nedenle gerçek bir Blink cüzdanını aldık, Spark ağının ortadan kaybolduğunu varsaydık ve yalnızca tohum anahtarı, kaydedilmiş kurtarma paketi ve herkesin kullanabileceği açık kaynaklı araçları kullanarak kurtarılabilir tüm sat'ları Bitcoin blok zincirine geri aktardık. Bu yazı, bunun kanıtıdır.
22 yaprağa dağılmış 100.000 sat'ı barındıran bir mobil Spark cüzdanı.

Spark’ı ilk kez duyan okuyucular içinkısa biraçıklama: Bir Spark cüzdanındaki varlıklar, bir grup operatör tarafından yönetilen paylaşımlı bir zincir üstü ağaçta bulunur ve bu ağacın her bir yaprağı, cüzdan bakiyesinin ayrı bir parçasıdır ve Bitcoin’e geri dönen kendine özgü önceden imzalanmış bir yola sahiptir. Tek taraflı çıkış, bu yolu — yani yaprağın zincir üstü işlemlerden oluşan çıkış zincirini, ağacın aşağısına doğru seviye seviye onaylayarak — yayınlamak ve operatörlerin işbirliği olmadan yaprağı Bitcoin’e zorla aktarmak anlamına gelir.
22 yaprağa yayılmış 100.000 sat'lık bir mobil Spark cüzdanı. Spark cüzdanları normal kullanım yoluyla yaprak biriktirir (ödemeler ağacı böler ve yeniden böler) ve her yaprak kendi çıkış zincirini taşır: operatörün işbirliği olmadan yaprağı Bitcoin'e zorlamak için seviye seviye onaylanması gereken zincir üzerindeki işlemler. Bu cüzdan için bu, 22 zincir boyunca 253 işlem paketi anlamına geliyordu. 100 bin satoshi için.
Spark operatörleri çevrimdışı hale geldiğinde yalnızca tohum kullanılarak kurtarma işlemi mümkün değildir: mevcut yapraklar yalnızca tohumdan tespit edilemez. Çıkış işlemi için, operatörler hâlâ çevrimiçi iken güncellenen bir kurtarma paketi — cüzdanın yapraklarının ve bunların atası olan işlemlerin bir JSON anlık görüntüsü — gereklidir:
refresh-recovery-bundle komutunu SEED_FILE=../.spark-seed.txt ve BUNDLE=../recovery-bundle.json değerleriyle çalıştır
İlk pratik ders: İlk paketimiz fark edilmeden eksik çıkmıştı. Operatörlerin toplu query_nodes(include_parents=true) API, eski ana ağ ağaçlarında kök düğümünü atladığından, 22 çıkış zincirinin her birinde en üstte bir boşluk oluştu ve çevrimdışı paket oluşturma işlemi şu hatayla başarısız oldu: Çıkış zinciri eksik. Eksik ataları düğüm kimliği kullanılarak yeniden getirme (bu işlem kök atlamasını devre dışı bırakır) sorunu çözdü — dışa aktarıcı artık bunu otomatik olarak yapıyor ve açık zincirleri içeren bir paketi kaydetmeyi reddediyor.
Paketinizin üst zincirlerini, bunlara ihtiyaç duyduğunuzdan önce doğrulayın; bir kesinti sırasında tespit edilen eksik bir paket kurtarılamaz.
Çıkış işlemleri sıfır ücretle önceden imzalanır ve ücretler CPFP geçici bağlantı noktaları aracılığıyla ödenir; bu nedenle çıkış işlemi, ücret artışlarını karşılamak için bağımsız bir L1 Bitcoin UTXO’suna ihtiyaç duyar. Araç, cüzdan tohumundan özel bir fonlama adresi türetir (yol m/8797556'/<account>/0: Yalnızca amaç dizini şifrelenmiştir; hesap ve adres dizinleri şifrelenmemiştir; bu nedenle, salt izleme amaçlı bir cüzdan, herhangi bir özel anahtar kullanmadan bir xpub’dan fon aktarım adresini türetip izleyebilir):
cpfp-address komutunu şu şekilde çalıştırın: SEED_FILE=../.spark-seed.txt BUNDLE=../recovery-bundle.json FEE_RATE=1
1 sat/vB oranında, 22 yaprağın tamamından çıkmak için 78.573 sat gerekiyordu. Cüzdan bakiyesinin neredeyse %79’u ücret olarak harcanacaktı. Yaprak başına hesaplamayı yapmadan önce 3ab20a4c…7262 adres ine fon aktardık. Bu konuyla ilgili daha fazla bilgi aşağıda yer almaktadır.
İlk denemede, 253 paketin tamamı arka arkaya Esplora’nın POST /txs/package arayüzü üzerinden paketlenip imzalandı ve gönderildi. İlk paket onaylandı (ana paket 16895bc8…9619, CPFP alt paketi 384cdc6d…3b37). Diğer 252 paket ise reddedildi:
"hata": "TRUC ihlali, tx 16895bc8… alt düzeydeki öğe sayısı sınırını aşacak"
"hata": "geçersiz işlem girişleri (eksik veya harcanmış)"
Spark çıkış işlemleri v3 standardındadır ve TRUC (Topologically Restricted Until Confirmation, BIP 431) olarak da adlandırılır. Mempool politikası, bir v3 kümesini bir adet onaylanmamış ana işlem artı bir adet alt işlem ile sınırlandırır. Bu, önceden imzalanmış sıfır ücretli çıkış işlemlerinin güvenli bir şekilde ücret artışı yapılabilir olmasını sağlar ve aynı zamanda bir çıkış zincirinin her seviyesinin, bir sonraki seviyenin mempool’a girebilmesi için önce onaylanması gerektiği anlamına gelir. 15 paketlik bir zincir, nasıl gönderilirse gönderilsin en az 15 blok sürer. Paketleri arka arkaya gönderen herhangi bir araç, zincir başına ilk paketten sonraki her şeyi askıda bırakır.
Döngüyü otomatikleştirmeden önce, her bir yaprağın fiyatını belirledik: İlgili zincirdeki CPFP ücretleri artı son ~111 vB’lik temizleme tutarı, yaprağın değerine göre hesaplandı. 1 sat/vB oranında bu gerçek cüzdan için sonuç:
Dört yaprak (32.768 + 32.768 + 16.384 + 8.192 sat) bakiyenin %90’ını oluşturuyordu. Diğer 18'i — rutin cüzdan faaliyetlerinden kaynaklanan tozlar, bazıları 1 sat kadar küçük — her birinin çıkışı 2.100–4.600 sat'a mal olacaktı: her şeyi çıkarmak, 100k'yı geri kazanmak için ~77,5k sat'lık ücret harcamak anlamına gelirdi. Araç artık bunu her bir yaprak için hesaplıyor ve varsayılan olarak ekonomik olmayan yaprakları atlıyor. (INCLUDE_UNECONOMICAL=1 ayarı bu ayarı geçersiz kılar; ekonomik hesaplamalar, regtest’e uyarlanmış bu paket üzerinde regresyon testine tabi tutulmuştur).
100.000 sat'lık cüzdandaki her bir sat, 1 sat/vB oranındaki ekonomik çıkış yoluyla takip edilmektedir. Burada iki farklı para kaynağı söz konusudur: cüzdanın bakiyesi ve ekonomik çıkışı finanse etmek için fon adresinden fiilen harcanan 9.388 sat'lık ücret.
Cüzdandaki 100.000 sat:
Spark çıkış ve geri ödeme işlemleri, sıfır ücretle önceden imzalanır (ücretler CPFP sabit noktalarına göre belirlenir); bu nedenle her geri ödeme çıkışı tam yaprak değerini taşır; cüzdan bakiyesinden yapılan tek kesinti, son toplama ücretidir.
Aşağıdakilerden çekilen 9.388 sat'lık ücret fonu:
Sonuç olarak: 100.000 sat'ın 89.668'i (~%90) hedef adrese ulaştı. Çıkışın toplam maliyeti ~18.700 sat'tır — 9.888'i toz olarak terk edilir, 8.388'i CPFP ücretleri, 444'ü süpürme ücretleri — artı ilk etapta CPFP adresine fon sağlayan işlem için zincir içi ücret. Ücret oranları yükseldikçe her terim ölçeklenir ve daha fazla yaprak ekonomik eşiğin altına düşer; 10 sat/vB'de bu cüzdan iki yaprak daha terk eder ve geri kalanı için on kat daha fazla ücret öder.
Yeniden yazılan akış tek bir komuttan oluşur:
make recover SEED_FILE=../.spark-seed.txt BUNDLE=../recovery-bundle.json NETWORK=mainnet FEE_RATE=1
Her turda, canlı zincir durumundan paketleri yeniden oluşturur, CPFP artışını tohumla imzalar, her yaprak zinciri için bir paket gönderir, onaylanmasını bekler ve bu süreci tekrarlar. Yeniden oluşturma sırasında zaten onaylanmış işlemler atlanır, bu nedenle döngü durum bilgisi içermez: hız sınırlamaları, çökmeler ve yeniden başlatmalar hiçbir maliyete yol açmaz — yeniden çalıştırıldığında işlem devam eder. Esplora’daki aksaklıklar, saatler süren bir beklemeyi yarıda kesmek yerine, üstel geri çekilme yöntemiyle yeniden denenir.
İki yapısal ayrıntı önemlidir:
Bu kurtarma işlemini sıralı olarak (varsayılan ayar) yürüttük. FAN_OUT=1 ayarında döngü, öncelikle 4 çıkışlı fazladan bir işlem yayınlardı — 9.388 sat’lık fon, her bir ekonomik yaprak için bir UTXO’ya bölünür; her bir UTXO’nun boyutu, o yaprağın kalan CPFP ücretlerine ek olarak 1.000 sat’lık bir tampon eklenerek belirlenir ve son çıkış kalan tutarı alır. 1 girişli/4 çıkışlı bir P2WPKH işlemi ~203 vB'dir, dolayısıyla 1 sat/vB oranında ~203 sat'tır.
O andan itibaren 4 zincir paralel olarak ilerler — her bir yaprak için bir tane. Her yaprak zinciri kendi TRUC kümesidir; dolayısıyla bir turun dört paketinin tümü bağımsızdır ve aynı blokta onaylanabilir. Bu cüzdanın dört yaprağının her birinde, geri ödeme yapılmadan önce yaklaşık 6 paketlik bir zincir vardı:
Yaklaşık 203 sat için 3,5 katlık bir gerçek zamanlı kazanç elde edilir ve geri ödeme vadesi dolduktan sonra aynı şekil tekrarlanır: Dört geri ödeme paketi, dört ardışık blok yerine, her bir yaprak için ayrı UTXO’lar içeren tek bir blokta yayınlanır. Kazanç, yaprak sayısıyla orantılıdır (zincir derinliklerinin toplamı ile en derin tek zincirin karşılaştırılması); bu nedenle, düzinelerce ekonomik yaprağa sahip bir cüzdan her zaman yayılmalı; birkaç yaprak için ise sıralı yöntem daha basittir ve bu örnekte yeterince hızlıydı.
Döngü tamamlandıktan sonra, her bir ekonomik yaprağın geri ödemesi, CSV zaman kilidinin sona ermesini bekler. Aynı işlemi yeniden çalıştırmak kurtarmak vade bitiminden sonra geri ödemeleri duyurur; onlar onayladıktan sonra, genel tarama yapmak Geri ödeme çıkışlarından herhangi bir hedef adrese tek girişli Taproot anahtar yolu harcamaları oluşturur, imzalayıp bunları sıradan işlemler olarak yayınlar. Bu yazının yazıldığı tarihte, bu cüzdanın dört ekonomik çıkış yolu kendi zincirleri üzerinden gerçekleşmekte ve geri ödemelerin vadesinin dolmasını beklemektedir.
Bu konuda kesin konuşmak gerekiyor, çünkü genellikle pazarlama söylemleri gerçeklerin önüne geçiyor:
Güvene dayalı değildir ve biz de öyle olduğunu iddia etmiyoruz. Bir yelpaze içinde değerlendirildiğinde: Tasarım gereği kendi kanal durumunu tutan bir Lightning daha zayıf, ancak hem anahtarlarınızı hem de verilerinizi elinde tutan ve para çekme işlemi dondurulana kadar bu tutma eylemi normal bir hizmet gibi görünen bir saklama hizmetinden çok daha güvenlidir.
TRUC ihlali ve eksik girdiler normal sıralama sinyalleri olarak değerlendirin ve bir paket grubunu asla “gönder ve unut” olarak ele almayın.Yukarıda bahsedilen her şey, açık kaynaklı araçlar kullanılarak manuel olarak gerçekleştirildi. Bu, bunu kanıtlamak için doğru yer; ancak çoğu kullanıcının bulunduğu ortam değil. Hedeflediğimiz yön, kullanıcının hiçbir zaman hazırlık yapması gerekmeyecek bir çıkış yoludur.
Somut olarak: Blink uygulaması, her durum değişikliğinden sonra — her işlemden sonra — kurtarma paketini otomatik olarak yenileyecek ve kalıcı hale getirecek; bunu yerel cihaz depolama alanına ve kullanıcının ayarladığı durumlarda kendi bulut depolama alanına şifreli olarak kaydedecektir. Bu paket herhangi bir harcama yetkisi taşımaz; anahtarlar değil, çıkış verileridir; dolayısıyla otomatik olarak yedeklenmesi, saldırı yüzeyini genişletmeden çıkış penceresini genişletir. Tohum, tıpkı bugün olduğu gibi, korunması gereken tek gizli bilgi olarak kalır.
Mesele şu ki, “istediğiniz zaman çıkabilirsiniz” ifadesinin herhangi bir hazırlık gerektirmemesi gerekir. Son işlem ne olursa olsun, bu fonları tekrar Bitcoin’e geri aktarmak için gereken veriler zaten kaydedilmiştir. Spark’a erişilemiyorsa, çıkış işlemi Blink uygulamasının içinden ya da aynı paket üzerinde çalışan açık kaynaklı araç aracılığıyla gerçekleştirilir — artık ortada olmayabilecek operatörlerden durum bilgisini almak için telaşlanmaya gerek kalmaz.
Bu, bu vaka çalışmasının ortaya koyduğu eksikliği giderir: Araç seti sistemden çıkarılabilir, ancak yalnızca eksiksiz ve güncel bir paketle karşılaştırıldığında. Yenileme işlemini otomatikleştirerek her zaman güncel ve yedeklenmiş olmasını sağlamak, öncelikle kendiniz oluşturmanız gereken bir acil çıkış yolunu, hazırda bulunan bir acil çıkış yoluna dönüştürür.
Burada kullanılan tümaraçlar açık kaynaklıdır ve her komut ile işlem kimliğinin yer aldığı teknik vaka çalışması, kodun hemen yanında bulunmaktadır:
İhtiyacınız olmadan önce kendi cüzdanınızdaki paket üzerinde deneyin. Asıl mesele de bu.

Şimdi bitcoin almaya ve göndermeye başlayın