Ինչու են իրականում վատ ատոմային փոփոխությունները և ինչպես կարող են ալիքները օգնել, ինչ կարևոր բաներ տեղի ունեցան Constantinople-hardfork-ում և ինչ անել, երբ ոչինչ չկա գազի համար վճարելու:
Որպես անվտանգության մասնագետի հիմնական շարժառիթը՝ պատասխանատվությունից խուսափելու ցանկությունն է:
Ամենավերջում ես դուրս եկա ICO-ից, սպասելով առաջին անդառնալի գործարքին, բայց շուտով հայտնվեցի կրիպտոբորսայի մշակմամբ:
Ես՝ արգասիքորեն, ոչ Մալչիշ Կիբալչիշ եմ, և մեկ խիստ հայացքը բավական է, որպեսզի ես հանձնեմ բոլոր բանալիներն ու գաղտPasswords. Հետեւաբար, որպես ճարտարապետի իմ հիմնական նպատակն էր կրիպտոալգորիթմի շտապ ոսպնյակում հեռու պահել իմ սիրելիներին:
Քո բանալիները, քո խնդիրները չեն:
Մենք կառուցում ենք ակտիվների փոխանակման համակարգ և ցանկանում ենք բացառել այդ ակտիվների միջանկյալ պահպանում մեր մոտ, բայց պետք է ապահովենք գործարքի անվտանգությունը:
Հնարավոր է հայտնվել որպես դատավոր վիճակային իրավիճակում և անցկացնել գործարքներ դրամապանակների հետ, որոնք պահանջում են երեքից երկու ստորագրություն՝ գնորդի, վաճառողի և սկրոֆի:
Այդուհանդերձ, եթե մասնակիցը հաջողությամբ հարձակվի սկրոֆի վրա, ապա նա ստանում է որոնվող երկու ստորագրությունները:
Ատոմային swap-ը փոխանակման սխեմա է, որտեղ երաշխավորը հանդիսանում է սմարթ-կոնտրակտ, որը թույլ է տալիս միայն ազնիվ վարք:
Հասկանալով թե լոկխան ում մասին է, կարող ես գործել միայն մեկ ճիշտ սցենարով և կրում ես կորուստ, եթե շեղվում ես դրանից:
Միայն հարմար կենդանիների փոխարեն կարգը ապահովում է hash ֆունկցիա, որի մեջ այնքան դժվար է գտնել բախումը, որ նույնիսկ չի արժի սկսել:
Քայլ առաջինը՝ загадка:
Անհրաժեշտ է պատկերացնել, որ Ալիսան մի գեղեցիկ առավոտ želi տանել Բոբին բիթքոյն` մի բերան «կриптоյուն»:
- Նա շարունակում է մեծ գաղտնիք մտածել:
- Ստանում է նրան hash:
- Փոխանակում է բիթքոյները սմարթ-կոնտրակտին, որի գումարները կարող է վերցնել Բոբը, ներկայացնելով գաղտնիքը (hash-ը պետք է հավասար լինի պայմանագրի մեջ նշվածին):
- Եթե Բոբը չի գալիս իր բիթքոյները վերցնելու երեկոյան, Ալիսան կարող է վերցնել դրանք իր մոտ:
Քայլ երկրորդ՝ приманка:
Բոբը մտնում է խաղի և փոխանցում է «կриптоեվրո» իր կոնտակտին, որը գրված է այնպես, որ:
- Ալիսան կարող է վերցնել «կрипտոեները» ներկայացնելով գաղտնի թիվ:
- Չնայած այդտեղից Բոբը անվանում է «алгары», եթե Ալիսան չի գալիս:
Քայլ երրորդ՝ отгадка в приманке:
Ալիսան գալիս է իր գումարները վերցնելու և վերցնում է գումարը Բոբի պայմանագրից՝ բացելով իր գաղտնիքը:
Քայլ ավարտական՝ загадка разгадана:
Գործարքը տեսնում է Բոբը, ու հայրենասեր հայացքով առանձնացնում է գաղտնիքը, որը Ալիսան ստացել է պայմանագրին: Այս գաղտնիքը նա օգտագործում է իր բիթքոյները վերցնելու:
Երբ ինչ-որ բան անում է սխալ:
Եթե Ալիսան անմիջապես մահանում է, Բոբը իր յուանները վերցնում է կեսօրին:
Այդ նույն ժամանակ, Ալիսան երեկոյան հետ է վերադարձնում բիթքոյնը, եթե հավակնոտ Բոբը գումարը պահելու է ավելի լավ ժամանակների համար:
Եթե դուք նախընտրում եք պատկերն ավելի, կան Հաբրում ավելի մանրամասն և տեսանելի .
Ժամկետային անհամապատասխանությունները նախատեսում են ապահովել մեզ չար Ալիսայի դեմ, որը Բոբի գումարը վերցնում է հենց վերջին պահին, իսկ ժամկետը սպառվում է, երբ նա trembly մատներով գրում է hex-ը տրանսակցիայում:
Մասնակիցները չեն կարող կորցնել իրենց գումարը, առավելագույնը, պետք է սպասել վերադարձին:
Բլոկչեյններում աջակցությունԴա պարզ, ինչպես խոշոր զուգարանը, դասավորություն է, որն աշխատող բլոկչեյններից պահանջում է ընդամենը մի քանի բան:
- Սմարտ պայմանագրերի աջակցություն, եթե առնվազն մի բաժին կա
- Երկու բլոկչեյնները պետք է աջակցեն նույն հեշինգ ալգորիթմներին (չպետք է մոռանաք ստուգել գաղտնիքի երկարությունը)
- Ժամփակման ժամեր:
Առաջին հայացքից, արդեն կարելի է decir «ս Goodbye» բորսային, մեր հանդիպումը սխալ էր, բայց այդքան էլ այդպես չէ:
Ամենաշատ առավելությունները ատոմար սվոփերի լուծումները չեն տրվում լիկվիդությամբ։ Մի մասը, որ ամենահայտնի զույգում BTC-USD ֆիատ մասը այնքան էլ տոքենիզացված չէր:
USDT-ի հաջողությունը ծնեց մի ամբողջ ալիք կայուն մետաղադրամների ERC20 ձևաչափով, որ ամեն ճաշակի, սկսած առավելագույն պահպանվող USDC-ից մինչև ալգորիթմային DAI:
Պարզության համար մենք հաջորդում ենք այն, որ Ալիսան Բոբին բիթքոյներ է վաճառում ինչ-որ ERC20 տոքենների դիմաց, և հույս ենք հայտնում կայունացնողների հաջողության, բարեբախտաբար, դեռ շատ ու ավելի տեխնիկական խնդիրներ կան:
Արագություն
Բիթքոյնը և Էթերիումը առանձին շատ արագ չեն, իսկ այստեղ պետք է սպասել սկզբում մի დეპոզիտ բոլոր հաստատումներով, ապա երկրորդ:
Դա տեղի է ունենում, քանի որ սկզբում գումարը մուտք է գործում մասնակցի կողմից, որը տեղեկություն ունի գաղտնիքի մասին, իսկ հակառակորդը սպասում է վերջնականությանը, և միայն այդ ժամանակ է, երբ նա փոխանցում է իր մասնաբաժինը:
Բացի այդ, մենք գործ ունենում ենք բավականին տատանվող ակտիվի հետ, այնպես որ այդ ընթացքում փոխարժեքը կարող է բավականին զգալիորեն փոխվել, իսկ պայմանները փոխելը արդեն դժվար է:
Անվտանգություն
Յուրաքանչյուր փոխանակում թողնում է արհեստական նյութեր երկու բլոկչեյններում։ Ակտիվ հետևորդն կարող է նկատել նույն հեշերը սմարթ պայմաններում և կատարել անմիջական ենթադրություններ, որոնք կարող են բարձր մակարդակի մտահոգություններ առաջացնել.
Երբ ձեր գործերը հայտնի են բորսային — դա շատ աննպատակ է, երբ դրանց մասին գիտի każdy — դա կրկնակի աննպատակ է:
Օգտագործելիություն
Բլոքչեյնի և էթերիի թեմաներից մեկն է։ Մնանք, թե ինչպիսի շարժումներ պետք է կատարի վաճառորդը և գնորդը:
Վաճառողից համար ամեն ինչ հարաբերականորեն պարզ է. պարզապես պետք է փոխանցել բիթքոյնը p2sh հասցեին։ Էթերիումի դեպքում ամեն ինչ շատ ավելի խելացի է:
ՊայմանագիրԵկեք վերանայենք GitHub-ի միջին պայմանագիրը սվոփի համար:
ուշა iERC20 {
ფუნქცია totalSupply() საზოგადოება ხედავს დაბრუნებას (uint256);
ფუნქცია transfer(მისამართი მიმღები, uint numTokens) საჯაროდ აბრუნებს (bool);
ფუნქცია balanceOf(მისამართი tokenOwner) საზოგადოება ხედავს დაბრუნებას (uint);
ფუნქცია approve(მისამართი წარმომადგენელი, uint numTokens) საჯაროდ აბრუნებს (bool);
ფუნქცია allowance(მისამართი მფლობელი, მისამართი წარმომადგენელი) საზოგადოება ხედავს დაბრუნებას (uint);
ფუნქცია transferFrom(მისამართი მფლობელი, მისამართი მყიდველი, uint numTokens) საჯაროდ აბრუნებს (bool);
}
შუშა Swapper {
სტრუქტურა Swap {
iERC20.token;
bytes32.hash;
uint.amount;
uint.refundTime;
bytes32.secret;
}
mapping (მისამართი => mapping(მისამართი => Swap)) swaps;
ფუნქცია create(iERC20 token, bytes32 hash, მისამართი მიმღები, uint რაოდენობა, uint refundTime) საჯაროდ {
require(swaps[msg.sender][receiver].amount == 0); // შეამოწმეთ, რომ მოცემული hash swap უკვე არსებობს
require(token.transferFrom(msg.sender, address(this), amount)); // გადარიცხეთ გაჩერებული tokens swap კონტრაქტში
swaps[msg.sender][receiver] = Swap(token, hash, amount, refundTime, 0x00); // შექმენით swap
}
ფუნქცია hashOf(bytes32 secret) საჯაროდ სუფთა აბრუნებს(bytes32) {
დაბრუნება sha256(abi.encodePacked(secret));
}
ფუნქცია withdraw(მისამართი მფლობელი, bytes32 secret) საჯაროდ {
Swap მეხსიერება swap = swaps[owner][msg.sender];
require(swap.secret == bytes32(0));
require(swap.hash == sha256(abi.encodePacked(secret))); // swap არსებობს
swaps[owner][msg.sender].secret = secret;
swap.token.transfer(msg.sender, swap.amount);
}
ფუნქცია refund(მისამართი მიმღები) საჯაროდ {
Swap მეხსიერება swap = swaps[msg.sender][receiver];
require(now > swap.refundTime);
წაშალეთ swaps[msg.sender][receiver];
swap.token.transfer(msg.sender, swap.amount);
}
}
Ուշադրություն! გთხოვთ, ნუ მიხმარებთ ამ და სხვა კონტრაქტების გამოყენებას სტატიის მიხედვით გამოჩნდეს, ისინი დაწერილია მხოლოდ დემონსტრაციისთვის. მ خصوص აქედან.
- ბობი უნდა გამოძახოს ცალკე კონტრაქტის მეთოდი
approve, რომ swap კონტრაქტს მიაწვდოს მის.token-ები - ბობი creates swap და კონტრაქტს მეთოდი
transferFromწაიღებს მის მისამართზე გამოგზავნის tokens - ალისა
withdrawგამჟღავნებს სესხს და კონტრაქტი გამოძახებასtransfer
მრგვალ დედებთან და კრიპტობირჟებში არ არის მხარდაჭერა approve tokens-ები, და არა შემთხვევით.
საკუთარ მომხმარებლებს ხშირად აქვთ შეცდომები და მხოლოდ გადასცემენ tokens კონტრაქტას, რის შემდეგაც tokens უბრალოდ დაიკარგება. Etherscan-ზე კომენტარების მნიშვნელოვანი ნაწილი არის გვესკნელების მონიტორინგათი.
და კონტრაქტის გამოძახებაზე საჭიროა ETH-ის გადასახადი, ამიტომ ორივე მონაწილე უნდა დაიცვას მას დაწყების წინ, და ამის გაკეთებას ცოტა ადამიანი უნდა შეიძინოს.
გაზგოლდეგი
დასაწყისში უნდა მოხდეს გამოსატყვისების გადაჭრა ყველგან, სადაც შესაძლებელი იყო, და ვირწმუნოთ, რომ ვიღაცა გვაქვს, ვინც განვახორციელებს კონტრაქტებზე ყველასთვის.
მოდრიზირებული კონტრაქტი
კონტრაქტი Swapper {
სტრუქტურა Swap {
iERC20.token;
მისამართი მიმღები;
uint.amount;
მისამართი refundAddress;
uint.refundTime;
}
mapping (bytes32 => Swap) swaps;
ფუნქცია create(iERC20 token, bytes32 hash, მისამართი მიმღები, uint რაოდენობა, მისამართი refundAddress, uint refundTime) საჯაროდ {
require(swaps[hash].amount == 0); // გამოიყენეთ hash ერთხელ
require(token.transferFrom(msg.sender, address(this), amount));
swaps[hash] = Swap(token, receiver, amount, refundAddress, refundTime);
}
ფუნქცია withdraw(bytes memory secret) საჯაროდ {
bytes32 hash = sha256(secret);
Swap მეხსიერება swap = swaps[hash];
require(swap.amount > 0);
წაშალეთ swaps[hash];
swap.token.transfer(swap.receiver, swap.amount);
}
ფუნქცია refund(bytes32 hash) საჯაროდ {
Swap მეხსიერება swap = swaps[hash];
require(now > swap.refundTime);
წაშალეთ swaps[hash];
swap.token.transfer(swap.refundAddress, swap.amount);
}
}
კონტრაქტური-კმახური დუალიზმი და EIP 712
Ինչպես որ մենք գիտենք, ալիքի հասցեն կարող է լինել պայմանագիր, կամ կարող է լինել առարկա, այսինքն՝ բանալի:
Բանալիի հիմնական գործառույթը՝ ստորագրել որևէ հաղորդագրություն:
Մենք կարող ենք որպես ուղարկող օգտագործել Բոբ-պայմանագիրը, որը կատարում է բոլոր անհրաժեշտ փոխանցումները, նախքան Բոբ-բանալիի ստորագրության ստուգումը:
Այժմ, ցանկացած մարդ կարող է Sponsoring-ի կոմիտեին, բայց որոշումը կայացնում է միայն նա, ով տեղեկացված է բանալիի մասին:
Բոբ-պայմանագիր
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-ում բարդ տվյալների ստորագրություններով աշխատելու համար կա ստանդարտ , ավելի մանրամասն կարող եք կարդալ
Անջատիր և կառավարիր
Հաճախ Ethereum պայմանագրի ներխուժման սցենարը выглядит так:
- Ը partecipate funds-ի բարձը պայմանագրին
- Այնուհետ ձեռք են բերում գումարը
- Ինչ-որ բան սխալ է լինում
- Թույլտվություն չի տրվում կրկնի, կրկին հաշիվը օրինակում լինի
Եթե մենք վերադառնանք մեր առաջին օրինակին, սխալ է տեղի ունենում, եթե առեղծվածը դատարկ բայթերի հավաքածուն է:
Ինչպես գ steal millionՍտեղծում ենք swap-ը hash-ով 0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925
यह sha256 का है 0x0000000000000000000000000000000000000000000000000000000000000000
Հանձնվում է գաղտնիքը և վերցնում ենք մեր նշումը
Հանձնվում է ևս մեկ անգամ և վերցնում ենք ուրիշինը, որովհետև 0 = 0
Յուրաքանչյուր գործարքի համար առանձին պայմանագիր ստեղծելով, մենք կարող ենք պայմանագրերը զանազանել EVM մակարդակում:
لكن это еще не все: теперь каждой сделке присущ адрес, на который можно переводить токены из любого кошелька или биржи.
Հեռացված պայմանագրեր և create2
Այժմ, սակայն, յուրաքանչյուր գործարքի համար պետք է պայմանագիր ստեղծել և սպասել, թե երբ գնորդը կփոխանցի այնտեղ աշխատանքի "կրիպտոֆենինգը"։ «առավոտյան պայմանագիր, երեկոյան գումար» սխեման ունի հավանականություն, որ գնորդը կվերանա, իսկ արտահայտությունը պայմանագրին արդեն ծախսված է։
Չէ որ կարելի է անել այնպես, որ առավոտյան գումար, իսկ երեկոյան բայթերը:
Constantinople-hard fork-ում մշակողները ավելացրել են create2 հրահանգը, որը պայմանագիր ստեղծում է որոշակի հասցեում
keccak256( 0xff ++ հասցե ++ աղյուսակ ++ keccak256(init_code))[12:]
Որտեղ
- հասցե — ֆաբրիկայի պայմանագրի հասցեն
- աղյուսակ — որևէ թիվ, որի իմաստը մենք կիմանանք հաջորդ մասում
- init_code — պայմանագրի բայթ-кոդը և կառուցողի պարամետրերը.
ՖաբրիկաՀրահանգը աշխատում է միայն assembly-ի միջոցով, այնպես որ, ֆաբրիկան մի փոքր ահարկու տպավորվում է:
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);
}
}
Ձեր պայմանագրի կոդը կարող եք ստանալ 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);
Solidity-ի սահմանափակ աջակցման պատճառով, գազը կարող է սխալ հաշվարկվել որոշակի նրբությունների պատճառով:
特别可爱的是,如果汽油不足,合同将因内部错误而崩溃,而不会报告汽油不足的情况,这与预期的情况相同。
Հիմա մենք կարող ենք փոխանցել տոկենները պայմանագրեր, դրանք նախօրոք ստեղծելու կարիք չկա և մինչև մենք դրանք ցանցում հրապարակենք, ոչ Nobody չի অনুমանի, թե պայմանագիրը ինչ է անում:
Վարսաքենու աչքը չի խփում մյուսին
Հստակ է, որ իսկական վերլուծաբանը, հատկապես, որը որոնք ստացել են մեծ ներդրումներ ռեժիմի հակառակորդների կանխումի համար փողը լվանալու առումով, այդպիսի մանկական հնարքներ չեն կանգնեցնի, և պայմանագիրը ստեղծելուց հետո նա դե ֆակտո կտեսնի բաղադրիչը:
Ինչպե՞ս անել այնպես, որ բաղադրիչը չլուսաբերվի:
Սվոպը մենք իրականացնում ենք օֆչեյնում. մասնակիցները փոխանակում են ստորագրությունները սվոպ-պայմանագրի փոխանցման համար, իսկ հետո գաղտնիք բացահայտվում է խիստ գաղտնի.
Քայլ առ քայլՍտեղծվում են երկու «մուլտիսիգ», որոնց միջոցով կարելի է վերցնել միջոցները, եթե Ալիսայի և Բոբի ստորագրությունները ներկա են:
Դրա համար, որպեսզի որևէ մասնակցի դուրս գալը օֆլայն չդարձրեն աղետ, ավելացնենք հին լավ таймаут:
Ալիսան և Բոբը զուգահեռ են ներդրում անում
- Ալիսան գաղտնիք է նախատեսում և փոխանցում Բոբին գաղտնիքի բաղադրիչը և փոխանցման տակ ապրանքների ստորագրությունը, որը բիտկոյները տեղափոխում է սվոպի հասցեին
- Բոբը Ալիսային փոխանցում է սվոպի պայմանագրի բիտիանական ստորագրությունը նշված բաղադրիչով:
- Ալիսան Բոբի տեղեկացնում է գաղտնիքը:
Այս պահին ներդրողությունը սպասում է: Ալիսան և Բոբը ցանկացած պահի կարող են ավարտել գործարքը: Այսպիսի բարեկամական մթնոլորտում նրանք կարող են փոխանակել ստորագրությունները, որպեսզի փողերը տեղափոխվեն վերջնական հասցեներ:
Երրորդ կողմի դիտորդի համար սա նման է նրան, որ փողերը անցել են 2-ը 2 մուլտիսիգով պայմանագրի միջոցով:
Եվ, այս մտքի շնորհիվ, երկուսն էլ կարող են գումար ներդնել միաժամանակ, քանի որ գաղտնիքը նախատեսվում է բոլոր հաստատումներից հետո:
Level 2
Որպեսզի գումարները մեկ հասցեում տեղափոխելու ենք և միջանկյալ փոխանցումը չհրապարակենք, ոչինչ չի խոչընդոտում գումարները մի քանի հասցեներ տեղափոխելու և անսահման քանակի միջանկյալ փոխանցումների կատարելու: Սա այնքան էլ անհրաժեշտ նախարար չէ, բայց եթե սկսել եք սվոպի հավաքումը, դժվար է կանգ առնել:
Հիմա Ալիսան և Բոբը կկարողանան առանձին գործել: Օրինակ, ավտոմատ կերպով հաշվարկել միջին գինը՝ փոխանակելով սատոշիին մեկ վարկյան, կամ ուղղակիորեն միացնել ձևավորողին և լիկվիդության ստացողին:
Քայլ առ քայլ
- Վաճառողը գաղտնիք է նախատեսում և փոխանցում գնորդին գաղտնիքի բաղադրիչը և փոխանցման տակ ստորագրությունը, որտեղ տարածքների մասը տեղափոխվում է սվոպի p2sh հասցեին, իսկ մնացորդը վերադարձվում է վաճառողի հասցեին
- Հաճախորդը փոխանցում է ստորագրություն, որն իրավունքը տալիս է փոխարկման համար նշանները և վերադարձումը հասցեատիրոջին:
- Վաճառողը բացում է գաղտնիքը
- Պատմությունը կրկնվում է նոր գաղտնիքով, այս դեպքում փոխարկմանը և վերադարձմանը ավելանում է նաև նախկինում ձեռք բերված և վաճառողի կողմից արդեն վճարված նշանների դուրսբերում հաճո գնորդի հասցեով:
Այսուհետ մեզ հասանելի է բարձր արագությամբ p2p առևտուրը, կարևոր է հետևել ժամանակին և փակել գործարքը մինչև ժամկետը:
Սակայն, մի փոքր փոփոխելով մեր պայմանագրերը, մենք կարող ենք մեր ալիքներին շնորհավորել անմահություն, ինչը մեծապես կ sencilla մեզ ցանց ստեղծելու հարցում:
Բայց այս մասին մենք կպատմենք հաջորդ հաղորդմամբ:
Ընտանիք: habr.com
