Atomic swaps-nin çatışmazlığı və kanalların köməyi ilə nə baş verdiyi barədə, Konstantinopol hard forkunun hansı önəmli hadisələri olduğu və qaz üçün nə ilə ödəməyin mümkün olduğu.
Hər bir təhlükəsizlik mütəxəssisinin başlıca motivasiyası məsuliyyətdən qaçmaq istəyi.
Taleh mənə qarşı çox mərhəmətlisiniz, ICO-dan ayrıldım, birinci geri dönməz əməliyyatı gözləmədən, lakin qısa müddətdə özümü kriptobörsənin inkişafında tapdım.
Mən— Kibalchish uşağı deyiləm, və bir ciddi baxış kifayətdir ki, mən bütün açarları və parolları verim. Buna görə də, memar kimi başlıca məqsədim, kriptoanalarisın yanan iynəsini qiymətli infrastruktur elementlərimdən mümkün qədər uzaqda yerləşdirmək oldu.
Sənin açarların, sənin problemlərin deyil
Biz aktivlərin mübadilə sistemini quraşdırırıq və bu aktivlərin özündə müvəqqəti saxlanmasını istəmirik, lakin əməliyyatın təhlükəsizliyini təmin etməliyik.
Mübahisəli vəziyyətdə hakimin rolu öhdəsinə götürülə bilər və üçdən iki imzaya ehtiyac duyan cüzdanlarla əməliyyatlar aparıla bilər: alıcı, satıcı və escrow.
Lakin, əgər iştirakçı escrows-a uğurla hücum edərsə, istədiyi iki imzanı əldə edəcək.
Atomic swap— bir smart müqavilənin təminatçı olduğu mübadilə sxemidir ki, bu da yalnız dürüst davranışı qəbul edir.
Sanki wolf, goat, and cabbage enigmasında yalnız tək doğrudur ssenari üzrə hərəkət edə bilərsən və ondan geri çəkilsən itkilərlə üzləşirsən.
Yalnız acgöz heyvanlar əvəzinə, əməliyyatı təmin edən hash funksiya var ki, onun içində toqquşma tapmaq elə çətindir ki, başlanğıc əldə etməyə dəyməz.
Birinci addım: enigmanın başlanması
Fərz edək ki, Alisa bir gözəl səhər Bob'a kriptovalyuta qarşı Bitcoin göndərmək istəyir.
- O, bəzi böyük bir sirri qəsd edir
- Ondan hash alır
- Bitcoinləri öz smart müqaviləsinə köçürür, hansı ki, onu yalnız Bob sirri təqdim edərək ala bilər (hashı müqavilədə göstərilən olmalıdır)
- Əgər Bob axşam ona aid Bitcoinlərini götürməyə gəlməsə, Alisa onları geri götürə bilər.
İkinci addım: cazibə
Bob oyuna daxil olur və kriptoavrolarını, belə bir şəkildə yazılmış müqaviləsinə köçürür ki:
- Alisa sirri təqdim etdikdə 'kriptoyeni' geri ala bilər
- Bob, Alisa görünmədiyi halda, bir saatdan daha sonra öz depozitini geri götürə bilər
Üçüncü addım: cazibədə sirrin qətl edilməsi
Alisa pulunu almaq üçün gəlir və Bob-un müqaviləsindən pulları alır, bu zaman öz sirrini açır.
Sonuncu addım: enigmanın açılması
Bob əməliyyatı görür və Alisa tərəfindən təqdim olunan sirri müqavilədən çıxarır. Bu sirri istifadə edir ki, artıq öz Bitcoinlərini götürsün.
Nələrsə səhv gedirsə
Əgər Alisa birdən birdən ölümdən qaçsa, Bob günortadan öz yuanlarını götürəcək.
Bir tərəfdən, Alisa axşama qədər Bitcoin-i geri qaytarır, əgər aldatıcı Bob pula daha yaxşı vaxtlara qədər saxlamağa qərar verərsə.
Əgər siz şəkli mətnə üstün tutursanız, Habrda sizin üçün daha ətraflı və aydın bir izah var. .
Taymautlar arasındakı fərq, son anda Bob-un pullarını alıb aparmaq istəyən pis niyyətli Alisadan bizi qorumaq üçündür, və taymout sona çatır, Bob həyəcanla hex-i əməliyyata daxil edərkən.
İştirakçılar pullarını itirə bilməzlər, maksimum gözləmək lazım olacaq.
Blockchain-də dəstək.Bu, qarşılıqlı blokçeynlərdən sadə bir tələb edən bir sxemdir:
- Hətta bir şaxələnmə ilə smart müqavilələrin dəstəyi.
- Hər iki blokçeyn eyni hash alqoritmlərini dəstəkləməlidir (sirrin uzunluğunu yoxlaymağı unutmamaqdı).
- Taymloklar.
İlk baxışdan, artıq birjalara “sağ olun, görüşüm səhv idi” demək olar, amma vəziyyət belə deyil.
Bütün üstünlüklərinə baxmayaraq, atomic swap-lar likvidliklə heyran etmir. Əsasən buna görə ki, ən populyar cütlük BTC-USD fiat hissəsi tam olaraq tokenləşdirilməmişdi.
USDT-nin uğuru, hər cür zövqə uyğun ERC20 formatında çoxlu stabil kriptovalyutaların yaranmasına səbəb oldu, bunlar arasında ən əmanətli USDC-dən ən alqoritmik DAI-ya qədər.
Bu səbəbdən, sadəlik üçün biz daha sonra Alisanın Bob-a Bitcoin-ləri hansısa ERC20 tokenləri qarşılığında satdığını düşünürük və stabilizatorların uğuru üçün ümid edirik, şükürlər olsun ki, bu zaman daha çox texniki problemlərimiz var.
Sürət
Bitcoin və Ethereum ayrı-ayrılıqda çox sürətli deyil, amma burada əvvəlcə bütün təsdiqlərlə bir depozit gözləməliyik, sonra ikinci depoziti.
Bütün bunlar, əvvəlcə sirdən xəbərdar olan iştirakçının pulları yatırması, və opponentin sonuncu qərarı gözləməsi və yalnız sonra öz hissəsini köçürməsi ilə bağlıdır.
Bundan əlavə, biz çox dəyişkən bir aktivlə məşğul oluruq, beləliklə, bu müddət ərzində kurs əhəmiyyətli dərəcədə dəyişə bilər və şərtləri dəyişdirmək artıq çətindir.
Gizlilik
Hər hansı bir mübadilə iki blokçeyndə izlər buraxır. Diqqətli müşahidəçi smart müqavilələrdə eyni hash-ləri görə bilər və burada bir əməliyyat baş verdiyinə dair məntiqi nəticələr çıxara bilər, bu da kurs dəyişmələrindən vergi məsələlərinə qədər çoxlu nəticələr doğurur.
Sənin işlərinin birja tərəfindən bilinməsi çox pisdir, bunun hər kəs tərəfindən bilinməsi isə iki qat daha pisdir.
İstifadə rahatlığı.
Blockchain-in və spesifik olaraq Ethereum-un gücü. Gəlin, satıcının və alıcının hansı hərəkətləri etməli olduğunu nəzərdən keçirək.
Satıcı üçün hər şey nisbətən asandır: sadəcə Bitcoin-i p2sh adresinə köçürmək lazımdır. Ethereum isə bununla müqayisədə daha mürəkkəbdir.
Müqavilə.Gəlin, swap üçün GitHub-da ortalama bir müqaviləyə nəzər yetirək:
contract iERC20 {
function totalSupply() public view returns (uint256);
function transfer(address receiver, uint numTokens) public returns (bool);
function balanceOf(address tokenOwner) public view returns (uint);
function approve(address delegate, uint numTokens) public returns (bool);
function allowance(address owner, address delegate) public view returns (uint);
function transferFrom(address owner, address buyer, uint numTokens) public returns (bool);
}
contract Swapper {
struct Swap {
iERC20 token;
bytes32 hash;
uint amount;
uint refundTime;
bytes32 secret;
}
mapping (address => mapping(address => Swap)) swaps;
function create(iERC20 token, bytes32 hash, address receiver, uint amount, uint refundTime) public {
require(swaps[msg.sender][receiver].amount == 0); // check is swap with given hash already exists
require(token.transferFrom(msg.sender, address(this), amount)); // transfer locked tokens to swap contract
swaps[msg.sender][receiver] = Swap(token, hash, amount, refundTime, 0x00); //create swap
}
function hashOf(bytes32 secret) public pure returns(bytes32) {
return sha256(abi.encodePacked(secret));
}
function withdraw(address owner, bytes32 secret) public {
Swap memory swap = swaps[owner][msg.sender];
require(swap.secret == bytes32(0));
require(swap.hash == sha256(abi.encodePacked(secret))); // swap exists
swaps[owner][msg.sender].secret = secret;
swap.token.transfer(msg.sender, swap.amount);
}
function refund(address receiver) public {
Swap memory swap = swaps[msg.sender][receiver];
require(now > swap.refundTime);
delete swaps[msg.sender][receiver];
swap.token.transfer(msg.sender, swap.amount);
}
}
Dikkat! Bu və digər müqavilələri istehsalda istifadə etməyin, onlar yalnız nümayiş üçün yazılmışdır. Xüsusilə bu.
- Bob token müqaviləsinin metodunu çağırmalıdır
approve, swap müqaviləsinə öz tokenlərinə giriş imkanı verərək - Bob swap yaradır və müqaviləni
transferFromgöndərənin tokenlərini öz ünvanına alır - Alice
withdrawsirin üstünü açır və müqavilə çağırılırtransfer
Ən çox cüzdanlar və kripto birjalar approve tokenləri dəstəkləmir və buna görə də.
İstifadəçilər tez-tez səhv edərək tokenləri müqaviləyə yalnız göndərirlər, bunun nəticəsində tokenlər sadəcə itirilir. Etherscan-dakı şərhlər bədbəxtlərin şikayətləri ilə doludur.
Və müqaviləni çağırmaq üçün ETH ödənişi tələb olunur, yəni hər iki iştirakçı başlanğıcda onunla təmin olunmalıdır, bu isə çox az adamın xeyrinədir.
Qazqaz
İlk növbədə, göndəricinin yoxlanmasını olan yerlərdə ləğv etmək və qazda artıq olan kimsənin müqavilələri istəyənlər üçün çağırdığını qəbul etmək yaxşıdır.
Təkmilləşdirilmiş müqavilə
contract Swapper {
struct Swap {
iERC20 token;
address receiver;
uint amount;
address refundAddress;
uint refundTime;
}
mapping (bytes32 => Swap) swaps;
function create(iERC20 token, bytes32 hash, address receiver, uint amount, address refundAddress, uint refundTime) public {
require(swaps[hash].amount == 0); // use hash once
require(token.transferFrom(msg.sender, address(this), amount));
swaps[hash] = Swap(token, receiver, amount, refundAddress, refundTime);
}
function withdraw(bytes memory secret) public {
bytes32 hash = sha256(secret);
Swap memory swap = swaps[hash];
require(swap.amount > 0);
delete swaps[hash];
swap.token.transfer(swap.receiver, swap.amount);
}
function refund(bytes32 hash) public {
Swap memory swap = swaps[hash];
require(now > swap.refundTime);
delete swaps[hash];
swap.token.transfer(swap.refundAddress, swap.amount);
}
}
Kontrakt-klavye dualizmi və EIP 712
Bildiyimiz kimi, yayımdakı adres bir müqavilə ola bilər, ya da bir subyekt ola bilər, yəni açar.
Açarın əsas fəaliyyəti - hər hansı bir mesajı imzalamaqdır.
Göndərici olaraq Bob-müqaviləsini istifadə edə bilərik, o, bütün lazım olan keçidləri həyata keçirir, öncə Bob-açanın imzasını yoxlayaraq.
İndi hər kəs iştirakçının komissiyasını maliyyələşdirə bilər, lakin qərarı yalnız açarı bilən şəxs verir.
Bob-müqaviləsi
library EIP712ProxyLibrary {
function hashCommand(address sender, iERC20 token, Swapper swapper, bytes32 hash, address receiver, uint amount, address refundAddress, uint refundTime) public view returns(bytes32);
}
contract ProxyBob {
address owner;
constructor(address _owner) public {
owner = _owner;
}
function createSwap(Swapper swapper, iERC20 token, bytes32 hash, address receiver, uint amount, address refundAddress, uint refundTime, uint8 v, bytes32 r, bytes32 s) public {
require(owner == ecrecover(EIP712ProxyLibrary.hashCommand(address(this), token, swapper, hash, receiver, amount, refundAddress, refundTime), v, r, s));
token.approve(address(swapper), amount);
swapper.create(token, hash, receiver, amount, refundAddress, refundTime);
}
}
Ethereum-da mürəkkəb məlumat strukturlarının imzaları üçün standart , onun haqqında daha ətraflı məlumatı
Böl və hakim ol
Tez-tez Ethereum müqaviləsinin pozulma senarisi belə görünür:
- İştirakçı müqaviləyə vəsait yatırır
- Sonra vəsaiti götürür
- Nəsə yanlış gedir
- Hücumçu pulları dəfələrlə götürür
Əgər ilk misalımıza qayıtsaq, nəsə yanlış gedir, əgər tapmaca boş baytlar dəstisidirsə.
Bir milyonu necə oğurlamaq olarHəşrlə svap yaradırıq 0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925
Bu, 0x0000000000000000000000000000000000000000000000000000000000000000
Sirrimizi ötürürük və tokenlərimizi götürürük
Bir daha ötürür və başqalarınınkını götürürük, bunun səbəbi 0 = 0
Hər əməliyyat üçün ayrı müqavilə yaradaaraq, EVM səviyyəsində müqavilələri izolyasiya edə bilərik.
Amma bu hələ də kifayət etmir: indi hər əməliyyatın öz adresi var ki, buraya istənilən cüzdan və ya birjadan tokenlər köçürülə bilər.
Tərk edilmiş müqavilələr və create2
Amma indi hər əməliyyat üçün müqavilə yaratmalı və alıcının oraya əmək “kriptofening”ini köçürməsini gözləməliyik. "Səhər müqavilə, axşam pul" sxemində hər zaman alıcının itməsi təhlükəsi var, halbuki müqaviləni yaratmaq üçün etiraf edilən etiraf edilmişdir.
Səhər pullar, axşam baytlar etmək mümkün deyilmi?
Constantinople hard fork-da inkişaf etdiricilər yeni müqaviləni müəyyən adresdə yaradan create2 əmri əlavə etdilər
keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]
Burada
- address — fabrik müqaviləsinin adresi
- salt — bir ədəd, bu, növbəti seriyadakı mənası öyrənəcəyimiz bir ədəd
- init_code — müqavilənin bayt kodu və konstruktorun parametrləri.
FabrikaƏmr yalnız assembly vasitəsilə işləyir, buna görə də fabrika bir az qorxu doğurur:
contract Factory {
event Deployed(address addr, uint256 salt);
function create2(bytes memory code, uint256 salt) public {
address addr;
assembly {
addr := create2(0, add(code, 0x20), mload(code), salt)
}
emit Deployed(addr, salt);
}
}
Sizin müqavilənizin kodunu web3 ilə əldə edə bilərsiniz:
const MyContract = new web3.eth.Contract(ABI, {})
const сode = MyContract.deploy({
data: BYTECODE,
arguments: contructorArgs
}).encodeABI();
const factory = new web3.eth.Contract(FACTORY_ABI, factoryAddress);
tx = factory.methods.create2(сode, salt);
Solidity-də məhdud dəstəyə görə, müqavilə üçün qaz bəzən eterin bəzi incəlikləri səbəbindən düzgün hesablanmaya bilər.
Xüsusilə də, qazın kəsildiyi halda müqavilənin daxili xətasıyla çökdüyü, qazın yetərli olmadığını da gözlədiyiniz kimi bildirmədiyi gözəldir.
İndi biz tokenləri müqavilələrə, onları öncədən yaratmadan köçürə bilərik və şəbəkədə onları tanıtmazdan əvvəl heç kim müqavilənin nə etdiyini anlamayacaq.
Külək küləyə gözünü çıxarmır
Aydındır ki, həqiqi bir analitik, xüsusilə də sistem düşmənlərinə pul mənimsəmək üçün mükafatlar aldığı zaman, bu cür uşaq fəndləri ilə dayandırılmayacaqdır və müqavilə yaradıldıqdan sonra o, yenə də hash-i görəcəkdir.
Hash-ı necə gizlətmək olar?
Swap-ı off-chain-ə köçürürük: iştirakçılar swap-müqaviləsinə köçürmək üçün imzaları bir-birinə verir, sonra isə gizli məlumat açılır.
Addım-addımİki 'multisig' yaradılır ki, burada Aliciyanın və Bobun imzaları ilə vəsaitlər əldə oluna bilər.
Hansısa iştirakçının offline-a getməsinin faciəyə çevrilməməsi üçün köhnə yaxşı vaxt aşımını əlavə edəcəyik.
Aliciya və Bob eyni zamanda depozit investisiya edir
- Aliciya bir sirr düşünür və Bob-a sirrin hash-ını və bitkoinlərin swap ünvanına köçürmək üçün əməliyyatın imzasını verir.
- Bob, Aliciyaya swap müqaviləsinə tokenlərin köçürülməsi üçün nəzərdə tutulmuş hash ilə imza təqdim edir.
- Aliciya Bob-a sirri bildirir.
Bu anda harmoniya yaranır: həm Aliciya, həm də Bob istənilən an ticarəti bitirə bilərlər. Belə dostcasına bir mühitdə onlar pulları son ünvanlara köçürmək üçün imzaları bir-birinə verə bilərlər.
Xarici bir müşahidəçi üçün bu, pulların 2-dən 2-ə multisig müqaviləsinə keçdiyi kimi görünür.
Bundan əlavə, bu sxem hər iki tərəfə eyni anda depozit etməyə imkan tanıyır, çünki sirr bütün təsdiqləndikdən sonra düşünülür.
Səviyyə 2
Bir ünvan üzərinə pul çıxara bildiyimiz və ara əməliyyatı yayımlamadan köçürdüyümüz üçün, bir neçə ünvana pul köçürməyə və sonsuz sayda ara əməliyyatı icra etməyə heç nə mane olmur. Bu mübadilə üçün mütləq bir tələbat olmasa da, əgər swap-yaratmağa başlamışsınızsa, dayanmaq çətindir.
İndi Aliciya və Bob tam anlamı ilə irəliləyə bilərlər. Məsələn, saniyədə satoshi dəyişərək ortalama qiyməti avtomatik hesablamaq ya da sadəcə olaraq market maker ilə likvidlik alıcısını birbaşa bağlamaq.
Addım-addım
- Satan sirr düşünür və alıcıya sirrin hash-ını və bir hissəsi p2sh swap ünvanına köçürülən əməliyyat imzasını verir, qalan hissə isə satıcının ünvanına qaytarılır.
- Alıcı, tokenleri ve geri ödemeyi alıcı adresine çıkarmaya izin veren imzayı iletir.
- Satıcı sırrı açar.
- Tarih, yeni bir sırla tekerrür ediyor, aynı zamanda swap ve geri ödemeye, daha önce satın alınıp satıcı adresine ödenmiş olanın alıcı adresine çıkarılması ekleniyor.
Artık yüksek hızlı p2p ticareti erişimimize açık, önemli olan süreyi takip etmek ve işlemi zaman dolmadan kapatmaktır.
Ancak, sözleşmelerimizi biraz düzeltirsek, kanallarımıza ölümsüzlük hediye edebiliriz ki bu, ağ oluşturmamızı büyük ölçüde kolaylaştıracaktır.
Ama bunu bir sonraki bölümde anlatacağız.
Mənbə: habr.com
