Shkëlqimi dhe varfëria e swaps-ëve atomic

Cilat janë disavantazhet e swap-eve atomike dhe si mund t'i ndihmojnë kanalet, çfarë ndodhi rëndësishëm në hard fork-un Constantinople dhe si të veprojmë kur nuk kemi si të paguajmë gazin.

Motivacioni kryesor i çdo specialisti të sigurisë është dëshira për të shmangur përgjegjësinë.

Fati ishte më i mirëkuptueshëm, unë u largova nga ICO pa pritur transaksionin e parë të pakthyeshëm, por së shpejti e gjeta veten duke zhvilluar një exchange kripto.

Unë nuk jam aspak Mëllçi Kibalçisht, dhe një shikim i fortë është i mjaftueshëm që unë të dorëzoj të gjitha çelësat dhe fjalëkalimet. Prandaj, qëllimi im kryesor si arkitekt ishte të vendosja gjilpërën e nxehtë të kriptoanalizës sa më larg që të ishte e mundur nga elementet e infrastrukturës që më janë të shtrenjta.

Nuk janë çelësat e tu, nuk janë problemet e tua.

Ne po ndërtojmë një sistem shkëmbimi aktivesh dhe duam të përjashtojmë ruajtjen ndërmjetësore të këtyre aktiveve, por duhet të sigurojmë sigurinë e transaksionit.

Mund të veprosh si gjyqtar në një situatë spori dhe të realizosh transaksione me portofolat që kërkojnë dy nga tre nënshkrime: blerësi, shitësi dhe escrow.

Megjithatë, nëse një pjesëmarrës e sulmon me sukses escrow-in, ai merr dy nënshkrimet e dëshiruara.

Swap-i atomik është një schemë shkëmbimi, ku garant i saj është smart kontrakti, i cili lejoi vetëm sjellje të ndershme.

Ashtu si në enigmën për ujkun, kozën dhe kapustën, ti mund të veprosh vetëm sipas një skenari të vetëm të saktë dhe do të pësojë humbje nëse devijon nga ai.

Por në vend të kafshëve ndotëse, rendi sigurohet nga funksioni hash, në të cilin është kaq e vështirë të gjesh një kolizion, sa nuk ia vlen të fillosh.

Hapi i parë: enigmat.

Le tĂ« supozojmĂ« se Alisa, njĂ« mĂ«ngjes tĂ« bukur, dĂ«shiron tĂ« transferojĂ« Bobit bitcoin pĂ«r njĂ« grusht “kriptojuanesh”.

  • Ajo zbulon njĂ« sekret tĂ« madh.
  • Merr nga ai njĂ« hash.
  • Transferon bitcoin nĂ« smart kontrakt, nga i cili paratĂ« mund t'i marrĂ« Bobi, duke paraqitur sekretin (hash-i nga ai duhet tĂ« barazojĂ« atĂ« tĂ« specifikuar nĂ« kontratĂ«n).
  • NĂ«se Bobi nuk e merr bitcoin-in e tij deri nĂ« mbrĂ«mje, Alisa mund tĂ« marrĂ« ata pĂ«rsĂ«ri pĂ«r vete.

Hapi i dytë: kurthi.

NĂ« lojĂ« hyn Bobi dhe transferon “kriptoeuro” nĂ« kontraktin e tij, i cili Ă«shtĂ« shkruar nĂ« njĂ« mĂ«nyrĂ« qĂ«:

  • Alisa mund tĂ« marrĂ« “kriptojenet” duke paraqitur njĂ« numĂ«r sekret.
  • Jo mĂ« herĂ«t sesa pasdite, Bobi, nĂ«se Alisa nuk shfaqet, mund tĂ« rikthejĂ« depozitĂ«n e tij.

Hapi i tretë: zbulimi në kurth.

Alisa vjen për paratë e saj dhe merr paratë nga kontrata e Bobit, duke zbuluar kështu sekretin e saj.

Hapi përfundimtar: enigmat është zgjidhur

Transaksionin e sheh Bobi, dhe me sy shqiponje e nxjerr atë sekret, të paraqitur nga Alisa në kontratë. Ky sekret ai e përdor për të marrë bitcoinët e tij.

Kur diçka shkon keq

Nëse Alisa papritur bëhet e vdekur, Bobi merr juanët e tij në drekë.

Nga ana tjetër, Alisa në mbrëmje kthehet me bitcoin, nëse Bobi tradhëtar vendos ta mbajë paratë për kohë më të mira.

Nëse preferoni një imazh më shumë se tekstin, në Habr për ju ka një shpjegim më të detajuar dhe vizual për funksionimin e swap-eve atomike.

Dallimi midis skadimeve është dizajnuar për të na mbrojtur nga Alisa e keqe, e cila merr paratë e Bobit në momentin më të fundit, ndërsa skadimi kalon, për sa kohë ai po merr frymë me gishta të dridhura duke futur hex në transaksion.

Pjesëmarrësit nuk mund të humbin paratë e tyre, maksimumi, do të duhet të presin kthimin.

Mbështetje në bllokadëKjo është një skemë e thjeshtë, si një këpucë, që kërkon vetëm pak nga bllokat që bashkëpunojnë:

  • MbĂ«shtetje pĂ«r kontratat e mençura me tĂ« paktĂ«n njĂ« degĂ«zim
  • TĂ« dy bllokat duhet tĂ« mbĂ«shtesin algoritme tĂ« njĂ«jta hash-shi (mos harroni tĂ« kontrolloni gjatĂ«si e sekretit)
  • KohĂ«zgjatjet.

Me njĂ« vĂ«shtrim tĂ« parĂ«, mund tĂ« thuhet tanimĂ« “lamtumirĂ« burse, takimi ynĂ« ishte njĂ« gabim”, por jo kaq lehtĂ«.

Pavarësisht të gjithë përfitimeve të saj, zgjidhjet në swap atomik nuk janë të mahnitshme në likuiditet. Shumë për shkak se në çiftin më të popullarizuar BTC-USD, pjesa fiat nuk ishte plotësisht e tokenizuar.
Suksesi i USDT ka shkaktuar një valë të tërë të monedhave stabile në formatin ERC20 sipas çdo shije, nga më mbështetësja USDC deri te më algoritmike DAI.

Prandaj, për thjeshtësi ne flasim më tutje se Alisa po shet Bobit bitcoin për disa tokena ERC20, dhe shpresojmë për fatin e stabilizatorëve, për fatin tonë kemi akoma më shumë probleme teknike.

Shpejtësia

Bitcoin dhe Ethereum veç e veç nuk janë shumë të shpejtë, dhe tani na duhet të presim fillimisht një depozitë me të gjitha miratimet, pastaj tjetrën.

Kjo është për shkak se fillimisht paratë depozitohet nga pjesëmarrësi, i cili e di sekretin, dhe rivali pret finalizimin dhe vetëm atëherë kalon pjesën e tij.

Për më tepër, ne jemi duke u marrë me një aset shumë të paqëndrueshëm, kështu që gjatë këtij kohë, çmimi mund të ndryshojë ndjeshëm, dhe ndryshimi i kushteve është tashmë i vështirë.

Privatësia

Çdo shkĂ«mbim lĂ« pas artefakte nĂ« tĂ« dyja blockchain-et. NjĂ« vĂ«zhgues i kujdesshĂ«m mund tĂ« vĂ«rejĂ« hash tĂ« njĂ«jta nĂ« kontratat smart dhe tĂ« nxjerrĂ« njĂ« pĂ«rfundim logjik se kĂ«tu Ă«shtĂ« realizuar njĂ« transaksion, nga i cili mund tĂ« nxirren shumĂ« pĂ«rfundime nga ato financiare deri te ato tatimore.

Kur bursa di pĂ«r çështjet e tua — Ă«shtĂ« jashtĂ«zakonisht e pakĂ«ndshme, kur gjithĂ« tĂ« tjerĂ«t e dinĂ« — Ă«shtĂ« dyfish e pakĂ«ndshme.

Përdorshmëria

Një veçori thelbësore e blockchain-it, sidomos e Ethereum-it. Le të shikojmë se çfarë lëvizjesh duhet të bëjë shitësi dhe blerësi.

Nga këndvështrimi i shitësit, gjithçka është relativisht e thjeshtë: thjesht duhet të transferojë bitcoin në adresën p2sh. Me Ethereum-in, gjërat janë shumë më të komplikuara.

KontrataLe të shqyrtojmë një kontratë të mesme nga GitHub për shkëmbim:

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);
    }
}

Kujdes! Mos e përdorni këtë dhe kontratat e tjera nga ky artikull në prodhim, ato janë shkruar ekskluzivisht për demonstrim. Sidomos kjo.

  • Bobi duhet tĂ« thĂ«rrasĂ« metodĂ«n e kontratĂ«s sĂ« tokens approve, duke i dhĂ«nĂ« kontratĂ«s sĂ« shkĂ«mbimit akses nĂ« tokenat e tij
  • Bobi krijon njĂ« shkĂ«mbim dhe kontratĂ«n duke pĂ«rdorur metodĂ«n transferFrom dhe merr nĂ« adresĂ«n e tij tokenat e dĂ«rguesit
  • Alisa nĂ« withdraw zbulon sekretin dhe kontrata thĂ«rret transfer

Shumica e xhelave dhe kriptoburseve nuk mbështesin approve tokenët, dhe nuk është pa arsye.

Këta përdorues shpesh gabojnë dhe thjesht transferojnë tokenë në kontratën, pas së cilës tokenët humbasin. Komentet në Etherscan janë plot me ankesat e të mjerëve.

Për të thirrur kontratën, duhet të paguani një tarifë në ETH, kështu që të dy palët duhet të kenë disa para përpara fillimit të marrëveshjes, dhe këtë pak kush dëshiron ta bëjë.

Gazgërmuesi

Fillimisht duhet të hiqni verifikimin e dërguesit gjithandej ku është e mundur dhe të supozoni se kemi dikë që vuajnë nga mbiprodhim gazi dhe thërret kontrata për të gjithë që duan.

Kontrata e modernizuar

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);
    }
}

Dualizmi kontrakt-kyç dhe EIP 712

Siç e dimë, adresa në eter mund të jetë një kontratë, ose mund të jetë një subjekt, dmth një kyç.
Aktiviteti kryesor i kyçit është të nënshkruajë disa mesazhe.

Ne mund të përdorim kontratën e Bob-it si dërgues, e cila bën të gjitha kalimet e nevojshme, pasi të ketë verifikuar nënshkrimin e Bob-it kyç.

Tani, kushdo mund të sponsorizojë tarifën e pjesëmarrësit, por vetëm ai që e di kyçin merr vendimin.

Kontrata e Bob-it

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);
    }
}

Për punën me nënshkrime të strukturave të dhënash të ndërlikuara në Ethereum ekziston një standard EIP 712, mund të lexoni më shumë rreth tij në blogun e portofolit Metamask

Ndaj dhe sundo

Shpesh skenari i hackimit të kontratës Ethereum duket kështu:

  • PjesĂ«marrĂ«si vendos fonde nĂ« kontratĂ«
  • Pastaj tĂ«rheq fonde
  • Diçka shkon keq
  • Sulmuesi merr paratĂ« pĂ«rsĂ«ri dhe pĂ«rsĂ«ri

Nëse kthehemi në shembullin tonë të parë, diçka shkon keq nëse enigmat është një grup i zbrazët bytes.

Si të vjedhësh një milionKrijojmë një swap me hash 0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925
Ky është sha256 nga 0x0000000000000000000000000000000000000000000000000000000000000000
Kalojmë sekretin dhe marrim tokenet tona
Kalojmë përsëri dhe marrim të huajat, gjithë kjo sepse 0 = 0

Duke krijuar një kontratë të veçantë për çdo marrëveshje, ne mund të izolojmë kontratat në nivelin EVM.

Por kjo nuk është e gjitha: tani çdo marrëveshje ka adresën e saj, në të cilën është e mundur të dërgohen tokenet nga çdo portofol ose shkëmbim.

Kontratat e braktisura dhe create2

Por tani për çdo marrëveshje duhet të krijojmë një kontratë dhe të presim derisa blerësi të dërgojë punën e tij 'kriptomundore'. Në skemën 'në mëngjes kontratat, në mbrëmje paratë' gjithmonë ekziston rreziku që blerësi të largohet, ndërsa ethe për krijimin e kontratës janë tashmë të shpenzuara.

A mund të bëjmë që në mëngjes të jenë paratë, dhe në mbrëmje bytes?

Në hardfork-un Constantinople zhvilluesit EIP 1014 shtuan direktivën create2, e cila krijon një kontratë të re në një adresë të caktuar

keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]

Ku

  • address — adresa e kontratĂ«s fabrikĂ«
  • salt — njĂ« numĂ«r i caktuar, kuptimi i tĂ« cilit do ta kuptojmĂ« nĂ« serinĂ« e ardhshme
  • init_code — kodi nĂ« byte tĂ« kontratĂ«s dhe parametrat e konstruktorit.

FabrikaDirektiva funksionon vetëm përmes assembly, kështu që fabrika duket disi e frikshme:

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);
  }
}

Kodi i kontratës tuaj mund të merret nëpërmjet web3:

const MyContract = new web3.eth.Contract(ABI, {})
const code = MyContract.deploy({
    data: BYTECODE,
    arguments: contructorArgs  
}).encodeABI();
const factory = new web3.eth.Contract(FACTORY_ABI, factoryAddress);
tx = factory.methods.create2(code, salt);

Për shkak të mbështetjes së kufizuar në solidity, gazi për kontratën mund të llogaritet gabim për shkak të disa nuancave të etheve.

Veçanërisht e bukur është që në rastin e mungesës së gazit, kontrata bie me një gabim të brendshëm, pa e bërë të qartë se gazit nuk ka mjaft, siç mund të pritet.

Tani, ne mund të transferojmë tokene në kontrata pa i krijuar ato më parë dhe derisa t'i publikojmë në rrjet, askush nuk do të dyshojë se çfarë bën kontrata.

Korbi nuk i nxjerr sytë korbit tjetër.

E qartë, që një analist i vërtetë, sidomos ai që ka marrë investime të mira për të luftuar armiqtë e sistemit përmes pastrimit të parave, nuk do të ndalet nga këto trillime fëmijësh, dhe pas krijimit të kontratës ai përsëri do të shohë hash-in.

Si ta bëjmë që hash-i të mos ekspozohet?

Ne transferojmë vetë swap-in në offchain: pjesëmarrësit shkëmbejnë nënshkrime për transferimin në kontratën e swap-it dhe më pas sekreti zbullohet në privat.

Hapi pas hapiKrijohen dy 'multisig' nga të cilat mund të tërhiqen fonde vetëm nëse ka nënshkrime nga Alice dhe Bob.

Për të siguruar që largimi offline i ndonjërit prej pjesëmarrësve nuk të bëjë tragjedi, do të shtojmë një ndihmë të vjetër, timeout-in.

Alice dhe Bob njëkohësisht depozitojnë.

  • Alice shpik njĂ« sekret dhe i dĂ«rgon Bob-it hash-in e sekretit dhe nĂ«nshkrimin e transaksionit qĂ« transferon bitcoin nĂ« adresĂ«n e swap-it.
  • Bob i dĂ«rgon Alice-s nĂ«nshkrimin pĂ«r tĂ« tĂ«rhequr token-at nĂ« kontratĂ«n e swap-it me hash-in e shpikur.
  • Alice i tregon Bob-it sekretin.

Në këtë moment arrin harmonia: si Alice ashtu edhe Bob mund të përfundojnë marrëveshjen në çdo moment. Në një ambient kaq miqësor, ata mund të shkëmbejnë nënshkrime për tërheqjen e parave në adresat përfundimtare.

Për një vëzhgues të jashtëm, kjo duket si të gjitha paratë kaluan nëpër një kontratë me multipodpis 2 nga 2.

Përveç kësaj, një skemë e tillë lejon të dy palët të bëjnë një depozitë njëkohësisht, sepse sekreti shpiket pas të gjitha konfirmimeve.

Niveli 2

Tani që ne mund të tërheqim para në një adresë dhe të mos publikojmë transaksionin ndërmjetës, asgjë nuk na pengon të tërheqim para në disa adresa dhe të kryejmë një numër të pakufizuar transaksionesh ndërmjetës. Nuk do të thoja se është një grup i nevojshëm për shkëmbim, por nëse e ke filluar një swap, është e vështirë të ndalesh.

Tani Alice dhe Bob do të kenë mundësi të zhvillohen plotësisht. Për shembull, llogaritni automatikisht çmimin mesatar, duke shkëmbyer në satoshi për sekondë, ose thjesht lidhni drejtpërdrejt krijuesin e tregut dhe merrësin e likuiditetit.

Hapi pas hapi

  • ShitĂ«si shpik njĂ« sekret dhe i jep blerĂ«sit hash-in e sekretit dhe nĂ«nshkrimin e transaksionit ku njĂ« pjesĂ« e fondeve transferohet nĂ« adresĂ«n p2sh tĂ« swap-it, ndĂ«rsa pjesa tjetĂ«r kthehet nĂ« adresĂ«n e shitĂ«sit.
  • Kurshtari pĂ«rcjell njĂ« nĂ«nshkrim qĂ« lejon nxjerrjen e tokens dhe kthimin nĂ« adresĂ«n e marrĂ«sit.
  • ShitĂ«si zbulon sekretin
  • Historia pĂ«rsĂ«ritet me njĂ« sekret tĂ« ri, duke shtuar pĂ«r swap dhe kthim edhe nxjerrjen e asaj qĂ« Ă«shtĂ« blerĂ« mĂ« parĂ« nĂ« adresĂ«n e blerĂ«sit dhe tashmĂ« i paguar nĂ« adresĂ«n e shitĂ«sit.

Tani na është e mundur tregtia p2p me shpejtësi të lartë, e rëndësishme është të ndjekim kohën dhe të mbyllim marrëveshjen para se të skadojë.

Megjithatë, duke e rregulluar pak kontratën tonë, mund t'u japim kanaleve tona pamje të përjetshme, çka do ta thjeshtonte shumë krijimin e rrjetit.

Por për këtë do të flasim në serinë e ardhshme.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster