Miks on aatomilised swapid halvad ja kuidas võivad kanalid aidata, mis olulist juhtus Constantinople'i hard fork'is ja kuidas olla, kui ei ole millegagi gaasi maksta.
Iga turbeeksperdi peamine motivatsioon on soov vältida vastutust.
Saatuse halastus oli kohal, lahkusin ICOst, ootamata esimest pöördumatut tehingut, kuid peagi leidsin end krüptobörsi arendamise juures.
Mina ei ole kindlasti Malkoša Kibalčiš ja üks rangem pilk on piisav, et ma annaksin kõik võtmed ja paroolid üle. Seetõttu oli minu peamine eesmärk arhitektina asetada tuline krüptoanalüüsi nõel nii kaugele kui võimalik minule kallite infrastruktuuri elementide juurest.
Kuna need ei ole sinu võtmed, ei ole need ka sinu probleemid.
Me ehitame varade vahetussüsteemi ja soovime vältida nende varade hoidmist enda käes, kuid peame tagama tehingu turvalisuse.
Saame tegutseda vahemeesena vaidlusalustes olukordades ja teha tehinguid rahakottidega, mis nõuavad kolme allkirja: ostjalt, müüjalt ja hooldajalt.
Kuid kui osaleja suudab hooldajat edukalt rünnata, siis saab ta soovitud kaks allkirja.
Aatomaarne vahetus — vahetuskeem, kus garantii rollis on nutileping, mis lubab ainult ausat käitumist.
Nagu mõistatuses hundist, lambast ja kapsast võid sina toimida ainult ühes õiges stsenaariumis ja kannatada kaotusi, kui sellest kõrvale kaldud.
Austatav looma asemel tagab korra räsifunktsioon, milles kollisiooni leidmine on nii keeruline, et ei tasu isegi proovida.
Esimene samm: mõistatus
Kujutame ette, et Alice tahab ühel kaunil hommikul saata Bobile bitcoini vastu tõukeratta 'krüptovääringut'.
- Ta mõtleb välja mingi suure saladuse
- Saab temalt räsihash'i
- Kandab bitcoine nutilepingusse, kust saab raha võtta Bob, esitades saladuse (hash peab olema lepingus märgitud hash'iga võrreldav)
- Kui Bob ei tule oma bitcoine õhtuks kätte saama, võib Alice need tagasi endale võtta.
Teine samm: lõks
Mängu astub Bob ja kannab 'krüptoeurod' oma lepingusse, mis on kirjutatud selliselt, et:
- Alice võib 'krüptoraha' kätte saada, esitades salajase numbri
- Enne lõunat võib Bob, kui Alice ei ilmu, peadagust tagasi saada.
Kolmas samm: näpunäide mõistatusele
Alicia tuleb oma raha järele ja võtab Bobi lepingust raha, paljastades samal ajal oma saladuse.
Viimane samm: mõistus on lahendatud
Bobi näeb tehingut ja kotkasilmaga eraldab ta sellest saladuse, mille Alicia lepingule esitas. Seda saladust ta kasutab, et juba ise oma bitcoine kätte saada.
Kui midagi läheb valesti
Kui Alicia peaks äkitselt surelikuks osutuma, võtab Bob lõunaks oma jüaanid tagasi.
Oma osas tagastab Alicia õhtuks bitcoini, kui reeturlik Bob otsustab raha paremate aegade ootamiseks pidada.
Kui eelistad pilti tekstile, on Habras sinu jaoks põhjalikum ja visuaalne .
Erinevus aegade vahel on loodud meid kaitsma pahatahtliku Aliciast, kes võtab Bobi raha viimasel hetkel, kui aeg on otsa saamas, samal ajal kui ta värisevate sõrmedega sisestab hex'i tehingusse.
Osalejad ei saa raha kaotada, maksimum, peab natuke ootama tagastamist.
Toetamine plokiahelatesSee on lihtne, nagu king, skeem, mis nõuab suheldes plokiahelatelt vaid vähe.
- Nutitehingute to support with vähemalt ühe haru
- Mõlemad plokiahelad peavad toetama sama krüptimisalgoritmi (ärge unustage kontrollida salajase pikkust)
- Aeglukud.
Esmapilgul võib juba öelda, et börsile 'head aega, meie kohtumine oli viga', kuid see ei ole nii lihtne.
Kõikide oma eeliste juures ei ole lahendused atomic swap'idel likviidsusega üle mõistuse. Suur osa on selles, et populaarseimas paaris BTC-USD ei olnud fiat-osa täielikult tokeniseeritud.
USDT edu on tekitanud terve hulga stabiilseid münte ERC20 formaadis, mis katab kõiki maitseid, alates kõige hoidlikumast USDC-st kuni kõige algoritmilise DAI-ni.
Seetõttu räägime edaspidi lihtsuse huvides sellest, et Alice müüb Bobile Bitcoine mingite ERC20 tokenite eest ja loodame stabilisaatorite õnnele, sest meil on veel palju rohkem tehnilisi probleeme.
Kiirus
Bitcoine ja Ethereum ei ole üksinda ka eriti kiired, ja nüüd peame ootama kõigepealt ühe sissemakse kõikide kinnitustega, siis teist.
See kõik on sellepärast, et kõigepealt teeb sissemakse osaleja, kellel on saladus teada, ja vastane ootab lõpuleviimist ning alles seejärel kannab oma osa.
Samuti tegeleme väga volatiilse varaga, seega võib selle aja jooksul hind oluliselt muutuda, ning tingimuste muutmine pole enam lihtne.
Privaatsus
Iga vahetus jätab jälgi mõlemale plokiahelale. Tähelepanelik vaatleja võib märgata samu hashe nii nutilepingutes ja teha loogilise järelduse, et siin on toimunud tehing, mille põhjal saab teha rohkelt järeldusi alates vahetuskurssidest kuni maksudeni.
Kui börs teab sinu tegemistest — on see äärmiselt ebameeldiv; kui sellest teab igaüks — on see kahekordselt ebameeldiv.
Usability
Plokiahela ja eriti Etheri tugevus. Vaadakem, milliseid samme peab müüja ja ostja astuma.
Müügipoolelt on kõik suhteliselt lihtne: tuleb lihtsalt edastada Bitcoin p2sh aadressile. Etheriga on olukord palju keerulisem.
LepingVaatame keskmist GitHubi lepingut vahetamiseks:
pragma solidity ^0.5.0;
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 if 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);
}
}
Tähelepanu! Ärge kasutage seda ja teisi artikli lepinguid tootmises, need on kirjutatud ainult demo eesmärkidel. Eriti seda..
- Bob peab kutsuma lepingus tokeni meetodit.
reject, andes vahetuse lepingule ligipääsu oma tokenitele. - Bob loob vahetuse ja lepingu meetodi abil.
transferFrom.võtab saatja tokenid enda aadressile. - Alice on.
withdraw.avalikustab salajase ja leping kutsub.transfer
Enamik rahakotte ja krüptobörse ei toeta. reject tokenite jaoks, ja mitte ilma põhjuseta.
Kasutajad eksivad sageli ja lihtsalt kannavad tokenid lepingule, mille järel tokenid lihtsalt kaovad. Etherscani kommentaarid on täis õnnetute nutu.
Ja et kutsuda lepingut, on vaja maksta ETH tasu, seega peavad mõlemad osalejad enne tehingu alustamist selleks ette valmistama, millega ei taha paljud tegeleda.
Gaasihoidla.
Alguses tasub eemaldada saatja kontroll igal võimalikul juhul ja eeldada, et meil on keegi, kes kannatab gaasi ülekoormuse all ja kutsub lepinguid kõigile huvilistele.
Moderniseeritud leping.
kontrakt Swapper {
struktuur Swap {
iERC20 token;
aadress vastuvõtja;
uint summa;
aadress tagasimakseAadress;
uint tagasimakseAeg;
}
mäpiga (bytes32 => Swap) swapid;
funktsioon create(iERC20 token, bytes32 hash, aadress vastuvõtja, uint summa, aadress tagasimakseAadress, uint tagasimakseAeg) public {
nõuda(swapid[hash].summa == 0); // kasuta hash'i kord
nõuda(token.transferFrom(msg.sender, address(this), summa));
swapid[hash] = Swap(token, vastuvõtja, summa, tagasimakseAadress, tagasimakseAeg);
}
funktsioon withdraw(bytes memory saladus) public {
bytes32 hash = sha256(saladus);
Swap memory swap = swapid[hash];
nõuda(swap.summa > 0);
delete swapid[hash];
swap.token.transfer(swap.vastuvõtja, swap.summa);
}
funktsioon refund(bytes32 hash) public {
Swap memory swap = swapid[hash];
nõuda(now > swap.tagasimakseAeg);
delete swapid[hash];
swap.token.transfer(swap.tagasimakseAadress, swap.summa);
}
}
Kontraktiline võtme-dualism ja EIP 712
Nagu me teame, võib Etheri aadress olla kas leping või subjekti, st võti.
Peamine tegevusvõti on allkirjastada mingeid sõnumeid.
Saame kasutada saatjana Bob-lepingut, mis teeb kõik vajalikud tehingud, kontrollides enne seda Bob-võtme allkirja.
Nüüd saab igaüks sponsorida osalise tasu, kuid otsustamise tegija on ainult see, kellel on võti.
Bob-leping
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);
}
}
Ethereumis keerukate andmestruktuuride allkirjade haldamiseks on standard , selle kohta võite lähemalt lugeda
Jagage ja valitsege
Sageli näeb Ethereum'i lepingu häkkimise stsenaarium välja järgmine:
- Osaline paneb lepingusse raha
- Siis võtab raha tagasi
- Midagi läheb valesti
- Kurjategija võtab raha ikka ja jälle
Kui naaseme meie esimese näite juurde, siis midagigi läheb valesti, kui mõistatus on tühi baitide kogum.
Kuidas varastada miljonLoome vahetuse, mille hashr on 0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925
See on sha256 0x0000000000000000000000000000000000000000000000000000000000000000
Edastame salajase ja võtame oma tokenid
Edastame veel kord ja võtame teiste oma, kõik seetõttu, et 0 = 0
Iga tehingu jaoks eraldi lepingu loomisega saame EVM tasemel lepingud isoleerida.
Aga see pole veel kõik: nüüd on igal tehingul oma aadress, kuhu saab ülekandeks tokenid mis tahes rahakotist või börsilt.
Hüljatud lepingud ja create2
Kuid nüüd peame igale tehingule looma lepingud ja ootama, kuni ostja sinna oma töö 'krüptoveri' kannab. Skeemis 'hommikul lepingud, õhtul raha' on alati oht, et ostja loobub, kuid lepingute tegemiseks kulutatud ether on juba ära kulutatud.
Kas ei saaks teha nii, et hommikul raha ja õhtul baitid?
Hardforkis Constantinople arendajad lisasid create2 käsu, mis loob uue lepingu määratletud aadressil
keccak256( 0xff ++ aadress ++ sool ++ keccak256(init_code))[12:]
Kus
- aadress — tehaste lepingu aadress
- sool — mõni number, mille tähendus selgub järgmises osas
- init_code — lepingu baitkood ja konstruktoriparameetrid.
TehasKäsk töötab ainult assembly kaudu, seega näeb tehas välja mõnevõrra hirmutav:
leping Factory {
üritus Deployed(address addr, uint256 salt);
funktsioon create2(bytes mälu kood, uint256 salt) avalik {
aadress addr;
assamblee {
addr := create2(0, add(kood, 0x20), mload(kood), salt)
}
emit Deployed(addr, salt);
}
}
Teie lepingu koodi saab hankida web3 abil:
const MyContract = new web3.eth.Contract(ABI, {})
const kood = MyContract.deploy({
data: BYTECODE,
arguments: contructorArgs
}).encodeABI();
const factory = new web3.eth.Contract(FACTORY_ABI, factoryAddress);
tx = factory.methods.create2(kood, salt);
Solidity piiratud toe tõttu võib lepingu gaasi hindamine olla vale, mis tuleneb mõningatest eetriga seotud nüanssidest.
Eriti meeldiv on see, et gaasi puudumisel kukub leping sisemise veaga, teavitamata, et gaasi on liiga vähe, nagu võiks oodata.
Nüüd saame edastada tokenid lepingutele, luues need eelnevalt, ja enne, kui me neid võrku avaldame, ei saa keegi aru, mida leping täpselt teeb.
Varese varesele silma ei näpi.
On selge, et tõelist analüütikut, eriti kui ta on saanud head investeeringud režiimi vastastele raha pesemisega võitlemiseks, sellised lapsemeelsed trikid ei peata, ja pärast lepingu loomist näeb ta ikkagi hashi.
Kuidas teha nii, et hash ei ilmuks?
Iga swapime viibime off-chain: osalejad vahetavad allkirju swap-lepingule üleminekuks, ja seejärel paljastatakse saladus privaatsetelt.
Samm-sammultLoomisel on kaks "multisigi", millega saab varasid võtta, kui Alice'il ja Bob'il on allkirjad.
Kuna kellegi osalejate offline minek ei tohiks olla tragöödia, lisame vana hea ajavööndi.
Alice ja Bob teevad samal ajal sissemakseid
- Alice mõtleb välja salajase sõnumi ja edastab Bob'ile salajase sõnumi haši ja allkirja tehingule, mis kannab bitcoine swap-aadressile.
- Bob edastab Alicele allkirja tokenite väljavõtmiseks swap-lepingule määratud hashing'iga.
- Alice teatab Bob'ile saladuse.
Sel hetkel saavutavad nad harmoonia: nii Alice kui ka Bob saavad igal hetkel tehingu lõpetada. Selles sõbralikus keskkonnas saavad nad vahetada allkirju raha väljavõtmiseks lõpp-aadressidele.
Kaugele vaatleja jaoks näeb see välja nagu raha liikus läbi 2/2 multisig leping.
Ja selline skeem võimaldab mõlemal poolel teha sissemakseid samaaegselt, kuna saladus mõeldakse välja juba pärast kõiki kinnitusi.
Tase 2
Kuna me saame raha kanda ühele aadressile ja ei avalda vahepealseid tehinguid, ei takista meid raha ülekandmine mitmele aadressile ning piiramatute vahepealsete tehingute tegemine. See ei ole kindlasti vahetuse jaoks vajalik komplekt, kuid kui oled vahetuse kogumisega alustanud, on keeruline peatuda.
Nüüd saavad Alice ja Bob täielikult tegutseda. Näiteks arvutada automaatselt keskmist hinda, vahetades satoshis sekundis, või lihtsalt otse ühendades turuhindaja ja likviidsuse saaja.
Samm-sammult
- Müüja mõtleb välja salajase numbri ja annab ostjale salajase numbri hääletuse ja tehingu allkirja, kus osa vahenditest kantakse p2sh vahetuse aadressile ning ülejäänu tagastatakse müüja aadressile.
- Ostja edastab allkirja, mis lubab vahetus tokenitele ja tagasimaksetele saajale ülekande teha.
- Müüja avab salajase numbri.
- Lugu kordub uue salajase numbriga, mille käigus lisatakse vahetusele ja tagasimaksete juurde ka varem ostetud ja müüja aadressile makstud raha väljavõtmine ostja aadressile.
Nüüd on meil ligipääs kiiretlte p2p kauplemisele, peamine on jälgida aega ja tehing enne aja maha minekut lõpetada.
Kuid veidi muutes meie lepinguid, saame kinkida meie kanalitele surematuse, mis lihtsustab võrgu loomist oluliselt.
Kuid sellest räägime järgmises osas.
Allikas: habr.com
