Ethereum-da to'liq markazlashtirilmagan Dapp-ni yaratish va o'rnatish uchun eng so'nggi qo'llanma

Ushbu o'quv qo'llanmada mening maqsadim sizni markazlashtirilmagan dasturni yaratish va Ethereum-ga joylashtirish uchun zarur bo'lgan qadamlar bilan tanishishdir.

Izoh: Bir necha keskin o'zgarishlarni tuzatish uchun 2 mart kuni yangilangan va qayta ko'rib chiqilgan.

Bu qanday ko'rinishga ega:

Men buni amalga oshirmoqdaman, chunki men sizga hamma narsani qanday ulash haqida to'liq tasavvurga ega bo'lmagan va juda kuchli texnologiya bo'lgan IPFS bilan markazlashtirilmagan xostingni o'z ichiga olgan juda ko'p darslarni ko'raman.

Bundan tashqari, men ethereum veb-sayti haqida gapiradigan haqiqatan ham to'xtab bo'lmaydigan dasturni qanday ishlab chiqishni aniq bilmagan vaziyatga tushib qoldim.

Siz ba'zi asosiy va murakkab mavzularni o'rganasiz, masalan:

  • Smart shartnomani noldan qanday yaratish kerak
  • Smart kontraktlarni ropsten-da qanday joylashtirish kerak
  • Dappning tashqi ko'rinishini qanday yaratish kerak
  • O'rnatilgan shartnomani sizning arizangiz bilan qanday ulash mumkin
  • IPFS-ning markazlashtirilmagan xostida oxirgi dasturni qanday o'rnatish kerak
  • Shaxsiy domeningizdan IPFS bilan qanday foydalanish kerak

Ushbu o'quv qo'llanmaning oxirida siz o'zingizning Smart kontraktlaringiz bilan to'liq markazlashtirilmagan veb-saytga ega bo'lasiz, shunda siz ularni brauzerdan foydalanib, Metamask yoki Mist-dan foydalanib blockchain bilan aloqa o'rnatishingiz mumkin.

Siz blockchain, yaratilgan dasturiy ta'minot, shartnomalar qanday ishlashi va javascript bilan veb-saytlarni dasturlash tajribasi haqida ozgina bilishingiz kerak.

Agar siz ushbu dastur qanday ishlashini bilsam va Ethereum-da o'rganish va Dapp dasturchisi bo'lish uchun nimadir yaratishni xohlamoqchi bo'lsangiz, ushbu qo'llanma siz uchun juda mos keladi.

Btw men Ethereum ishlab chiqaruvchisi bo'lishning eng muhim tushunchalarini o'rganadigan qattiqlikni noldan o'rganish uchun Ethereum rivojlanishi haqida kitob yozdim. Bizni cheksiz bepul olish uchun bu erda tekshirib ko'ring: https://www.amazon.com/dp/B07BJB1YNQ

Siz shuningdek uni mening veb-saytimdan 20 AQSh dollari miqdorida PDF-da olishingiz mumkin: https://merunas.io/book

Mana biz foydalanmoqchi bo'lgan texnologiyalar:

  • Ma'lumotlar bazasi: Ethereumning Testnet Ropsten blockchain.
  • Hosting: markazlashtirilmagan platformada abadiy bepul hostingni olish uchun IPFS.
  • Frontend: veb-paket bilan reakt.js. Men eng muhim bosqichlarni tushuntirib beraman, deb qo'rqmang. Siz xohlagan ramka yoki oddiy javascript-dan foydalanishingiz mumkin.
  • Domen nomi: Godaddy. Bu erda men noma'lum markazlashtirilgan domen xizmatidan foydalanishim mumkin edi, ammo godaddy yoki boshqa biron bir domen ro'yxatga oluvchisida bu juda tez va osonroq.
  • Shartnomani dasturlash tili: Qattiqlik 0.4.11, hozirgi paytda Smart shartnomalarni ishlab chiqish uchun eng mashhur til.
  • Ushbu kontraktlarni veb-foydalanuvchi interfeysida ishlatish uchun frontend shartnomalari: web3.js.
  • Frameeworks: bizning shartnomalarimizni o'rnatish, sinovdan o'tkazish va tuzish uchun murakkabliklar.
  • Ishlab chiqish serveri: Node.js-ni testrpc bilan birga mahalliy dasturni ishlab chiqishda ishlatish uchun.
  • Metamask: oxirgi dastur kabi oxirgi dasturni ishlatish.

Va biz quyidagi qadamlarni tashlaymiz:

  1. Loyihani sozlash
  2. Barqarorlik shartnomalarini dasturlash
  3. Frontend dasturini yarating
  4. Ilovani IPFS orqali onlayn ravishda joylashtiring
  5. Ilova uchun maxsus domendan foydalaning
  6. Yakuniy Dapp bilan o'ynang!

1. Loyihani sozlash

Sizga nimani yaratmoqchi ekanligimizni tushuntirib beraman, shunda siz natijani aniq tasavvur qilasiz.

Biz 1 dan 10 gacha bo'lgan raqamlarga pul tikish imkoniga ega bo'lgan ilova kabi kazino yaratmoqchimiz va agar ular to'g'ri bo'lsa, ular 100 ta pul tikishdan keyin qolgan barcha eter pullarining bir qismini yutib oladilar.

Ishni boshlash juda murakkab, ammo uni ishlatish yoqimli va yoqimli bo'lgani uchun sizga yoqadi.

Endi sizni ogohlantirishim kerakki, bu xavfsiz dastur emas, chunki siz qattiqlik bilan tasodifiylikni yaratolmaysiz. Siz blockchain-da turli xil tasodifiy yaratish usullarini sinab ko‘rishingiz va nima ishlayotganini ko‘rishingiz kerak.

Boshlang'ichni yaratish jarayonini boshidan oxirigacha ko'rish uchun ushbu qo'llanmani kirish sifatida oling.

Birinchidan, node.js-ning hozirgi versiyasini nodejs.org veb-saytidan yuklab oling, agar sizda hozirda node bo'lmasa. Keyin, kompyuteringiz ish stolida kazino-ethereum nomli papkani yarating. Ichkarida terminal yoki buyruq satrini oching va buyruqni bajaring: npm init -y

Shundan so'ng:

npm i -D -g truffle

Ushbu loyihada Ethereum rivojlanish doirasi Truffle-ni rivojlanayotgan qaramlik (-D) va global (-g) sifatida o'rnatish.

Keyin bajaring:

ngm tashabb -y
truffle tashabb

Ushbu 2 buyruqlar loyihani rivojlantirish uchun zarur fayllarni yaratib, loyihani boshlaydi.

Shundan so'ng:

npm i -D veb-to'plami reaktsiya-dom babel yadrosi-babel-loader babel-preset-reaktiv babel-preset-env css-loader style-loader json-loader web3@0.20.0

Bularning barchasi biz devning oldingi uchini yaratish uchun kerak bo'lgan vositalar. Ko'p bog'liqliklar mavjud, chunki biz javascript va React.jslarning so'nggi versiyalari bilan veb-dastur yaratamiz.

Biz asosan veb-paketni o'rnatdik, reaksiya, babel va web3.

E'tibor bering, biz web3 ning 0.20.0 versiyasini web3@0.20.0 bilan o'rnatmoqdamiz, chunki web3 ning so'nggi versiyasi, 1.0 hali beta-versiyada va u beqaror.

Keyin npm i -g http-serverini o'rnating. Veb-ilovangizni mahalliy serverga joylashtirish uchun foydalanadigan engil server: localhost-da: 8080.

Endi siz ushbu loyihani reaktsiya va veb-paket yordamida yaratishingiz kerak bo'lgan barcha bog'liqliklarga egasiz.

Shundan so'ng, sizning loyiha papkangizga o'ting va webpack.config.js faylini yarating. Bu barcha javascript va css-larimizni birlashtiradigan va build.js deb nomlangan bitta faylni yangi va eski brauzerlar bilan ishlashga moslashtirilgan barcha js kod bilan birlashtiradigan fayl. Shunday qilib, biz eng so'nggi javacriptning hali e'lon qilinmagan xususiyatlaridan foydalanishimiz mumkin.

Endi ushbu kodni fayl ichiga yozing:

const path = zarur ('yo'l')
modul.exports = {
   kirish: path.join (__ dirname, 'src / js', 'index.js'), // Bizning old src papkasida bo'ladi.
   chiqish: {
      yo'l: path.join (__ dirname, "dist"),
      fayl nomi: 'build.js' // Yakuniy fayl dist / build.js-da yaratiladi
   },
   modul: {
      qoidalar: [{
         test: /\.css$/, // CSSni reaktsiyaga yuklash uchun
         foydalanish: ['style-loader', 'css-loader'],
         o'z ichiga oladi: / src /
      }, {
         test: /\.jsx?$/, // js va jsx fayllarini yuklash uchun
         yuklovchi: 'babel loader',
         chiqarib tashlash: / node_modules /,
         so'rov: {
            oldindan sozlash: ['es2015', 'reaksiya', 'bosqich-2']
         }
      }]
   }
}

Shundan so'ng, loyihada src / papkani yarating va ushbu papkaning ichida js / va css / faqat papkalarni yarating, shunchaki boshlang'ich kodni tartibga solish kerak.

Har bir papkaning ichida index.js va index.css yarating.

Va nihoyat dist / tashqi darajadagi va index.html ichidagi papkani yarating.

Tuzilma quyidagicha bo'ladi:

shartnomalar /
- Migratsiya.sol
migratsiya /
tugun_modullari /
sinov /
src /
- css / index.css
- js / index.js
dist /
- indeks.html
paket.json
truffle-config.js
truffle.js
veb-sahifasi.config.js

Endi index.html-ga o'ting va ushbu kodni qo'lda yozing:




   
   
   
    Casino Ethereum Dapp 


   
   

Ushbu kodning asosiy jihatlari shundaki, matnni yaxshi ko'rinishga ega bo'lish uchun Open sans shriftini qo'shdim, reaktsiya kodi kiritiladigan

va veb-paketda yaratilgan faylni qo'shish uchun.

Shartnoma / Casino.sol faylini yarating, bu keyingi qismda kodlashimiz kerak bo'lgan asosiy mustahkamlik shartnomasi.

Bularning barchasini tayyorlab bo'lgach, biz nihoyat dasturni yaratishni boshlashimiz mumkin!

2. Barqarorlik shartnomalarini dasturlash

Ushbu bo'limda siz loyihaning asosiy shartnomasini yozasiz va uni kimdir haqiqiy pulni yo'qotishiga olib keladigan zaif kodni ishlatmaslik uchun to'g'ri ishlayotganligini tekshirasiz.

Birinchidan, har bir qattiqlik shartnomasi kompilyator versiyasidan boshlanishi kerak, shuning uchun buni siz yaratgan Casino.sol faylining yuqori qismida yozing:

pragma mustahkamligi 0.4.20;

Endi shartnoma tuzing:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   funktsiya Casino () public {
      egasi = msg.sender;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
}
  • O'zgaruvchi deb nomlangan manzilning egasi sizning Metamask hisob qaydnomangizdagi uzun satr, mening holda bu 0x08f96d0f5C9086d7f6b59F9310532BdDCcF536e2.
  • Casino () funktsiyasi konstruktor bo'lib xizmat qiladi, chunki u shartnoma bilan bir xil nomga ega va biz ushbu shartnoma egasini belgilash uchun foydalanamiz. Ushbu shartnomani yaratgan foydalanuvchi manzili egasi.
  • Kill () funktsiyasi shartnomani xohlaganingizda yo'q qilish uchun ishlatiladi. Albatta uni faqat egasi o'ldirishi mumkin. Shartnoma saqlangan qolgan efirlar egasining manziliga yuboriladi. Faqatgina shartnoma buzilgan bo'lsa va uni kafolatlay olmasangiz, undan foydalaning.

Esingizda bo'lsin, maqsad quyidagilardan iborat:

Ilovalar kabi kazino yarating, unda foydalanuvchilar 1 dan 10 gacha bo'lgan raqamlarga pul tikish imkoniga ega bo'ladilar va agar ular to'g'ri bo'lsa, ular 100 ta pul tikgandan keyin qo'yilgan barcha eter pullarining bir qismini yutadilar.

Shunday qilib, biz quyidagi vazifalarni bajarishimiz kerak:

  • Foydalanuvchi qancha raqam uchun qancha pul tikishini yozib oling.
  • Garovning minimal narxi.
  • Birlashtirilgan eterlarning umumiy miqdori.
  • Qancha tikish mavjudligini saqlash uchun o'zgaruvchan.
  • Gamblingni qachon to'xtatish va yutgan raqamni aniqlash kerak.
  • Har bir g'olib uchun yutilgan eter miqdorini yuborish funktsiyasi.

Bu funktsiyalar:

  • Bir qator uchun pul tikish.
  • G'olib sifatida tasodifiy raqamni yarating.
  • G'oliblarga efirni yuboring.

Foydalanuvchi qancha raqam uchun qancha pul tikishini yozib oling.

Ob'ektga o'xshash javascript-da biz foydalanuvchining manzilini, miqdor tikish va raqamni saqlash uchun biz o'zgaruvchining xaritalash turi bilan tuzilishdan foydalanishimiz mumkin.

Tuzilma javascript-dagi ob'ektga o'xshaydi, amapping esa massivga o'xshaydi.

Kod bilan boraylik:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   uint256 public minimumBet;
   uint256 jamoat totalBet;
   uint256 jamoat raqamiOfBets;
   uint256 umumiy maxAmountOfBets = 100;
   manzil [] ommaviy o'yinchilar;
   tizim pleeri {
      uint256 miqdoriBet;
      uint256 raqamiTanlangan;
   }
   // pleer manzili va => foydalanuvchi ma'lumotlari
   xaritalash (manzil => pleer) public playerInfo;
   funktsiya Casino () public {
      egasi = msg.sender;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
}

Player deb nomlangan tuzilma miqdori va tanlangan raqamdan iboratdir, chunki biz foydalanuvchi qancha efir va qancha raqamga pul tikishini nazorat qilishni istaymiz.

So'ngra biz bu pleerInfo [here_goes_his_address] .amountBiz kabi xususiyatlarni bajarish uchun PlayerInfo deb nomlangan xaritani yaratamiz, bu erda biz uning xususiyatlariga kirish uchun javascript ob'ektidagi "kalit" sifatida manzildan foydalanishimiz mumkin.

G'oliblarga mukofotlarni tarqatish uchun kim o'yin o'ynayotganini bilish uchun bizda ko'plab o'yinchilar bo'lishini istaymiz.

O'yin uchun minimal tikish miqdorini aniqlash uchun konstruktorni o'zgartiring, shunda siz sovrinlarni taqsimlash uchun o'zgaruvchan minimal harajatlarni tanlashingiz mumkin:

funktsiya Casino (uint256 _minimumBet) {
   egasi = msg.sender;
   agar (_minimumBet! = 0) minimumBet = _minimumBet;
}

Endi shartnoma oxirida 1 dan 10 gacha bo'lgan raqamlarga pul tikish uchun funktsiyani yarating, ikkalasini ham qo'shgan holda:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   uint256 public minimumBet;
   uint256 jamoat totalBet;
   uint256 jamoat raqamiOfBets;
   uint256 umumiy maxAmountOfBets = 100;
   manzil [] ommaviy o'yinchilar;
   tizim pleeri {
      uint256 miqdoriBet;
      uint256 raqamiTanlangan;
   }
   // pleer manzili va => foydalanuvchi ma'lumotlari
   xaritalash (manzil => pleer) public playerInfo;
   Casino (uint256 _minimumBet) ommaviy {
      egasi = msg.sender;
      agar (_minimumBet! = 0) minimumBet = _minimumBet;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
   // ikkalasini ham hisobga olgan holda 1 dan 10 gacha bo'lgan raqamlar uchun pul tikish
   umumiy pullik funktsiyasi (uint256 numberSelected) umumiy pullik {
      talab qilish (! checkPlayerExists (msg.sender));
      talab qilish (numberSelected> = 1 && numberSelected <= 10);
      talab qilish (msg.value> = minimumBet);
      playerInfo [msg.sender] .amountBet = msg.value;
      playerInfo [msg.sender] .numberSelected = numberSelected;
      numberOfBets ++;
      games.push (msg.sender);
      totalBet + = msg.value;
   }
}
  • To'lanadigan so'z bu modifikator bo'lib, uni bajarishda eterni qabul qilish mumkinligini anglatadi.
  • Talab () funktsiyasi haqiqiylikni qaytarishi kerak bo'lgan if kabi. Agar talab ichidagi holat "noto'g'ri" deb baholansa, funktsiya to'xtaydi va to'langan "efir" jo'natuvchiga qaytariladi. Biz buni o'yinchi allaqachon o'ynaganligini, raqam chegaralanganligini va to'langan pul miqdori minimal pul miqdoriga teng yoki teng ekanligini tekshirish uchun foydalanamiz.
  • msgstr.sender va msg.value bu foydalanuvchi shartnomani bajarayotganda belgilaydigan qiymatlardir. Yuboruvchi uning manzili va qiymati bu to'lov funktsiyasini bajarayotganda to'langan eter miqdoridir.
  • Keyin biz ushbu foydalanuvchi uchun PlayerInfo [msg.sender] .amountBet = msg.sender; bilan o'ynagan pul miqdorini aniqlaymiz. msg.sender bu funktsiyani bajargan foydalanuvchining manzili.
  • Keyin bizOfBets sonini 1 ga ko'paytiramiz. Ushbu o'zgaruvchi 100 o'yin mavjud bo'lganda uni to'xtatish va mukofotlarni tarqatish uchun qancha o'yin tikilishini ko'rish uchun ishlatiladigan hisoblagich.
  • Va nihoyat, biz g'oliblarga tarqatiladigan ushbu o'yin uchun totalAmount pul tikamiz.

Siz ko'rishingiz mumkin, birinchi talab qilingan bu funktsiya bayoni:

talab qilish (! checkPlayerExists (msg.sender));

Men foydalanuvchi allaqachon o'ynamaganligini tekshirish uchun checkPlayerExists () funktsiyasini taklif qilaman, chunki biz har bir kishi bitta o'yinda bir marta o'ynashini xohlaymiz. Funktsiya hali mavjud emas. Endi uni yarataylik:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   uint256 public minimumBet;
   uint256 jamoat totalBet;
   uint256 jamoat raqamiOfBets;
   uint256 umumiy maxAmountOfBets = 100;
   manzil [] ommaviy o'yinchilar;
   tizim pleeri {
      uint256 miqdoriBet;
      uint256 raqamiTanlangan;
   }
   // pleer manzili va => foydalanuvchi ma'lumotlari
   xaritalash (manzil => pleer) public playerInfo;
   Casino (uint256 _minimumBet) ommaviy {
      egasi = msg.sender;
      agar (_minimumBet! = 0) minimumBet = _minimumBet;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
   funktsiya checkPlayerExists (manzil pleer) public doimiy return (bool) {
      for (uint256 i = 0; i 
   // ikkalasini ham hisobga olgan holda 1 dan 10 gacha bo'lgan raqamlar uchun pul tikish
   umumiy pullik funktsiyasi (uint256 numberSelected) umumiy pullik {
      talab qilish (! checkPlayerExists (msg.sender));
      talab qilish (numberSelected> = 1 && numberSelected <= 10);
      talab qilish (msg.value> = minimumBet);
      playerInfo [msg.sender] .amountBet = msg.value;
      playerInfo [msg.sender] .numberSelected = numberSelected;
      numberOfBets ++;
      games.push (msg.sender);
      totalBet + = msg.value;
   }
}

Funktsiyaning doimiy kalit so'zi, bu hech qanday gazni sarf qilmaydigan funktsiyani anglatadi, chunki u blockchain-dan allaqachon mavjud bo'lgan qiymatni qaytarib beradi. Bu qiymatni o'qish. Shuning uchun bu bepul.

Ushbu ajoyib funktsiyalarni yaratgandan so'ng, biz g'olib raqamini olishimiz uchun tikish soni kattaligini yoki maksimal darajaga tengligini tekshirishimiz kerak. Chunki 99 ta pul tikilgan taqdirda biz keyingi tikish, 100 raqami, narxlarni chiqaramiz va kerakli hisob-kitoblarni amalga oshiramiz. Uni olish?

Ajoyib, buni shu maqsadda tikish () funktsiyasining oxirida qo'shing:

if (numberOfBets> = maxAmountOfBets) generateNumberWinner ();

Endi biz g'olibni aniqlash uchun tasodifiy 1 dan 10 gacha bo'lgan raqamni yaratadigan generateNumberWinner () funktsiyasini yaratishimiz kerak:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   uint256 public minimumBet;
   uint256 jamoat totalBet;
   uint256 jamoat raqamiOfBets;
   uint256 umumiy maxAmountOfBets = 100;
   manzil [] ommaviy o'yinchilar;
   tizim pleeri {
      uint256 miqdoriBet;
      uint256 raqamiTanlangan;
   }
   // pleer manzili va => foydalanuvchi ma'lumotlari
   xaritalash (manzil => pleer) public playerInfo;
   Casino (uint256 _minimumBet) ommaviy {
      egasi = msg.sender;
      agar (_minimumBet! = 0) minimumBet = _minimumBet;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
   funktsiya checkPlayerExists (manzil pleer) public doimiy return (bool) {
      for (uint256 i = 0; i 
   // ikkalasini ham hisobga olgan holda 1 dan 10 gacha bo'lgan raqamlar uchun pul tikish
   umumiy pullik funktsiyasi (uint256 numberSelected) umumiy pullik {
      talab qilish (! checkPlayerExists (msg.sender));
      talab qilish (numberSelected> = 1 && numberSelected <= 10);
      talab qilish (msg.value> = minimumBet);
      playerInfo [msg.sender] .amountBet = msg.value;
      playerInfo [msg.sender] .numberSelected = numberSelected;
      numberOfBets ++;
      games.push (msg.sender);
      totalBet + = msg.value;
   }
   // G'olib bo'lgan 1 dan 10 gacha bo'lgan raqamni yaratadi
   funktsiya generateNumberWinner () public {
      uint256 numberGenerated = block.number% 10 + 1; // Bu xavfsiz emas
      DistributePrizes (numberGenerated);
   }
}

U hozirgi blok raqamini oladi va oxirgi raqamni oladi + 1, agar blok raqami 128142 bo'lsa, hosil bo'lgan raqam 128142% 10 = 2 va 2 +1 = 3 bo'ladi.

Bu xavfsiz emas, chunki sharoitga qarab qaysi raqam g'olib bo'lishini bilish oson. Konchilar o'z manfaati uchun blok raqamini ko'rishga qaror qilishlari mumkin.

Keyin biz g'oliblarga mukofotlarni distributivPrays (numberGenerated) funktsiyasi bilan tarqatamiz:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   uint256 public minimumBet;
   uint256 jamoat totalBet;
   uint256 jamoat raqamiOfBets;
   uint256 umumiy maxAmountOfBets = 100;
   manzil [] ommaviy o'yinchilar;
   tizim pleeri {
      uint256 miqdoriBet;
      uint256 raqamiTanlangan;
   }
   // pleer manzili va => foydalanuvchi ma'lumotlari
   xaritalash (manzil => pleer) public playerInfo;
   Casino (uint256 _minimumBet) ommaviy {
      egasi = msg.sender;
      agar (_minimumBet! = 0) minimumBet = _minimumBet;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
   funktsiya checkPlayerExists (manzil pleer) public doimiy return (bool) {
      for (uint256 i = 0; i 
   // ikkalasini ham hisobga olgan holda 1 dan 10 gacha bo'lgan raqamlar uchun pul tikish
   umumiy pullik funktsiyasi (uint256 numberSelected) umumiy pullik {
      talab qilish (! checkPlayerExists (msg.sender));
      talab qilish (numberSelected> = 1 && numberSelected <= 10);
      talab qilish (msg.value> = minimumBet);
      playerInfo [msg.sender] .amountBet = msg.value;
      playerInfo [msg.sender] .numberSelected = numberSelected;
      numberOfBets ++;
      games.push (msg.sender);
      totalBet + = msg.value;
   }
   // G'olib bo'lgan 1 dan 10 gacha bo'lgan raqamni yaratadi
   funktsiya generateNumberWinner () public {
      uint256 numberGenerated = block.number% 10 + 1; // Bu xavfsiz emas
      DistributePrizes (numberGenerated);
   }
   // Har bir g'olibga umumiy tikish soniga qarab tegishli efirni yuboradi
   funktsiya distributiviPrizes (uint256 numberWinner) public {
      manzil [100] xotira g'oliblari; // Ruxsat etilgan o'lchamlarga ega bo'lgan vaqtinchalik xotira qatorini yaratishimiz kerak
      uint256 soni = 0; // Bu g'oliblar qatorini hisoblash
      for (uint256 i = 0; i 
      futbolchilar.length = 0; // Barcha pleyerlar qatorini o'chirish
      uint256 G'olibEtherAmount = totalBet / G'oliblar.length; // Har bir g'olib qancha yutadi
      uchun (uint256 j = 0; j 

Ushbu funktsiya quyidagilarni bajaradi:

  1. Birinchidan, g'olib deb nomlangan g'oliblar qatorini o'yinchining tanlangan raqami - tanlangan Wininner-ni tekshirish orqali hosil qiladi. G'oliblar qatori - bu funktsiyani bajargandan so'ng o'chiriladigan xotira massivi. U belgilangan o'lchamga ega bo'lishi kerak.
  2. Keyin u har bir g'olib olgan eter miqdorini hisobning umumiy miqdori va g'oliblarning miqdoriga qarab hisoblab chiqadi. G'olib qancha kam bo'lsa, mukofot shunchalik katta bo'ladi.
  3. Keyin u har bir g'olib uchun mos keladigan miqdordagi efirni [j] .transfer g'oliblari bilan yuboradi.

Bu shunday bo'lishi kerak. Endi bizda oddiy kazino sifatida o'ynashga imkon beradigan ish shartnomasi mavjud.

Men qilishim kerak bo'lgan oxirgi narsa bu anonim zaxira funktsiyasini yaratish, nomini o'zgartirmaydigan funktsiyani yaratish, agar u biron bir funktsiyani bajarmasdan shartnomaga efirni yuborganingizda bajariladigan bo'lsa, u to'lanadi.

// Agar kimdir shartnomaga efirni yuborib, uni yo'qotib qo'ymasa va har bir o'yinda taqsimlanadigan ushbu shartnomaning xazinasini oshiradigan bo'lsa, qaytarib yuborish funktsiyasi.
   funktsiya () umumiy to'lanadigan {}

Bu sizga shartnomaga yuborgan eteringizni tejashga imkon beradi. Aks holda rad qilinadi.

Bu siz tuzgan to'liq shartnoma:

pragma mustahkamligi 0.4.20;
shartnoma Casino {
   davlat egasining manzili;
   uint256 public minimumBet;
   uint256 jamoat totalBet;
   uint256 jamoat raqamiOfBets;
   uint256 umumiy maxAmountOfBets = 100;
   manzil [] ommaviy o'yinchilar;
   tizim pleeri {
      uint256 miqdoriBet;
      uint256 raqamiTanlangan;
   }
   // pleer manzili va => foydalanuvchi ma'lumotlari
   xaritalash (manzil => pleer) public playerInfo;
   funktsiya () umumiy to'lanadigan {}
   Casino (uint256 _minimumBet) ommaviy {
      egasi = msg.sender;
      agar (_minimumBet! = 0) minimumBet = _minimumBet;
   }
   funktsiya kill () public {
      if (msg.sender == egasi) o'zini o'zi yo'q qilish (egasi);
   }
   funktsiya checkPlayerExists (manzil pleer) public doimiy return (bool) {
      for (uint256 i = 0; i 
   // ikkalasini ham hisobga olgan holda 1 dan 10 gacha bo'lgan raqamlar uchun pul tikish
   umumiy pullik funktsiyasi (uint256 numberSelected) umumiy pullik {
      talab qilish (! checkPlayerExists (msg.sender));
      talab qilish (numberSelected> = 1 && numberSelected <= 10);
      talab qilish (msg.value> = minimumBet);
      playerInfo [msg.sender] .amountBet = msg.value;
      playerInfo [msg.sender] .numberSelected = numberSelected;
      numberOfBets ++;
      games.push (msg.sender);
      totalBet + = msg.value;
   }
   // G'olib bo'lgan 1 dan 10 gacha bo'lgan raqamni yaratadi
   funktsiya generateNumberWinner () public {
      uint256 numberGenerated = block.number% 10 + 1; // Bu xavfsiz emas
      DistributePrizes (numberGenerated);
   }
   // Har bir g'olibga umumiy tikish soniga qarab tegishli efirni yuboradi
   funktsiya distributiviPrizes (uint256 numberWinner) public {
      manzil [100] xotira g'oliblari; // Ruxsat etilgan o'lchamlarga ega bo'lgan vaqtinchalik xotira qatorini yaratishimiz kerak
      uint256 soni = 0; // Bu g'oliblar qatorini hisoblash
      for (uint256 i = 0; i 
      futbolchilar.length = 0; // Barcha pleyerlar qatorini o'chirish
      uint256 G'olibEtherAmount = totalBet / G'oliblar.length; // Har bir g'olib qancha yutadi
      uchun (uint256 j = 0; j 

Siz to'liq va yangilangan shartnomani mening github-da ko'rishingiz mumkin https://github.com/merlox/casino-ethereum, shartnomalar papkasida. Bu xavfsiz tasodifiy sonlarni yaratish uchun oraclize bilan jihozlangan zamonaviy versiya.

Shartnoma tugagandan so'ng bizda ikkita variant mavjud:

  • Truffuff yordamida testlarni yozing va ushbu sinovlar davomida shartnomani testrpc-ga joylashtiring.
  • Solidlik IDE https://remix.ethereum.org yordamida kontraktni qo'lda sinab ko'ring. Bu shartnomalarni yozish, sinash va joylashtirishning rasmiy vositasidir.

Men ushbu maqolani juda uzoq vaqt davomida yozishni xohlamasligim sababli, biz shartnomani tezda sinab ko'rish uchun IDE remix-dan foydalanamiz, ammo siz ilovalaringiz kutilganidek ishlayotganini va yangilanganingizda har safar xavfsizligini ta'minlash uchun truffle bilan testlarni bajarishingiz kerak.

Davom etishdan oldin metamask.io-ni ushbu havoladan yuklab olishingiz kerak. Bu brauzeringizda Smart kontraktlarni bajarish uchun ishlatiladigan vositadir, shuningdek Ethereum hamyonida.

O'rnatgandan so'ng, uni oching, amallarni bajaring va qayd yozuvini yarating. 12 so'zli kalit so'zni saqlashga ishonch hosil qiling, chunki bu parol yoki shaxsiy kalitni unutganingizda hisobni tiklashning yagona usuli. Siz shunga o'xshash narsani ko'rishingiz kerak:

Hey! Bu chap tomonda

Endi sizda metamaskda hisob qaydnomangiz bor va undan dpps va Smart Contracts bilan ishlashda foydalanishingiz mumkin.

Shunday qilib, Remix IDE-ga o'ting va shartnomani joylashtiring:

Bu remix ideasi

Bu biz IDE remiksida qiladigan ishlarimiz:

  • Shartnomani Testnet Ropsten Blockchain-ga, eterning haqiqiy qiymati bo'lmagan blokchainga topshiring.
  • Metamaskadan foydalanib, har bir funktsiyaning gazini to'lash kerak.
  • Barcha funktsiyalar kutilganidek ishlashiga ishonch hosil qiling.

Sizda ikkita panel mavjud, chapda sizning kodingiz va o'ng tomonda, u erda siz ushbu shartnoma bilan qiziqarli narsalarni qilishingiz mumkin.

O'ng panelda "Ishga tushirish" yorlig'ini bosing:

Ko'rishingiz kerak qizil tugma, uint256 _minimumBet deb, to'ldiruvchisi bo'lgan kirish maydoni bilan yarating. Bu konstruktorning minimal garovi. Siz uni bo'sh qoldirishingiz yoki raqam yozishingiz mumkin.

Endi Metamask kengaytmasini oching va tarmog'ingizni rasmdagi kabi Ropsten Testnet Network-ga o'zgartiring.

Keyin https://faucet.metamask.io/ saytiga o'ting va 1 bepul efirni so'rang. Müslüm, bu sizning Ropsten hisobingiz uchun efir olishingiz mumkin bo'lgan joy.

Biroz vaqt o'tgach, sizning qayd yozuvingizda bir qancha miqdorda eterlar borligini ko'rasiz.

Remix IDE-ga o'ting va atrof-muhitda ekanligingizga ishonch hosil qiling: AOK qilingan veb-3:

Bu siz Metamaskdan kiritilgan blockchain-dan foydalanayotganingizni anglatadi. Endi shartnomani o'rnatish uchun Yaratish-ni bosing, metamaskadan bildirishnoma oynasini ko'rasiz:

Joylashtirish uchun to'lovni amalga oshirish uchun "Yuborish" ni bosing va siz tugallandingiz, shartnomangiz Ropsten tarmog'ida jonli.

Agar biron sababga ko'ra muhitni o'zgartira olmasangiz yoki bildirishnoma oynasini ko'rmasangiz, Chrome dasturiy vositalarini ochish uchun F12 tugmachasini bosing. Qayta yuklash tugmachasini bosing va ushlab turing va oxirgi variantni tanlang:

Keshni bo'shating va sahifani qayta yuklang

Bu xatolarni tuzatishi kerak.

Shartnomani o'rnatganingizdan so'ng, siz o'ng tomonda kontraktning manzili, funktsiyalari va boshqa qiziqarli ma'lumotlarni ko'rasiz.

Shunga o'xshash narsa:

Yuqoridagi qismida tugmachasi bor, undan keyin foydalanish uchun shartnomaning manzilini saqlash uchun foydalanishingiz mumkin. Shunchaki bosing va manzilni biron bir joyga saqlang.

Keyin, ko'k tugmalar doimiy yoki umumiy funktsiyalar va o'zgaruvchilar. Agar uint256 public totalBet kabi umumiy o'zgaruvchini e'lon qilsangiz; bu qiymatga istalgan vaqtda kirishingiz mumkin, chunki u ommaviy.

Aytishingiz mumkinki, u avtomatik ravishda olish usuliga ega.

Keyin doimiy funktsiyalar qiymatni qaytaradigan va shartnomaning holatini o'zgartirmaydigan funktsiyalardir. Bu shuni anglatadiki, ular kontrakt o'zgaruvchilarini o'zgartirmaydilar, shunchaki bajaradilar va sizga natija beradilar.

Vazifalarni birin-ketin bajarishdan boshlaylik.

Agar siz minimumBet-ni cheritsangiz, darhol o'sha o'zgaruvchining qiymatini olasiz, chunki u ommaviydir:

Mening holatimda bu miqdor, chunki men shartnomani tuzishda uni konstruktorga o'rnatdim

Ueyda uint256: 1000000000000000 ni qaytaradi, bu 0,1 efir. Esingizda bo'lsin, siz Eterdan emas, Veydan foydalangan holda aloqada bo'lasiz.

Keyingi, qizil tugmalar - bu blockchain-ga qiymatlarni tejaydigan funktsiyalarni bajarish uchun gaz sarflaydiganlar.

Agar siz CheckPlayerExists () funktsiyasi o'qilganligini ko'rsangiz, shartnomani doimiy ravishda o'zgartirishingiz kerak, chunki u qiymatni qaytaradi va asosiy o'zgaruvchilarni o'zgartirmaydi.

Shunday qilib, shartnomani o'zgartirishdan oldin, hozirgi shartnomani yo'q qilishimiz kerak. O'ldirish funktsiyasini bajaring va shartnomani o'zgartiring (agar funktsiya doimiy bo'lsa, buni qilishingiz shart emas, lekin baribir shartnomani o'ldirishga urinib ko'rishingiz mumkin):

funktsiya checkPlayerExists (manzil pleer) doimiy qaytish (bool) {

Qayta joylashtiring va shunda ko'rasiz, CheckPlayerExists tugmasi endi ko'k. Bu shuni anglatadiki, u ishlash uchun gazni iste'mol qilmaydi.

Funktsiya doimiydir, bajarish uchun gaz kerak emas va mantiqiy qiymatni qaytaradi

E'tibor bering, ishlash uchun bayt32 va satr "qo'shtirnoq ichida" bo'lishi kerak. Bu manzilni qo'yishda yuzaga keladigan keng tarqalgan muammo, chunki ular ikki tirnoqli json qiymatlarini talab qiladi.

Tikish funktsiyasi sizga minimal miqdordan kattaroq eter yuborishingiz va 1 dan 10 gacha bo'lgan raqamni tanlashingizni talab qiladi.

Uni sinab ko'rish uchun o'ng ustunning yuqori qismiga o'ting va rasmdagi kabi pulni yuboring:

100 finney 0,1 efirdir, aniq muammolar tufayli siz 0.1 kabi suzuvchi qiymatlarni yoza olmaysiz, shuning uchun biz kichikroq qismdan foydalanamiz

Shartnomada msg.value sifatida mavjud bo'lgan qiymat. Shartnoma uchun o'rnatgan minimumBetdan kattaroq narsani yuboring va pul tikish uchun raqamni yuborib, funktsiyani bajaring.

Agar gaz gaz limiti chegarasidan oshib ketgan deb aytsa, cookie fayllarini o'chirib tashlagan sahifani sizlarga ilgari aytganimdek yangilang.

Funktsiyalar bilan o'ynaganimdan so'ng, distributiv priznesi () funktsiyasi kontraktdagi barcha o'zgaruvchilarni asl holatiga qaytarmasligini angladim, shunda totalBet va OBBet soni birinchi o'yindan keyin bir xil bo'lib qoldi.

Shunday qilib, men quyidagicha yangi funktsiyani yaratdim:

funktsiya resetData () {
   futbolchilar.length = 0; // Barcha pleyerlar qatorini o'chirish
   totalBet = 0;
   numberOfBets = 0;
}

Va men uni distributiv prizlar () funktsiyasidan chaqirdim. Men ilgari bilmagan mumkin bo'lgan muammoni topdim, bu sinov kuchi!

Endi keyingi qismga o'tishdan oldin, uni keyinchalik oldingi ilovada ishlatish uchun shartnoma tuzaylik.

Ko'chirish papkasida 2_deploy_contracts.js faylini yarating. Ushbu faylda siz kontrakt tuzuvchi olgan qiymatlarni o'rnatasiz, mening holda:

var Casino = artifaktlar.require ("./ Casino.sol");
module.exports = funktsiya (tarqatuvchi) {
  tarqatuvchini.deploy (web3.toWei (0.1, 'efir'), 100, {gaz: 3000000});
};

Izoh:

  • Avval biz Casino.sol shartnomasini talab qilamiz.
  • Keyin .deploy () usulida biz minimal garovni aniqlaymiz, bu holda 0,1 eter ushbu funktsiya bilan Wei ga aylantiriladi.
  • 100 - bu maksimal miqdordagi o'yinchi.
  • Nihoyat, shartnomani tuzish uchun foydalanishga tayyor bo'lgan gaz limiti.

Shundan so'ng, sizning loyihangiz papkasiga o'ting va buyruq truffle kompilyatsiyasini bajaring. Bu shartnoma haqida barcha kerakli ma'lumotlarni o'z ichiga olgan json faylini yaratadi.

Biz ushbu ma'lumotlardan foydalanmaymiz, lekin shunchaki truffle ramkasini ishlatganingizda bilasiz. Bu sizga Remix IDE-dan foydalanish o'rniga buyruq satridan hamma narsani joylashtirish va sinashga yordam beradi.

Sinov tugagandan so'ng, darslikning keyingi qismini davom ettiring.

3. Frontend dasturini yarating

Reaksiya bilan dastur yaratish uchun index.js faylini ochib boshlang:

'reaktsiya' dan reaktsiya
ReactDOM-ni 'реак-dom' -dan import qilish
"veb3" dan Web3-ni import qilish
import './../css/index.css'
sinf ilovasi React.Componentni kengaytiradi {
   quruvchi (rekvizit) {
      super (rekvizitlar)
      this.state = {
         so'nggi g'olib: 0,
         taymer: 0
      }
   }
ovoz raqami (soni) {
      konsol.log (raqam)
   }
render () {
      qaytish (
         
            

O'zingizning eng yaxshi raqamingizga ega bo'ling va ko'p miqdordagi Eter yutib oling

               

Taymer:

& nbsp;                 {this.state.timer}             
               

So'nggi g'olib:

& nbsp;                 {this.state.lastWinner}             

Keyingi raqam uchun ovoz bering

            
                   
  • {this.voteNumber (1)}}> 1
  •                
  • {this.voteNumber (2)}}> 2
  •                
  • {this.voteNumber (3)}}> 3
  •                
  • {this.voteNumber (4)}}> 4
  •                
  • {this.voteNumber (5)}}> 5
  •                
  • {this.voteNumber (6)}}> 6
  •                
  • {this.voteNumber (7)}}> 7
  •                
  • {this.voteNumber (8)}}> 8
  •                
  • {this.voteNumber (9)}}> 9
  •                
  • {this.voteNumber (10)}}> 10
  •             
         
      )    } }
ReactDOM.render (
   ,
   document.querySelector ('# ildiz')
)

Bu asosiy tuzilma faqat reaktsiya bilan, men nima qildim:

  • Avval reaksiya, reaktivlik, css va web3-ni olib keldim, chunki biz aynan shu narsadan foydalanamiz.
  • Keyin men hujjatning asosiy ko'rinishini yaratish uchun foydalanadigan komponentini yaratdim.
  • Va nihoyat men shartnomaga ovoz berish uchun foydalanadigan ovozli raqam (raqam) usulini yaratuvchini yaratdim va render () usulida asosiy html-ni onClick voqealari bilan qo'shdim.

Agar siz reaktsiyaga yangi bo'lsangiz, sizga shunchaki kodni qo'lda nusxalashni yoki javascript-dagi voqealar bilan oddiy html veb-saytini yaratishni maslahat beraman.

Bu erda css:

tanasi {
    shriftlar oilasi: 'open sans';
    chegarasi: 0;
}
ul {
    list-style-type: yo'q;
    padding-chap: 0;
    displey: egiluvchan;
}
li {
    to'ldirish: 40px;
    chegara: 2px qattiq rgb (30,134,255);
    chegara-o'ng: 5px;
    chegara-radius: 10px;
    kursor: ko'rsatgich;
}
li: hover {
    fon rangi: rgb (30,134,255);
    rang: oq;
}
li: faol {
    shaffoflik: 0,7;
}
* {
   rang: # 444444;
}
.main-konteyner {
   to'ldirish: 20px;
}
.block {
   displey: egiluvchan;
   align-items: markaz;
}
.ko‘rsatilgan tanlangan {
   fon rangi: rgb (30,134,255);
   rang: oq;
}
.bet-input {
   to'ldirish: 15px;
   chegara-radius: 10px;
   chegara: 1px qattiq engil;
   shrift hajmi: 15pt;
   chegarasi: 0 10px;
}

Birlashtirilganda, ilova quyidagicha ko'rinadi:

Endi shartnomaga murojaat qilaylik. Shartnomani tarqatish va ma'lumotlarni olish uchun truffle-dan foydalanishimiz mumkin, ammo buning uchun siz bir necha o'nlab GB bo'lgan butun blockchain-ni yuklab olishingiz kerak edi.

Men hamma uchun ochiq bo'lishini xohlaganim uchun, shunchaki shartnomani Remix IDE-ga taqdim etamiz va ABI-ni manzil bilan olamiz.

Remix.ethereum.org saytiga o'ting va Yaratish tugmachasini bosib shartnomani joylashtiring.

Shartnoma tafsilotlarini oxirida oching:

Keyingi nusxasini ABI interfeysi:

Ikki marta bosish orqali ushbu ulkan kodni o'ng tomonga nusxalash

Keyin sizga index.js-ga o'ting va quyidagi huquqni konstruktorga qo'ying:

quruvchi (rekvizit) {
   super (rekvizitlar)
   this.state = {
      so'nggi g'olib: 0,
      raqamOfBets: 0,
      minimal Bet: 0,
      totalBet: 0,
      maxAmountOfBets: 0,
   }
   if (web3 type! = 'aniqlanmagan') {
      console.log ("Metamask kabi tashqi manbadan aniqlangan web3-dan foydalanish")
      this.web3 = yangi Web3 (web3.currentProvider)
   } else {
      this.web3 = yangi Web3 (yangi Web3.providers.HttpProvider ("http: // localhost: 8545"))
   }
   const MyContract = web3.eth.contract ((bu erda ABI interfeysi ketadi))
   this.state.ContractInstance = MyContract.at ("0x925d81c01d878899adbb7d38f84ce9d5284fa2e7")
}

Mana nima qildim:

  • Avval konstruktorni yarataman va dasturning dastlabki holatini o'rnataman.
  • Keyin men import qilgan Web3 o'zgaruvchisi aniqlangan yoki aniqlanmaganligini tekshiraman. Web3 Metamask kabi yordamchi dasturlar o'zlarining veb3-larini kiritganda aniqlanadi. Aslida, agar siz metamaskadan foydalansangiz, ushbu xabarni chrome dev vositalarida ko'rasiz.
  • Ilova ushbu shartnoma uchun qanday funktsiyalar mavjudligini bilishi uchun men ABI shartnomasini o'rnatdim.
  • Va nihoyat, MyContract.at () bilan shartnomaning manzilini o'rnatdim. Men namunani ShartnomaInstance deb nomlangan mulk sifatida saqladim, lekin bilish kerak bo'lgan narsa bu MyContract.at () misolni qaytarishi.

Remix IDE-da quyidagini bosgan holda shartnoma manzilini oling:

Shartnoma ABI va uning manzili bilan shartnoma vazifalarini oldingi ilovada ishlatishingiz mumkin.

Aytaylik, siz bet () funktsiyasini bajarmoqchisiz, bu holda:

yourContractInstance.bet (7, {
   gaz: 300000,
   dan: web3.eth.accounts [0],
   qiymati: web3.toWei (0.1, 'efir')
}, (xato, natija) => {
   // Natijada - bu funktsiyaning operatsiya manzili
})
  1. Asosan sizning misolingizni oling va funktsiyani bajaring.
  2. Funktsiya parametrlarini yuboring, mening holda 7 bu pul tikish uchun raqam.
  3. Ob'ektni gaz bilan yuborish: va: dan. Qiymat: bu shunchaki shartnomada msg.value-ga kirishingiz uchun foydalanuvchi tikadigan eter miqdoridir.
  4. Nihoyat, xato va natija bilan qayta qo'ng'iroq. Agar biron-bir xato bo'lmasa va xato nol bo'lsa, natija shunchaki bitim manzili, shuning uchun etherscan.io-da qo'ng'iroq qanday amalga oshirilganligini ko'rishingiz mumkin. Ulardan foydalanib, qatl qilinganidan keyin nima sodir bo'lganligi to'g'risida xabarlar paydo bo'lishi kerak.

Siz doimiy funktsiyalar va umumiy o'zgaruvchilar bilan juda o'xshash narsalarni qilasiz. Gaz ishlashi uchun ular xarajat qilmaydilar (katta doimiy funktsiyalardan tashqari), siz ularni quyidagicha bajarishingiz mumkin:

yourContractInstance.maxAmountOfBets ((xato, natija) => {
   agar (natija! = null) // Biror narsa qilish
})

Shunday qilib maxAmountOfBets umumiy o'zgaruvchisini olasiz.

Endi men o'zimning uslubim bilan old tomonning kodini ishlab chiqdim. Bu to'liq kod:

'reaktsiya' dan reaktsiya
ReactDOM-ni 'реак-dom' -dan import qilish
"veb3" dan Web3-ni import qilish
import './../css/index.css'
sinf ilovasi React.Componentni kengaytiradi {
   quruvchi (rekvizit) {
      super (rekvizitlar)
      this.state = {
         so'nggi g'olib: 0,
         raqamOfBets: 0,
         minimal Bet: 0,
         totalBet: 0,
         maxAmountOfBets: 0,
      }
if (web3 type! = 'aniqlanmagan') {
         console.log ("Metamask kabi tashqi manbadan aniqlangan web3-dan foydalanish")
         this.web3 = yangi Web3 (web3.currentProvider)
      } else {
         console.log ("Hech qanday veb-sayt topilmadi. Http: // localhost: 8545-ga qaytib boring. Ushbu nosozlikni jonli efirga uzatganingizda olib tashlashingiz kerak, chunki bu xavfli emas. Ishlab chiqish uchun Metamask-ga o'ting. truffleframework.com/tutorials/truffle-and-metamask ");
         this.web3 = yangi Web3 (yangi Web3.providers.HttpProvider ("http: // localhost: 8545"))
      }
const MyContract = web3.eth.contract ([{"doimiy": noto'g'ri, "kirishlar": [], "nom": "generateNumberWinner", "chiqimlar»: [], "to'lanadigan": noto'g'ri, "turdagi": " funktsiya "}, {" doimiy ": haqiqiy," kirishlar ": []," nom ":" raqamOfBets "," chiqish ": [{" nomi ":" "," turi ":" uint256 "}]," to'lanadigan ": noto'g'ri", "turi": "funktsiya"}, {"doimiy": noto'g'ri, "kirishlar": [{"nomi": "o'yinchi", "turi": "manzil"}], "nom": " checkPlayerExistlar "," chiqishlar ": [{" nomi ":" "," turi ":" bool "}]," to'lanadigan ": noto'g'ri," turdagi ":" funktsiya "}, {" doimiy ": noto'g'ri," kirishlar " ": []," name ":" o'ldirish "," chiqishlar ": []," to'lanadigan ": noto'g'ri," turi ":" funktsiya "}, {" doimiy ": noto'g'ri," kirishlar »: []," nomi ":" resetData "," chiqishlar ": []," to'lanadigan ": noto'g'ri," turdagi ":" funktsiya "}, {" doimiy ": noto'g'ri," kirishlar ": [{" nomi ":" maxBets ", "turi": "uint256"}], "nom": "setMaxAmountOfBets", "chiqishlar": [], "to'lanadigan": noto'g'ri, "turdagi": "funktsiya"}, {"doimiy": noto'g'ri, "kirishlar" : [{"name": "number", "type": "uint256"}], "name": "tikish", "natijalar": [], "to'lanadigan": true, "type": "function"} , {"doimiy": yolg'on, "kirishlar": [], "nom": "tarqatish", "chiqishlar": [], "to'lanadigan": noto'g'ri, "turdagi": "funktsiya"}, {"con stant ": true," inputs ": []," name ":" numberWinner "," outputs ": [{" name ":" "," type ":" uint256 "}]," to'lanadigan ": yolg'on," turi ":" funktsiya "}, {" doimiy ": haqiqiy," kirishlar ": []," nomi ":" minimumBet »,« chiqish »: [{" nomi ":" "," turi ":" uint256 " }], "to'lanadigan": noto'g'ri, "turdagi": "funktsiya"}, {"doimiy": haqiqiy, "kirishlar": [], "nom": "maxAmountOfBets", "chiqishlar": [{"nomi": "", "turi": "uint256"}], "to'lanadigan": noto'g'ri, "turdagi": "funktsiya"}, {"doimiy": to'g'ri, "kirishlar": [{"nomi": "", "turi ":" uint256 "}]," nom ":" o'yinchilar "," chiqishlar ": [{" nomi ":" "," turi ":" manzil "}]," to'lanadigan ": noto'g'ri," turdagi ":" funktsiya "}, {" doimiy ": haqiqiy," kirishlar ": []," nom ":" totalBet "," chiqish ": [{" nomi ":" "," turi ":" uint256 "}]," to'lanadigan ": noto'g'ri", "turi": "funktsiya"}, {"kirishlar": [{"nomi": "_ minimumBet", "turi": "uint256"}, {"nomi": "_ maxAmountOfBets", "turi" : "uint256"}], "to'lanadigan": noto'g'ri, "turi": "konstruktor"}, {"to'lanadigan": haqiqiy, "turi": "zaxira"}])
      this.state.ContractInstance = MyContract.at ("0x7a684de06f473636e03e2d951c78d190eeecb411")
   }
komponentDidMount () {
      this.updateState ()
      this.setupListeners ()
setInterval (this.updateState.bind (bu), 10e3)
   }
updateState () {
      this.state.ContractInstance.minimumBet ((xato, natija) => {
         agar (natija! = null) {
            this.setState ({
               minimumBet: parseFloat (web3.fromWei (natija, "efir"))
            })
         }
      })
      this.state.ContractInstance.totalBet ((xato, natija) => {
         agar (natija! = null) {
            this.setState ({
               totalBet: parseFloat (web3.fromWei (natija, "efir"))
            })
         }
      })
      this.state.ContractInstance.numberOfBets ((xato, natija) => {
         agar (natija! = null) {
            this.setState ({
               numberOfBets: parseInt (natija)
            })
         }
      })
      this.state.ContractInstance.maxAmountOfBets ((xato, natija) => {
         agar (natija! = null) {
            this.setState ({
               maxAmountOfBets: parseInt (natija)
            })
         }
      })
   }
// Voqealarni tinglang va ovozNumber usulini bajaring
   setupListeners () {
      letNodes = this.refs.numbers.querySelectorAll ('li') ga ruxsat bering
      liNodes.forEach (number => {
         number.addEventListener ('cherting', voqea => {
            event.target.className = 'raqam tanlangan'
            this.voteNumber (parseInt (event.target.innerHTML), bajarilgan => {
// Tanlangan boshqa raqamni olib tashlang
               uchun (bo'lsin i = 0; i 
ovoz soni (raqam, cb) {
      let = this.refs ['ether-bet']. qiymatiga ruxsat bering
agar (! tikish) tikish = 0.1
if (parseFloat (tikish)  {
            cb ()
         })
      }
   }
render () {
      qaytish (
         
            

O'zingizning eng yaxshi raqamingizga ega bo'ling va ko'p miqdordagi Eter yutib oling

                Gambling soni: & nbsp;                 {this.state.numberOfBets}             
                G'olibning oxirgi raqami: & nbsp;                 {this.state.lastWinner}             
                Jami efir bahosi: & nbsp;                 {this.state.totalBet} efir             
                Minimal pul tikish: & nbsp;                 {this.state.minimumBet} efir             
                Gamblingning maksimal miqdori: & nbsp;                 {this.state.maxAmountOfBets} efir             

Keyingi raqam uchun ovoz bering


                Eter qancha pul tikmoqchisiz?   efir
               
            
   
                   
  • 1
  •                
  • 2
  •                
  • 3
  •                
  • 4
  •                
  • 5
  •                
  • 6
  •                
  • 7
  •                
  • 8
  •                
  • 9
  •                
  • 10
  •             
         
      )    } }
ReactDOM.render (
   ,
   document.querySelector ('# ildiz')
)

Jami efir tikish kabi muhim parametrlarni o'rnatish uchun komponent o'rnatilganda, men boshlang'ich holatida dastur holatini yangilayman.

Keyin men har bir

  • raqam uchun klik voqealarini tinglovchilarni o'rnatdim, shuning uchun uni bosganingizda shartnomaning bet () funktsiyasini to'g'ri raqam va siz istagan eter miqdori bilan bajaradi.

    Endi u quyidagicha ko'rinadi va ishlaydi:

    To'liq kodni mening github-da topish mumkin: https://github.com/merlox/casino-ethereum

    Agar siz buni hozirgacha amalga oshirgan bo'lsangiz, tabriklaymiz! To'liq tarkibni aslida kam odam o'qiydi, siz ulardan biri bo'lasizmi?

    4. Ilovani Internetda IPFS yordamida joylashtiring

    Endi dastur to'ldirilgandan so'ng, uni onlayn dunyoga abadiy bepul va markazlashtirilmagan holda hosting bilan o'tkazish vaqti keldi, bu qanday ajoyib?

    Bu IPFS-ning kuchi.

    Yaxshilikda bu unchalik yaxshi emas, chunki sizning tuguningiz uni saqlab turganda sizning ilovangiz onlayn bo'ladi. Bu torrent p2p filmlariga o'xshab, uni kimdir ekmoqchi ekan, yuklab olishingiz mumkin.

    Ammo u butunlay markazlashtirilmagan bo'ladi, shuning uchun buni amalga oshirish kerak.

    IPFS-ni o'rnatishni boshlaylik, ularning veb-saytiga o'ting va dasturni o'rnating: https://ipfs.io/docs/install/

    Windows-da, har qanday joydan ipfs buyrug'ini bajarish uchun papkani yo'l o'zgaruvchisiga qo'shishim kerak edi. Agar siz buni o'qiyotgan bo'lsangiz, yo'l o'zgaruvchisini qanday o'zgartirishni oldindan bilishingiz kerak.

    Uni o'rnatgandan so'ng ish stolingizga o'ting va quyidagi buyruqlarni bajaring:

    ipfs daemon

    Bu tugunni yaratadi. Boshqa buyruq satrida yoki terminalda:

    ipfs tengdoshlari

    Bu sizga tarkibingizni baham ko'radigan tengdoshlarni jalb qiladi.

    ipfs qo'shish -r dist /

    Bu sizning dist papkangizni tarmoqqa qo'shadi. Siz uchun yaratilgan uzoq hashni ko'rasiz. So'nggi xesh bu papka uchun noyob identifikator:

    qo'shilgan Qmc9HzLPur2ncuUArLjAaa4t2HrXFycgjUPb6122N6tzi2 dist / build.js
    qo'shilgan QmZBaGYWsACJ5aCFhW459xHZ8hk4YazX1EQFiSenu3ANfR dist / index.html
    qo'shilgan QmfZoCnPcgmHYmFJqHBcyuFh3FEYrTZqGdGyioSMrAZzw2 dist

    So'nggi xeshdan nusxa oling va bajaring:

    ipfs nomi nashr QmfZoCnPcgmHYmFJqHBcyuFh3FEYrTZqGdGyioSMrAZzw2

    Siz shunga o'xshash narsani olasiz:

    QmRDVed784YwKrYAgiiBbh2rFGfCUemXWk3NkD7nWdstER: / ipfs / QmfZoCnPcgmHYmFJqHBcyuFh3FEYrTZqGdGyioSMrAZzw2 nashr etilgan.

    Bu sizning kontentingiz birinchi url-da mavjudligini anglatadi. Siz buni darvoza.ipfs.io/ipns/ ga o'tish orqali tekshirishingiz mumkin

    Mening holatim:

    shluz.ipfs.io/ipns/QmRDVed784YwKrYAgiiBbh2rFGfCUemXWk3NkD7nWdstER

    Yuklashga biroz vaqt ketadi, chunki tarmoq hozirda unchalik katta emas. Shunda siz bu ajoyib Dappni ko'rasiz! Metamaskni Ropsten sinov tarmog'iga o'rnatishni unutmang.

    Agar siz fayllaringizga o'zgartirishlar kiritsangiz, veb-paketni bajarishni unutmang, keyin ipfs add -r dist / va ipfs nomi ni e'lon qiladi. Nashr qilingan xesh har doim bir xil ekanligini tushunasiz.

    Sizning Dapp onlayn.

    5. Ilova uchun maxsus domenni ishlating

    Endi siz o'zingizning domeningizdan foydalanishni xohlashingiz mumkin, chunki sizning loyihalaringiz uchun bunday URL-dan foydalanish unchalik professionalliksiz.

    IPFS tomonidan tayyorlangan ushbu mukammal darslik misoli, agar siz to'liq tafsilotlarni xohlasangiz, sizga buni aniq tushuntiradi.

    Buni qanday qilib xudojo'ylik bilan qilish kerakligini sizga aytib beraman. Bu boshqa provayderlarda deyarli bir xil.

    1. Avval godaddy-da domeningizning DNS menejeriga o'ting.
    2. Host bilan yangi TXT yozuvini qo'shing: @ va qiymati: dnslink = / ipns /
    3. Uni saqlang va Host bilan yozuvni o'zgartiring yoki qo'shing: @ 217.182.195.23 ga ishora. Bu Gateway.ipfs.io-ning asl IP-si.
    4. Boshqa A yozuvlarni olib tashlang, chunki ular ushbu yangi A yozuviga aralashishi mumkin.
    5. Saqlab oling, bir necha daqiqadan so'ng o'sha domenga o'ting va uning ishlayotganligini tekshiring.
    6. Bundan tashqari, unga kirishingiz mumkin: gateway.ipfs.io/ipns/
    7. Bu holda urllar darvoza.ipfs.io/peppo.es va peppo.es
    Mana, ishlayapti! Mening domenim peppo.es

    6. Yakuniy Dapp bilan o'ynang

    Bu butun darslik. Agar uni oxirigacha o'qisangiz, tabriklaymiz! Siz ajoyib va ​​endi ethereum.org sahifasida ta'kidlanganidek to'xtab bo'lmaydigan dasturlarni yaratishga qodirsiz.

    O'zingizning harakatlaringizdan zavqlaning va iloji boricha xatolarni topish uchun ilova dasturini sinab ko'rishga ishonch hosil qiling. Agar siz jasoratli bo'lsangiz, uni asosiy Homestead tarmog'iga joylashtirishingiz mumkin.

    Faqatgina farq shundaki, siz o'rnatishda Metamask tarmog'ingizni o'zgartirishingiz kerak.

    Shuningdek, men sizga qattiqlik hujjatlari, Web3.js hujjatlari, truffle hujjatlari va IPFS hujjatlarini tekshirishingizni maslahat beraman. Ular sizga ko'proq ma'lumot olish va ulkan dasturlarni yaratish uchun kerak bo'lgan barcha narsalarga ega.

    Siz truffuff-dan foydalanishni va ilovalarni tezroq ishlab chiqishni o'rganishingiz mumkin, chunki siz ularni buyruq satridan joylashtirishingiz mumkin, garchi buning uchun butun blockchain-ni yuklab olishingiz kerak.

    Shuningdek, siz Oraclize shartnomalari yordamida chindan ham tasodifiy raqamlarni yaratishingiz mumkin. Agar siz Dapp dasturini professionalga uzatmoqchi bo'lsangiz, ularni qidirib toping.

    Nihoyat, menga biron bir narsa noaniq bo'lsa, ehtimol xatolar va loyiha bilan bog'liq savollar haqida xabar bering.

    Siz buni qildingizmi?

    Btw men Ethereum ishlab chiqaruvchisi bo'lishning eng muhim tushunchalarini o'rganadigan qattiqlikni noldan o'rganish uchun Ethereum rivojlanishi haqida kitob yozdim. Bizni cheksiz bepul olish uchun bu erda tekshirib ko'ring: https://www.amazon.com/dp/B07BJB1YNQ

    Siz shuningdek uni mening veb-saytimdan 20 AQSh dollari miqdorida PDF-da olishingiz mumkin: https://merunas.io/book