Solidus Bridge testnet ağında çalışıyor. Burada görünen her şey test verisidir, parasal değeri yoktur.

Kimlik belgesi ayna sözleşmesi neler yapabilir ve neler yapamaz, zincir üzerinde gösterilmiş

Bu sayfa, kimlik belgesi aynasının neyi değiştirebileceğini, onu kimin çağırabileceğini ve hangi işlemler için işlevi olmadığını zincir üzerinde denetler.

Ne yapar

Ayna, bir hedef zincirde Solidus kimlik belgesi durumunu tutan sözleşmedir. Aktarım başına bir kayıt, veren başına bir bayrak ve son kalp atışını saklar. Bunlardan herhangi birini yalnızca bir mesaj, yeterli sayıda bilinen doğrulayıcıdan geçerli imzalar taşıdığında değiştirir; Sepolia, Fuji ve Arc'ta dört doğrulayıcıdan üçü.

Neyi sunduğu için ayna sözleşmesini okuyun sayfasına bakın. Bir mesajın ona nasıl ulaştığı için kimlik belgesi durumu köprüsü nedir sayfasına bakın. Her imza tek bir hedefe bağlıdır; hedef, imzalanan şeyin içindedir sayfası bunu gösterir. Bu sayfa öbür tarafı kapsar: sözleşmenin yapamadıkları. Her sınırın yanında onu doğuran Solidity ve tekrarlayabileceğiniz bir okuma var.

Yazma yüzeyi

Ayna on iki dış işleve sahiptir. On biri view işlevidir. Biri, submit, durum yazar. Hiçbiri payable değildir. Entegrasyon yapanları bir aynaya yönlendiren kayıt defterinin yazan üç işlevi vardır ve üçü de yalnızca sahibe aittir.

sözleşme işlev seçici kim çağırabilir ne yazar
ayna submit(bytes,bytes) 0x39b973ad herkes bir sonraki sıra numarası, sonra mesajın taşıdığı şey: işaretçisi ve veren bayrağıyla bir aktarım, tek başına bir veren bayrağı ya da bir kalp atışı
kayıt defteri setMirror(uint32,address) 0x753ab46d sahip bir alanı hangi aynanın karşıladığı
kayıt defteri transferOwnership(address) 0xf2fde38b sahip sahip
kayıt defteri renounceOwnership() 0x715018a6 sahip sahip, sıfıra ayarlanır

submit için izin listesi yoktur. Bir çağrının uygulanıp uygulanmayacağına imzalar karar verir ve herhangi bir denetimde başarısız olan bir çağrı bütünüyle geri alınır; bu yüzden reddedilen bir mesaj hiçbir şey yazmaz. On bir görünümün zincir dışında çağrılması hiçbir şeye mal olmaz. Kayıt defterinin setMirror işlevi, entegrasyon yapanların nereye baktığını değiştiren tek işlevdir ve önünde bir zaman kilidi gecikmesi durur.

Yedi iddia, her biri kanıtıyla

Solidity ile dağıtılmış sözleşme tek bir programdır ve Solidity kaynağı bridge-contracts deposunda herkese açıktır. solc 0.8.28 ile derlendiğinde (optimizer açık, 200 çalıştırma, Cancun), aynanın kaynağı Sepolia'daki kodla aynı boyutta kod verir: 5,040 bayt. İkisi, kurucu değerlerini tutan dokuz 32 baytlık yuva ve 32 baytlık derleyici üst verisi hash'i dışında özdeştir. Erişim denetimi kütüphanesinin 5.6.1 sürümüne karşı derlenen kayıt defteri 742 bayttır ve yalnızca üst veri hash'inde farklıdır.

Dağıtılmış her okuma 2026-10-08 tarihinde 17:07 ile 17:18 UTC arasında, iddia 2'deki Fuji karşılaştırması dışında, Ethereum Sepolia üzerinde 0x0a5a…517A aynasına karşı çalıştırıldı. Taramalar son bölümde. Her okumanın yanında bir kontrol durur: farklı cevap vermesi gereken bir sözleşme üzerinde aynı okuma.

# iddia Solidity dağıtılmış
1 Sahip yok, yönetici işlevi yok Ayna ya da iki kütüphanesinde Ownable, onlyOwner, msg.sender ya da tx.origin yok. Kontrol: kayıt defterinde Ownable ve onlyOwner var. Tarama 2: owner(), transferOwnership(address), setThreshold(uint8) ve pause() kodun seçicileri arasında değildir, submit ise vardır. Tarama 7: cast call $M 'owner()(address)' geri alınır. Aynı çağrı kayıt defterinde 0x23A8…d294 zaman kilidini döndürür.
2 Zincir kimliği, yerel alan, eşik ve doğrulayıcı listesi kurulumda sabitlenir solidusChainId, solidusDomain, localDomain ve threshold değerleri immutable olarak tanımlıdır. _validators.push(v) ve _isValidator[v] = true kurucudadır ve başka hiçbir yerde değildir. Tarama 4: kod 3 değerini sabit olarak 2 yerde, 11155111 değerini 3 yerde ve 50002 değerini 4 yerde tutar. Tarama 8: Fuji'de aynı adres aynı 5,040 baytı tutar ve 9 bayt farklıdır, hepsi üç yerel alan sabitinin içinde. threshold() 3 okur ve validators() dört adres listeler.
3 Bir proxy değildir, yükseltme yolu yoktur ve kendini silemez Ayna ya da kütüphanelerinde delegatecall, selfdestruct, create2 ya da new yok ve başlatıcı yok. Tarama 5: EIP-1967 uygulama yuvasında ve yönetici yuvasında cast storage ikisinde de sıfır okur. Kontrol: Sepolia'daki üçüncü taraf bir proxy olan 0xE737…E275 ikisinde de sıfırdan farklı okur. Tarama 3 hiçbir DELEGATECALL, CREATE, CREATE2 ya da SELFDESTRUCT bulmaz ve tarama 2 hiçbir upgradeTo(address) bulmaz.
4 Hiçbir token ve hiçbir ether taşımaz Token arayüzü yok ve .call, .send ya da .transfer yok. Tek assembly, bir calldataload kaydırmasıdır. Tarama 3 hiçbir CALL ya da CALLCODE bulmaz. Tek STATICCALL durumu değiştiremez ve kaynaktaki tek harici okuma ecrecover işlevidir. Kontrol: ether ödeyen örnek kasada 1 CALL var.
5 Hiçbir çağrı ona ether veremez payable işlev, receive ve fallback yok. Kod, CALLVALUE sıfır değilse geri alarak açılır. Tarama 6: 1 wei taşıyan simüle edilmiş bir çağrı geri alınır, boş calldata ile yapılan çağrı da. Kontrol: Sepolia WETH üzerinde aynı değer çağrısı 0x döndürür. cast balance $M 0 okur.
6 submit durum yazan tek işlevdir Bir nonpayable işlev ve on bir view işlevi. Üç _apply… yazıcısı private tanımlıdır ve submit onların tek çağıranıdır. Tarama 1: kod 12 seçiciye cevap verir, kaynağın ABI'siyle aynı 12. Bilinmeyen 0x12345678 seçicisiyle yapılan çağrı geri alınır. Yukarıdaki bayt karşılaştırması kodu kaynağa bağlar.
7 Hiçbir adres ayrıcalıklı değildir submit çağıranı asla okumaz. threshold kadar ayrı doğrulayıcının, artan adres sırasıyla imzalamış olmasını ister. Tarama 3 hiçbir CALLER ya da ORIGIN bulmaz. Kontrol: kasada 4 CALLER var. Bir yabancının simüle edilmiş submit(0x,0x) çağrısı BadLength(18, 0) ile geri alınır, seçici 0x2e728bb2. Bu bir mesaj biçimi hatasıdır, yetkilendirme hatası değil.

İddia 5 çağrıları kapsar. EVM, kendini yok eden bir sözleşmenin herhangi bir adrese ether göndermesine izin verir ve hedefteki hiçbir kod bunu reddedemez.

İddia 2 için bir not gerekir. Dört değer Solidity'nin immutable anahtar sözcüğünü kullanır: Solidus zincir kimliği, Solidus alanı, yerel alan ve eşik. Derleyici onları depolamaya değil koda yerleştirir. Doğrulayıcı listesi bir depolama dizisi ve bir eşlemedir, bu yüzden kanıtı farklıdır. Kaynak onu yalnızca kurucuda yazar ve zaten yazan tek işlev submit işlevidir. İddia 6 bu kanıtı taşır.

Bir ayna nasıl değiştirilir

Bir ayna hiçbir zaman yerinde değiştirilmez. Yerine geçen, kendi sabit değerleri olan yeni bir aynadır. Kayıt defterinin sahibi sonra setMirror(domain, newMirror) çağırır. mirrorOf(domain) değerini çağrı anında okuyan bir entegrasyon yapan değişikliği izler. Adresi saklayan, eski aynada kalır.

Sahip bir zaman kilididir, 0x23A8…d294. Sepolia'da asgari gecikmesi 172800 saniye, yani 48 saat okunur; veriyi görmeden bir koşulu denetleyin sayfasındaki rakam. Bir yabancının simüle edilmiş setMirror çağrısı OwnableUnauthorizedAccount (0x118cdaa7) ve yabancının adresiyle geri alınır. Aynı simülasyon zaman kilidinden 0x döndürür. transferOwnership ve renounceOwnership yabancıya aynı geri almayı verir. Sahip ayrıca bir alanı sıfır adresine ayarlayabilir ve zaman kilidinin simülasyonu bunu da kabul eder.

Gecikme bir alanı yeniden yönlendirmeye uygulanır. submit için geçerli değildir: beklenecek bir sahibi yoktur; herkes imzalı bir mesajı her an iletir.

Sahibin aynaya ulaşmanın bir yolu yok. Kayıt defterinin kodunda hiçbir CALL, STATICCALL ya da DELEGATECALL yoktur, bu yüzden hiçbir sözleşmeyi çağıramaz. Aynanın çağıracağı sahibe özel bir işlev yoktur.

Tek komutla görün

Bu okumalar herkese açık bir Sepolia RPC kullanır, çünkü Solidus vekili eth_getCode, eth_getStorageAt ya da eth_getBalance sunmaz. --override-balance yalnızca simüle edilen göndericinin 1 ether tutmasını sağlar. Hiçbir şey gönderilmez. 2026-10-08 tarihinde çalıştırıldı.

Her tarama, altındaki satırla karşılaştırabileceğiniz bir sayı ya da değer basar. Bir sıfır, yalnızca yanındaki kontrol aynı taramada sıfırdan farklı bir sonuç döndürdüğü için kanıt sayılır.

RPC=https://ethereum-sepolia-rpc.publicnode.com
M=0x0a5a0d19206f436d67B7b87BF4c889d5b769517A   # mirror
R=0x19aF92b387200827E0540f516FEd1468B09806A5   # registry
V=0x923f75C32F3e1556Ee516d44E89088454D9E27a8   # example vault, a control
P=0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275   # third-party proxy, a control
F=0x0000000000000000000000000000000000000001
trim() { local c; c=$(cast code "${1}" --rpc-url $RPC); echo "${c:0:$((${#c}-106))}"; }   # cut the 53-byte compiler metadata trailer
OPS='^(CALL|CALLCODE|DELEGATECALL|CREATE|CREATE2|SELFDESTRUCT|CALLER|ORIGIN)$'

# scan 1: the selectors the code answers
SELS=$(cast disassemble $(trim $M) | awk '$(2)=="PUSH4"{p=$(3);next} $(2)=="EQ"&&p{print p} {p=""}')
echo "$SELS" | wc -l
# 12

# scan 2: candidate functions, with submit as the control
for s in 'submit(bytes,bytes)' 'owner()' 'transferOwnership(address)' 'upgradeTo(address)' \
         'setThreshold(uint8)' 'pause()' 'withdraw(uint256)'; do
  echo "$s $(echo "$SELS" | grep -c $(cast sig "$s"))"; done
# submit(bytes,bytes) 1
# owner() 0
# transferOwnership(address) 0
# upgradeTo(address) 0
# setThreshold(uint8) 0
# pause() 0
# withdraw(uint256) 0

# scan 3: opcodes that call out, create, delete, or read the caller
cast disassemble $(trim $M) | awk '{print $(2)}' | grep -cE "$OPS"
# 0
cast disassemble $(trim $V) | awk '{print $(2)}' | grep -E "$OPS" | sort | uniq -c
#    1 CALL
#    4 CALLER
cast disassemble $(trim $R) | awk '{print $(2)}' | grep -cE '^(CALL|CALLCODE|DELEGATECALL|STATICCALL)$'
# 0   (the registry cannot call any contract)

# scan 4: the constructor values sit in the code as constants
cast disassemble $(trim $M) | grep -E 'PUSH32 0x0+(3|c352|aa36a7)$' | awk '{print $NF}' | sed -E 's/^0x0+/0x/' | sort | uniq -c
#    2 0x3
#    3 0xaa36a7
#    4 0xc352

# scan 5: no proxy slots (the control is a proxy)
for slot in 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
            0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; do
  echo "mirror  $(cast storage $M $slot --rpc-url $RPC)"
  echo "control $(cast storage $P $slot --rpc-url $RPC)"; done
# mirror  0x0000000000000000000000000000000000000000000000000000000000000000
# control 0x0000000000000000000000000bf2a7bc86e37684d45281e6a101dd639e918223
# mirror  0x0000000000000000000000000000000000000000000000000000000000000000
# control 0x0000000000000000000000005abd1d39301fd4484b829cd1f0d4f17a6af9569f

# scan 6: no ether in, and a value call reverts (the control is Sepolia WETH)
cast balance $M --rpc-url $RPC
# 0
cast call $M --value 1 --from $F --override-balance $F:1000000000000000000 --rpc-url $RPC
# Error: server returned an error response: error code 3: execution reverted
cast call 0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 --value 1 --from $F --override-balance $F:1000000000000000000 --rpc-url $RPC
# 0x

# scan 7: the mirror has no owner(), the registry does
cast call $M 'owner()(address)' --rpc-url $RPC
# Error: server returned an error response: error code 3: execution reverted
cast call $R 'owner()(address)' --rpc-url $RPC
# 0x23A8E34E422A9c2E88c1F205070758b84191d294

# scan 8: the same address on Fuji holds the same code, except the local domain
diff <(cast code $M --rpc-url $RPC | fold -w2) \
     <(cast code $M --rpc-url https://api.avax-test.network/ext/bc/C/rpc | fold -w2) | grep -c '^<'
# 9

Adresler canlı /v1/routes yanıtından gelir; onu Bridge API başvurusu açıklar. Entegrasyon adımları geliştiriciler sayfasında, zincir sağlığı durum sayfasında, güven modeli güvenlik sayfasında ve kısa cevaplar SSS sayfasında.

Okumaya devam edin