Her Şey Doğru Görünüyor — Ama İşlem Başarısız Oluyor. Bölüm II

Her Şey Doğru Görünüyor — Ama İşlem Başarısız Oluyor. Bölüm II

İngilizceden çevrilmiştir

Bu makalenin ilk bölümünde, takas servisi rabbit.io'nun bir müşteriye küçük bir miktar SOL göndermek istediği bir vakayı anlattım; işlem defalarca reddediliyordu — oysa Solana blok zincirinin bilinen tüm kurallarına göre her şey tamamen geçerli görünüyordu.

İlk bölüm ayrıca, teknik olarak doğru olan bir işlemin XRP Ledger, Stellar ve Lightning Network (Bitcoin'in Layer 2'si) gibi ağlarda yine de reddedilebileceği durumları kapsıyordu. Ayrıca, gönderen tarafında görünürde hiçbir sorun olmadığında bile USDC akıllı kontratındaki kara liste uygulamasının neden olabileceği beklenmedik başarısızlıkları da açıkladım.

Birinci Bölümü kaçırdıysanız, buradan okuyabilirsiniz.

Bugün diğer ağlar ve tokenlerle ilgili birkaç benzer örneğe bakmak istiyorum. Her birinde ilk bakışta her şey doğru görünebilir — ama işlem yine de başarısız olur.

5. DeFi'de USDT. İşlem Sessizce Geri Alınıyor

Bu vaka, ağırlıklı olarak DeFi protokollerinin geliştiricilerine ve işletmecilerine özgüdür. Yine de sıradan kullanıcılar da sonuçlardan etkilenebilir.

Aşağıdaki durumu hayal edin. Bir protokole USDC, DAI ve USDT yatırmaya çalışıyorsunuz. USDC ve DAI ile yatırımlar sorunsuz çalışıyor, ancak USDT transferi geri alınıyor. Adres doğru, ağ doğru ve gas yeterli. Neden?

Nedeni şu ki: Ethereum'daki USDT ERC-20 standardına tam uymuyor. Standart, transfer ve transferFrom fonksiyonlarının başarılı olduğunda true, başarısız olduğunda false olmak üzere boolean bir değer döndürmesini gerektirir. USDT ise hiçbir değer döndürmez.

Bir akıllı kontrat ERC-20 standardına sıkı bir şekilde yazıldıysa ve transfer çağrısına yanıt olarak bir boolean bekliyorsa, USDT hiçbir şey döndürdüğünde EVM sanal makinesi (Solidity 0.4.22 ve sonrasında) bunu hata olarak yorumlar ve transferi geri alır. Teknik olarak işlem başarılı olabilirdi, ama zorla geri çevrilir. Gönderen ne ağdan ne de akıllı kontrattan tam olarak neyin yanlış gittiğine dair net bir gösterge almaz.

Bu örnek rabbit.io üzerindeki takaslarla ilgili değildir. Sistemimiz en basit ve en güvenilir şekilde organize edilmiştir: size tokenlerinizi manuel olarak göndereceğiniz bir adres verilir ve karşılığında ihtiyaç duyduğunuz tokenleri bizden alırsınız. DeFi akıllı kontratları bu işleme dahil değildir.

Bununla birlikte, yalnızca rabbit.io üzerinde takas yapan değil aynı zamanda DeFi ile aktif olarak etkileşen okuyucular — geliştiriciler dahil — için basit bir çözüm önerebilirim. OpenZeppelin'in SafeERC20 kütüphanesini kullanın; bu kütüphane standart dışı tokenleri doğru şekilde ele alır.

Profesyonelce yazılmış DeFi protokollerinin çoğu zaten bunu yapıyor. Ancak daha eski veya amatör akıllı kontratlar USDT ile etkileşime girdiğinde hâlâ hata verir. Bu sorun o kadar yaygındır ki, benzer davranışa sahip diğer tokenleri de bulabileceğiniz weird-erc20 veritabanına dahil edilmiştir.

6. Ethereum'daki USDT. Allowance (İzin) Doğrudan Değiştirilemiyor

Ethereum'daki USDT'nin düzenli olarak akıllı kontratlarla başarısızlığa yol açan bir başka tuhaflığı daha var.

ERC-20 standardında, bir akıllı kontrata tokenlerinizi harcama izni vermek isterseniz approve(spender, amount) fonksiyonunu çağırırsınız. Örneğin, allowance'ı 100'den 200 USDC'ye arttırmak istiyorsanız, basitçe approve(spender, 200) çağrısı yaparsınız.

USDT farklı çalışır. Kodunda, alıcı adresin zaten sıfırdan farklı bir allowance'a sahip olması durumunda doğrudan yeni bir sıfırdan farklı değer atanmasına izin verilmediği açıkça belirtilmiştir. Başka neredeyse herhangi bir token için tamamen geçerli olan bir işlem USDT ile kullanıldığında reddedilir.

Bu davranış, allowance'larla ilgili çift harcama saldırısına karşı bir koruma olarak getirilmiştir. Geliştiriciler, bir saldırganın hem eski allowance'ı hem de yeni allowance'ı anında harcayabileceğinden korkmuşlardır.

USDT allowance'ını değiştirmek için zorunlu desen şu şekildedir:

  • Adım 1: allowance'ı sıfırlamak için approve(spender, 0) çağrısı yapın
  • Adım 2: işlemin onaylanmasını bekleyin
  • Adım 3: approve(spender, yeni_değer) çağrısını yapın

Merkeziyetsiz uygulama kullanıcıları için bu kafa karıştırıcı olabilir. Kullanıcı daha önce uygulamaya izin vermiştir, şimdi farklı bir izin belirlemek istiyor, işlemi imzalıyor — fakat hiçbir şey değişmiyor ve bariz bir açıklama yoktur.

Bu örnek de rabbit.io üzerindeki takaslarla ilgili değildir. Platformumuzda böyle reddedilen işlemler oluşamaz çünkü rabbit.io cüzdan bağlanmasını gerektirmez ve cüzdanınızdan token harcama izni istemez.

Ancak eğer bir dApp içinde USDT ile ilgili approve işleminiz başarısız oluyorsa, çözüm genellikle basittir. Mevcut allowance seviyesini kontrol edin. Sıfır değilse, önce bunu sıfıra çekin ve ancak ondan sonra yeni değeri ayarlayın.

7. Bitcoin. Dust Limiti

Bitcoin ağında dust (toz) olarak adlandırılan bir kavram vardır. Bu, daha sonra harcamak için gereken miktardan daha küçük değere sahip bir işlem çıktısını ifade eder. Başka bir deyişle, paralar teknik olarak cüzdanınızda var olabilir, ancak göndermek için gereken ücret, paranın kendisinden daha yüksek olur.

Sıklıkla karıştırılan temel bir ayrımı anlamak önemlidir: konsensüs kuralları ile node politikası arasındaki fark.

Çıktıları dust limitinin altında olan bir işlem Bitcoin konsensüs kurallarına göre teknik olarak geçerli olabilir. Ancak çoğu node varsayılan olarak böyle bir işlemi iletmeyi reddeder ve çoğu madenci de bunu bir bloğa dahil etmeyi reddeder.

Neden basittir: son derece küçük miktarları saklamak veritabanını şişirir ancak gerçek bir ekonomik fayda sağlamaz.

Dust limiti, adres türüne ve minimum relay ücretine bağlıdır. Tarihsel olarak dust limiti 546 satoshi olarak kabul edilir. Minimum ücret oranı 1 sat/vByte ise, daha küçük çıktılar gönderilen miktardan daha fazla ücret gerektirecektir. Ancak bu yalnızca "1" ile başlayan legacy adresler için geçerlidir.

Daha modern adres türleri blok zincirinde daha az yer kaplayan işlemler oluşturduğundan, onların dust limitleri daha düşük olabilir. Örneğin, normal bc1q... adresleri için 1 sat/vByte ücret oranında dust limiti 294 satoshi'dir ve şu an uygulanan minimum relay ücreti (0.1 sat/vByte) ile dust limiti on kat daha küçük olur.

Bitcoin ücretleri, Kaynak: mempool.space

Aşağıdaki durumu hayal edin.

100.000 satoshi (0.001 BTC) sahibi olduğunuzu varsayın. Birine 99.000 satoshi göndermek istiyorsunuz. Bir işlem oluşturuyorsunuz ve ağ ücreti 980 satoshi. Geriye size değiş olarak 20 satoshi kalması gerekiyor.

Ancak bu gerçekleşmeyecektir. Ne değişi alırsınız ne de ana ödeme alıcıya ulaşır. Relay node'ların ağı söz konusu çıktılardan birinin dust limitinin altında olması nedeniyle işlemi sessizce reddedecektir.

Buna bağlı bir diğer sorun da dust'ın ileride harcanmasıdır. Düşük ücretler varken 294 satoshiden küçük birçok çıktı alırsanız ve daha sonra ücretler artarsa, bu paraları harcamaya çalışmak öylesine pahalı hale gelebilir ki, aktarılan miktar gerekli ücreti bile karşılayamaz.

Bu yüzden diğer kripto varlıkları bitcoin ile takas ederken oluşturulan çıktıların dust limitinin üzerinde olduğundan emin olun. Rabbit.io mevcut dust limitinin birkaç katı tutarında takaslara izin verir. Ancak ağ ücretleri artarsa, bu kadar küçük miktarların daha sonra gönderilmesi zorlaşabilir.

8. Ethereum ve EVM Ağları. Bir Eski İşlem Tüm Yenilerini Engelliyor

Ethereum ve herhangi bir EVM uyumlu blok zincirinde (BSC, HyperEVM ve diğerleri gibi), belirli bir adresten gönderilen her işlemin bir sıralı numarası vardır, buna nonce denir.

Ağ işlemleri kesin sırayla işler: önce nonce = 0 olan işlem, sonra nonce = 1, sonra 2 vb. Bir sayıyı atlamak mümkün değildir.

Eğer bir işlem düşük gas ücreti nedeniyle mempool'da takılırsa, aynı adresten gönderilen ve daha yüksek nonce sahip tüm sonraki işlemler de beklemede kalır, normal ücretleri olsa bile.

Çok gerçekçi bir senaryo şöyle olabilir. Birkaç hafta önce düşük gas ücretiyle bir işlem gönderdiniz. Takıldı. Unuttunuz. Şimdi yeni bir işlem göndermeye çalışıyorsunuz. Doğru adresi belirlediniz ve yeterli ücreti koydunuz, fakat işlem işlenmiyor.

Sorun mevcut işlemde değil, eski bekleyen işlemdedir.

Çözüm, eski nonce ile aynı nonce'u kullanarak ancak daha yüksek gas ücretiyle bir işlem göndermektir. Bu ya orijinal işlemi hızlandırır (speed up) ya da onu iptal eder. İptal, aynı nonce ile kendinize transfer gönderip daha yüksek ücret koyarsanız gerçekleşir.

Ancak her cüzdanın kullanıcıların nonce değerini kontrol etmesine izin vermediğini unutmayın. Örneğin Trust Wallet ve Exodus gibi popüler cüzdanlar bu işlevi sağlamaz. Oysa birçok kişi güncelliğini yitirmiş ve kullanışsız bulduğu MetaMask'in aslında bunu sunduğunu bilmiyor.

9. TRON ve USDT TRC-20: Enerji Eksikliğinden Kaynaklanan İşlem Hatası

TRON ağının alışılmadık bir kaynak modeli vardır. Tek bir işlem ücretinin yerine işlemler iki tür kaynağı tüketir:

  • Bandwidth - her tür işlem için
  • Energy - akıllı kontratlarla etkileşimler için, TRC-20 token transferleri dâhil

Enerji TRX dondurarak elde edilebilir. Eğer bu yapılmazsa, ağ maliyeti karşılamak için otomatik olarak TRX yakar.

Ve işte beklenmedik bir fiyatlama sorunu ortaya çıkar:

  • alıcı zaten USDT'ye sahipse yaklaşık 6-13 TRX yakılacaktır
  • alıcı daha önce hiç USDT tutmamışsa 13-27 TRX gerekebilir

Gönderenin ücretler için 15 TRX mevcut olsa ancak transfer yeni bir adrese gidiyorsa, işlem OUT OF ENERGY hatasıyla başarısız olabilir. Bu denemede harcanan TRX geri ödenmez.

Başka bir deyişle, durum bu makaledeki diğer örnelere benzer görünüyor: adres doğru, ağ doğru, gönderen USDT'ye sahip, TRX var — yine de işlem başarısız oluyor.

Sonuç basit: USDT TRC-20 ile stabil çalışmak için olası işlem maliyetlerini karşılamak üzere bakiyede en az 27 TRX bulundurmak tavsiye edilir.

Sonuç Yerine

SOL transferinin başarısız olması hikâyesi bana değerli bir ders verdi. Blok zincirlerini yanlış anladığım için değil; her blok zincirinin kendi ekosistemi olduğu, gizli kurallarının bulunduğu, bunların her zaman açıkça belgelenmediği ve bazen sadece alışılmadık durumlarda kendini gösterdiği anlamında bir derstir.

Her kafa karıştırıcı başarısızlık hayal kırıklığı nedeni değil, yeni bir şey öğrenme fırsatıdır. Ve ne kadar çok yeni şey öğrenirsem, kripto para birimleriyle çalışmaya devam etmek benim için o kadar ilginç hale geliyor.

Aynı şekilde hissediyorsanız, alışılmadık vakaları belgeleyin ve bulgularınızı paylaşın. Kripto endüstrisi, pratik deneyim resmi dokümantasyon güncellenmeden daha hızlı yayıldığında daha güvenilir hale gelir.