1. Anasayfa
  2. Solidity

Solidity Nasıl Öğrenilir: Ultimate Ethereum Kodlama Eğitimi

Bu Kılavuz, Solidity'yi öğrenmeniz için size adım adım yol gösterecektir. Solidity Programlama Dilini derinlemesine öğrenmek için diğer rehberlerimizi de inceleyip, UYGULAMA Kursumuza katılın!

Solidity Nasıl Öğrenilir: Ultimate Ethereum Kodlama Eğitimi
Solidity Nasıl Öğrenilir?
0

Solidity Nasıl Öğrenilir?

Solidity Nasıl Öğrenilir: Ultimate Ethereum Kodlama Eğitimi

Ethereum Vakfı, projenin ilk günlerinden bu yana, 2013’ün sonları ve 2014’ün başlarından beri blok zinciri dünyasını sarsıyor. Ethereum, “Bitcoin 2.0″ı ve bizim “blockchain” olarak düşündüğümüz hareketi, ilk büyük hareketin ardından gerçekten başlattı. Piyasalarda 1000 doları aşan Bitcoin “balonu” herkesin dikkatini çekti. Ethereum, Bitcoin’e benzer bir kripto para birimi olan Ether’e sahip bir blok zinciri projesidir, ancak Ethereum, (neredeyse) tam bir sanal makine dilinin ek özelliğine ve düğüm uygulamasına gömülü işleme yeteneğine sahiptir.

Ethereum Sanal Makinesi (EVM), Ethereum düğümlerinin ödeme karşılığında verileri gerçekten depolamasına ve işlemesine, gerçek dünyadaki olaylara yanıt vermesine ve daha önce geliştiriciler ve gerçekler için hiç mevcut olmayan zincir içi uygulamaları desteklemek için birçok yeni fırsata izin verir. Dünya kullanıcıları 2014’ün başlarında gerçekten İsviçre’de olma ve bir Ethereum “holonunu” ziyaret etme ve Ether token satışından önce, “kendi kendini finanse ettikleri” zamanlarda Ethereum kurucularından bazılarıyla takılma şansım oldu.

“Akıllı sözleşmeler, dünyanın her yerindeki insanların aynı dili konuşmasalar veya aynı para birimini kullanmasalar bile birbirleriyle iş yapmalarının bir yoludur.”

Mihai Alisie

Dolayısıyla, insanları bir araya getirmek ve güvenilir, emniyetli ve otomatik bir şekilde iş yapmalarını sağlamak için bir iş sözleşmesinin kurallarını programlı olarak basit bir makine dilinde tanımlayabileceğimiz fikriyle başlıyorum.

Solidity Programlama Dilinin kendisi, EVM’de çalıştırılabilen makine düzeyinde kod oluşturmak için kullandığımız bir araçtır, yüksek düzeyde insan tarafından okunabilir kodumuzu alan ve onu “verileri içine koy” gibi basit talimatlara ayıran bir derleyiciye sahip bir dildir. Bir kayıt”, “iki kayıttan veri ekle“, “xxxxx bellek noktasındaki talimata geri dön“, bunlar herhangi bir mikroişlemci yürütülebilir programın temelini oluşturur.

Dolayısıyla Solidity dili, EVM bayt koduna derlenebilen birkaç dilden sadece biridir, aynı şeyi yapan başka bir dile Serpent denir. Her dilin birkaç derleyici aracı olabilir, ancak hepsi aynı şeyi yapar, bu da ödeme için ethereum düğümlerinde çalıştırılacak EVM makine düzeyinde bayt kodu oluşturmaktır.

Solidity Nasıl Öğrenilir?

Solidity, programlama dilleri açısından oldukça basit bir dildir.

Aslında, ECMAScript’e (Javascript) çok benzer bir sözdizimine sahip, amaca yönelik olarak oluşturulmuş bir dildir. Ethereum Design Rationale belgesinden hatırlanması gereken bazı önemli noktalar var, yani 32 baytlık bir komut kelimesi boyutuna sahip bir yığın ve bellek modeli içinde çalışıyoruz, EVM bize “yığın” programına erişim sağlıyor. Program Sayacı döngüsü/atlaması (sıralı program kontrolü için) yapmak için bellek adreslerini de yapıştırabildiğimiz bir kayıt alanı, genişletilebilir bir geçici “hafıza” ve aslında kalıcı blok zincirine yazılan daha kalıcı bir “depolama” ve en önemlisi , EVM, akıllı sözleşmeler içinde toplam determinizm gerektirir.

Bu determinizm gereksinimi, Solidity dilinde “random()” işlevini görmemenizin nedenidir. Bir ethereum bloğu “mayınlandığında”, o blok içindeki akıllı sözleşme dağıtımları ve işlev çağrıları (son blok süresi içinde sıralananlar anlamına gelir) bloğu çıkaran düğümde yürütülür ve yeni durum herhangi bir şekilde değişir. Bu akıllı sözleşmedeki depolama alanları veya işlemler aslında o madenci düğümünde gerçekleşir. Ardından, yeni blok diğer tüm düğümlere yayılır ve her düğüm, aynı durum değişikliklerini blok zincirinin yerel kopyalarında da yapmayı içeren bloğu bağımsız olarak doğrulamaya çalışır. Akıllı sözleşmenin deterministik olmayan bir şekilde hareket etmesi durumunda başarısız olacağı yer burasıdır. Yeni blok ve sözleşmeleri yürütüldükten sonra diğer düğümler blok zincirinin durumu hakkında bir fikir birliğine varamazlarsa, ağ tam anlamıyla durabilir.

Bu nedenle ethereum akıllı sözleşmeleri (ve genel olarak herhangi bir blok zinciri sisteminde akıllı sözleşmeler) belirleyici olmalıdır: böylece düğüm ağı, çalışmaya devam etmek için gelen yeni bloklar hakkında her zaman doğrulayabilir ve fikir birliğini sürdürebilir.

EVM akıllı sözleşmelerinde bulacağınız bir diğer sınırlama, “bellek” ve “depolama” dışındaki verilere erişilememesidir (akıllı sözleşmenin, sabit diskleri okuyabilmesini veya silebilmesini istemiyoruz). üzerinde çalıştığı düğümler) ve bir JQuery ile olduğu gibi dış kaynakları sorgulayamama. JSON yapılarını ayrıştırmak veya kayan nokta aritmetiği yapmak gibi pek çok kütüphane işlevine gerçekten erişimimiz yok ve bu alt rutinleri yapmak veya ethereum blok zincirinin kendisinde çok fazla veri depolamak aslında maliyet açısından engelleyici.

Bazı durum değiştiren işler veya hesaplamalar yapan bir akıllı sözleşme çağırdığınızda (sadece depodan okumak dışında herhangi bir işlem), akıllı sözleşme tarafından yapılan iş için bir gaz “maliyeti”ne maruz kalacaksınız ve bu gaz maliyeti işlevinizi yürütmek için gereken hesaplamalı çalışma miktarı ile ilgili. Sonsuza kadar belirli bir miktar hesaplama için belirli bir miktar gaz ödemeyi bekleyebileceğiniz bir tür “mikro hesaplama için mikro ödeme” sistemidir.

Gazın fiyatının kendisinin genel olarak sabit kalması, yani Ether küresel piyasalarda yükseldiğinde, Eter’e karşı gaz fiyatının düşmesi gerektiği anlamına gelir. Bu nedenle, bir akıllı sözleşmeye bir işlev çağrısı yaptığınızda, önceden ödemeniz gereken gaz miktarına ilişkin bir tahmin alabilirsiniz, ancak ödemeye hazır olduğunuz fiyatı da (gaz başına ether cinsinden) belirtmelisiniz ve madencilik düğümleri, bir sonraki bloklarında akıllı sözleşme işlev çağrınızı almaları için bunun yeterince iyi bir oran olup olmadığına karar verebilir.

Akıllı sözleşmelerin, Ether alıp gönderebilecekleri kendi adresleri vardır. Akıllı sözleşmeler, işlevin “arayanını” doğrulanabilir bir şekilde izleyebilir, böylece işlevlerinden birinin ayrıcalıklı bir “sahip” veya “yönetici” hesabı tarafından mı çağrıldığını belirleyebilir ve idari işlevler için buna göre hareket edebilir. Ethereum blok zincirinden veri okuma ve eski bloklardaki işlemlerle ilgili bilgilere erişme yeteneğine sahiptirler. Ancak akıllı sözleşmeler kendi küçük deterministik dünyalarına “kilitli” mi, sadece ethereum blok zincirinde depolanan verilerin farkında mı?

Hiç de bile! İşte burada “oracle” devreye giriyor. Bize dış dünya hakkında güvenilir bir şekilde bir şeyler anlatacak bir oracle çağrı yapabilir ve akıllı sözleşme dahilinde bu veriler üzerinde hareket edebiliriz. Buradaki kilit nokta, gerçek dünya olaylarının kendileri deterministik olmasa da, Oracle’a her düğümün olup bitenlerle ilgili talebini her zaman deterministik bir şekilde yanıtlayacağı konusunda güvenilebilir, böylece tüm düğümler hala bir fikir birliğine varabilir. Yani güvenilir Oracle teoride böyle çalışır: bir “oracle” bazı verileri alır, gerçek dünyadaki bir hisse senedi fiyatı hakkında bir fiyat akışı söyler ve bu verileri basit bir Oracle akıllı sözleşmesinde “depolama” ya kaydeder.

function storeTickerData(bytes8 symbol, uint open, uint high, uint low, uint close)
    onlyOracle
    returns(bool success)
  {
    # store ticker data on-chain
    tickerData[symbol][block.number] = [open,high,low,close]
    # tickerData is a map of maps, string => uint => array[uint,uint,uint,uint]
    return true;
  }

Güvenilir oracle olma konusunda uzmanlaşmış ve kendilerini veri akışına güvenmekten kurtaracak sistemler tasarlayan şirketler var. Oraclize belgelerine bakarsak, şu ilginç alıntıyı görürüz:

Özellikle amaç, akıllı sözleşme geliştiricilerini ihtiyaç duydukları verilerle Oraclize’a güvenmeye zorlamak değildir. Herhangi bir orijinallik desteği olmadan, Oraclize verileri kolayca değiştirebilir. Bu nedenle, bu karmaşık görevi tamamlamak için Oraclize, istenen verileri orijinallik kanıtıyla birlikte döndürür: yani veriler, akıllı sözleşme tarafından açıkça talep edilen veri sağlayıcıdan gelir.

Bu nedenle, daha fazla ayrıntı için dokümanların “gerçeklik kanıtları” bölümüne göz atmalısınız, ancak fikir şu ki, gelecekte uzak bir zamanda yeni ethereum meraklıları bile, ethereum düğümlerini döndürüp blok zincirlerini ağla senkronize etmeye başlasalar bile, tüm bu “oracle-dependent” akıllı sözleşmeleri yürütmek için ihtiyaç duydukları tüm veriler, sonsuza kadar indirmeleri için güvenli bir şekilde zincirdedir. Oracle’ın gerçek dünya olayları hakkında tüm bu veri yazımını yapması için “gazı” kimin ödediği meselesi (blockchain depolama “durum değiştirme” maliyeti gazdır) başka bir konudur, ancak temel olarak, veri talep eden tarafından önceden ödenir. Buradaki güzel şey, gerçek rastgeleliği içermesi anlamında “zar atan” bir akıllı sözleşme yazamasak da, aslında bir zarın atılmasına tepki veren bir akıllı sözleşme yazmanın mümkün olmasıdır. bir oracle tarafından görevlendirilir.

Solidity Temelleri Eğitimi

Temel Kod Arka Planı ve Kurulumu

Öyleyse Solidity dilinde yazılmış temel bir ethereum akıllı sözleşmesiyle başlayalım. Öğrenmenin en iyi yolu yapmaktır! Yukarıdaki küçük kod parçasından, oldukça basit bir işlev bildirim sözdizimine ve ‘uint‘ (işaretsiz tamsayı) ve ‘string‘ gibi bazı temel veri türlerine sahip olduğumuzu görebiliriz ve belgelerde ayrıca aşağıdaki gibi değişken türlerimiz olduğunu görüyoruz. ‘.balance‘ ve ‘.transfer‘ yöntemlerini içeren, tahmini olarak bir Ethereum adresindeki bakiyeyi döndüren ve akıllı sözleşmenin Wei cinsinden birimlerle bu adrese Ether göndermesine izin veren ‘adres’.

Temel dizileriniz, numaralandırmalarınız, operatörleriniz, “eşlemeler” adı verilen karma veri yapılarınız ve blok yüksekliği, son blok zaman damgası ve bazı kullanışlı SHA-karma ve adres/anahtar işleme işlevleri gibi şeyleri içeren bazı özel önceden tanımlanmış birimler ve global değişkenlere sahibiz. Çok boyutlu dizilerle çalışırken Solidity ile ilgili önemli bir tuhaflık: indeksleme, belgelerde belirtildiği gibi, yalnızca bildirim sırasında çoğu dilde “ters” sıradadır:

Sabit boyutlu bir dizi k ve eleman tipi T, T[k] olarak, dinamik boyutlu bir dizi T[] olarak yazılır. Örnek olarak, 5 dinamik uint dizisinden oluşan bir dizi uint[][5] şeklindedir (notasyonun diğer bazı dillerle karşılaştırıldığında tersine çevrildiğini unutmayın). Üçüncü dinamik dizideki ikinci uint’e erişmek için x[2][1] kullanırsınız (endeksler sıfır tabanlıdır ve erişim, bildirimin tersi şekilde çalışır…)

Tamam, burada tehlikeli olmak için yeterince temel aracımız var, hadi başlayalım. İnsanların blok zincirinde kendileriyle ilgili bazı temel bilgilere ve bazı görüntülere sahip olabileceği bir tür temel sosyal uygulama yapalım. Her kullanıcının kendi hesabıyla ilişkili bir ethereum adresi ve bir “tanıtıcı” veya kullanıcı adı olacaktır. İnsanların girebileceği veya giremeyeceği bazı temel demografik verilere sahip olacağız ve ardından temel bir dizinde kullanıcıları arayabileceğiniz ve kullanıcılarına ekledikleri/noter tasdikli görselleri kontrol edebileceğiniz basit bir arama sayfamız olacak.

Solidity Nasıl Öğrenilir: Ultimate Ethereum Kodlama Rehberi

Yapacağımız ilk şey, akıllı sözleşmemi derlemeyi kolayca test etmemi sağlayacak bir Truffle “test bed” kurmak. Akıllı sözleşmeleri derlemek ve dağıtmak, uzun imzalı işlemler oluşturmayı içerir, ancak Truffle, basit komutları kullanarak akıllı sözleşmemi derlememe/dağıtmama ve test etmeme izin verecek. Bunu yapabilen bir sürü araç var, ancak Truffle aracını kullanan bu Solidity akıllı sözleşme video eğitimini beğendim. Herkesin takip etmesi için sadece bu eğitim için oluşturduğum bir demo github proje klasörüm var.

Introduction to Ethereum Smart Contract Development with Solidity

Bazı basit kurulum komutlarıyla başlayacağım (Debian linux ortamında):

tectract@blockgeeks/ethereum-demo-tools> npm i -g truffle
  # if you run into permissions error globally installing node modules, see here

  tectract@blockgeeks/ethereum-demo-tools> mkdir Geekt  # I'm going to call my social application "Geekt"
  tectract@blockgeeks/ethereum-demo-tools> cd Geekt
  tectract@blockgeeks/ethereum-demo-tools/Geekt> truffle init # this creates a few folders and setup files, within the Geekt/ folder
  tectract@blockgeeks/ethereum-demo-tools/Geekt > ls
  contracts  migrations  test  truffle.js                  # we have created three folders, and one new file called truffle.js

  tectract@blockgeeks/ethereum-demo-tools/Geekt > ls contracts/
  ConvertLib.sol  MetaCoin.sol  Migrations.sol             # we have some basic template contracts generated by Truffle

  tectract@blockgeeks/ethereum-demo-tools/Geekt > ls migrations/
  1_initial_migration.js  2_deploy_contracts.js            # a couple files for compilation/migration settings with Truffle

Basit Bir Solidity Akıllı Sözleşme Örneği

Tamam, ‘truffle init‘ dediğimde oluşturulan /Geekt/contracts klasöründe Geekt.sol adında bir sözleşme oluşturalım. Dosyanın en üstünde derleyici sürümünü ve bazı temel sözleşme tanımı sözdizimini ve değişken tanımlarını belirten bir satır var.

pragma solidity ^0.4.4;
contract Geekt {

  address GeektAdmin;

  mapping ( bytes32 => notarizedImage) notarizedImages; // this allows to look up notarizedImages by their SHA256notaryHash
  bytes32[] imagesByNotaryHash; // this is like a whitepages of all images, by SHA256notaryHash

  mapping ( address => User ) Users;   // this allows to look up Users by their ethereum address
  address[] usersByAddress;  // this is like a whitepages of all users, by ethereum address

Gerçek dünyada durum değiştiren bir işlevi çağırdığınızda, bunun için ne kadar ether ödeyeceğinizi belirtmeniz gerekecek, ancak neyse ki gaz maliyeti ve gaz fiyatı açısından bir maliyet tahmini talep edebilirsiniz ( gaz/eter) önceden ve genellikle çok doğrudur. Ethereum madencileri, yeterince ödeme yapıp yapmadığınıza karar verecek ve durum değiştiren işleminizi bir sonraki bloğa dahil edecek, böylece bir sonraki blok bulunduğunda bu işlevlerin geri dönmesini beklemeniz gerekecek. Bu “depolama” yapılarından veri okumak ücretsizdir ve bir sonraki bloğu beklemeniz de gerekmez, düğümler sadece verileri okur ve hemen size geri gönderir.

Bu nedenle, Kullanıcı eşlemesi, Kullanıcı nesneleri oluşturmamıza ve bunları adrese göre aramamıza izin veren ana depolama nesnemizdir. Eşlemeler, verileri depolamak ve hızlı bir şekilde almak için süper verimlidir, ancak bir haritayı yinelemenin kolay bir yolu yoktur, bu nedenle, bir kullanıcının bilinen her adresini beyaz gibi tutan bir usersByAddress adres dizisi oluşturduğumuzu da görebilirsiniz.

Depoda “görüntü” nesneleri oluşturmamıza ve bunları görüntü verilerinin ilişkili bir SHA256 karma değerine göre aramamıza izin vermek için noterizedImages eşlemesini oluşturdum ve bu notaryHash dizinleri 32 bayt uzunluğundadır.

Ayrıca, noter tasdikli tüm resimleri yinelememize izin veren beyaz sayfalar gibi, tüm notaryHash’lerin bir listesi olan bir ImagesByNotaryHash bytes32 dizisine sahibiz.

struct notarizedImage {
    string imageURL;
    uint timeStamp;
  }

  struct User {
    string handle;
    bytes32 city;
    bytes32 state;
    bytes32 country;
    bytes32[] myImages;
  }

Bunlar çok temel yapılardır ve aynı zamanda “depolama” nesnelerini temsil ederler, bu nedenle “oluşturmak” için gerçek ethere mal olurlar ve içlerindeki veriler aslında ethereum blok zincirinde saklanır ve “durumu” değiştirmek gerçek ethere mal olur. Bu görüntünün/kullanıcı yapılarının blok zinciri belleğinde nerede bulunduğunu takip etmek için gerçekten sadece dış eşlemeleri ve dizileri kullandık. NotarizedImage yapımız, muhtemelen web üzerinde bir yerde bir görüntünün URL’sini ve görüntünün ne zaman noter tasdikli olduğunu bildiren bir zaman damgasını saklar. Kullanıcı yapımız bazı temel kullanıcıları saklar: tanıtıcı, şehir, eyalet, ülke ve ayrıca bu kullanıcının noter tasdikli ve kullanıcı hesabına “eklediği” tüm resimlerin bir dizisini saklar.

function registerNewUser(string handle, bytes32 city, bytes32 state, bytes32 country) returns (bool success) {
    address thisNewAddress = msg.sender;
    // don't overwrite existing entries, and make sure handle isn't null
    if(bytes(Users[msg.sender].handle).length == 0 && bytes(handle).length != 0){
      Users[thisNewAddress].handle = handle;
      Users[thisNewAddress].city = city;
      Users[thisNewAddress].state = state;
      Users[thisNewAddress].country = country;
      usersByAddress.push(thisNewAddress);  // adds an entry for this user to the user 'whitepages'
      return true;
    } else {
      return false; // either handle was null, or a user with this handle already existed
    }
  }

İşte registerNewUser fonksiyonumuz. Giriş değişkenleri olarak tanıtıcı, şehir, eyalet, ülke alır ve başarıyı veya başarısızlığı belirtmek için doğru veya yanlış döndürür. Neden başarısız olsun? Kullanıcıların birbirlerinin tutamaçlarını üzerine yazmalarına izin vermek istemiyoruz, bu yüzden bu, tutamaçlar için bir ilk talep sistemi gibi olacak. Bu tanıtıcıya sahip bir kullanıcı zaten varsa, null değerini döndürürüz, bu yüzden bunu kontrol etmek için koşullu bir “if” satırı yerleştirdim. Ayrıca, tanıtıcı olmayan bir kullanıcı adı oluşturulmasına da izin vermiyoruz. Dikkate aldığımız bir şey, fonksiyonun çağırıcısı olan thisNewAddress, bu verileri almak için özel msg.sender işlevini kullandığımızı görebilirsiniz, bu, birisi (herhangi biri) olduğunda “bu işlevi yap” işleminin gönderildiği adrestir. Akıllı sözleşme işlevimizi çağırıyor ve bunu yapmak için gerçek eter ödüyorlar. Bu nedenle, bir “eşleme” nesnesi varsayılan olarak boştur ve şunu çağırdığımızda:

Users[thisNewAddress].handle = handle;

Bu, Kullanıcılar eşlememizde yeni bir Kullanıcı nesnesi oluşturur ve tanıtıcıyı ayarlar. Şehir, eyalet, ülke ile aynı. Ayrıca, true döndürmeden önce yeni Kullanıcının adresini usersByAddress global Users “beyaz sayfalar” nesnemize aktardığımızı unutmayın.

function addImageToUser(string imageURL, bytes32 SHA256notaryHash) returns (bool success) {
    address thisNewAddress = msg.sender;
    if(bytes(Users[thisNewAddress].handle).length != 0){ // make sure this user has created an account first
      if(bytes(imageURL).length != 0){   // ) {  // couldn't get bytes32 null check to work, oh well!
        // prevent users from fighting over sha->image listings in the whitepages, but still allow them to add a personal ref to any sha
        if(bytes(notarizedImages[SHA256notaryHash].imageURL).length == 0) {
          imagesByNotaryHash.push(SHA256notaryHash); // adds entry for this image to our image whitepages
        }
        notarizedImages[SHA256notaryHash].imageURL = imageURL;
        notarizedImages[SHA256notaryHash].timeStamp = block.timestamp; // note that updating an image also updates the timestamp
        Users[thisNewAddress].myImages.push(SHA256notaryHash); // add the image hash to this users .myImages array
        return true;
      } else {
        return false; // either imageURL or SHA256notaryHash was null, couldn't store image
      }
      return true;
    } else {
      return false; // user didn't have an account yet, couldn't store image
    }
  }

addImageToUser to user işlevimiz registerNewUser işlevine oldukça benzer. Özel msg.sender nesnesi aracılığıyla gönderen adresinize göre sizi arar ve kullanıcı girişiniz için bir resim eklemeye çalışmadan önce bu adres için kayıtlı bir Kullanıcı (tutamaçla) olup olmadığını kontrol eder. Kullanıcıların global beyaz sayfalardaki girişler için kavga etmelerini önlemek için, yalnızca mevcut değilse, görsellerin global beyaz sayfalarına notaryHash‘lerini eklemelerine izin veriyoruz, ancak onların içine herhangi bir notaryHash girişi eklemelerine/güncellemelerine izin veriyoruz.

function getUsers() constant returns (address[]) { return usersByAddress; }

  function getUser(address userAddress) constant returns (string,bytes32,bytes32,bytes32,bytes32[]) {
    return (Users[userAddress].handle,Users[userAddress].city,Users[userAddress].state,Users[userAddress].country,Users[userAddress].myImages);
  }

  function getAllImages() constant returns (bytes32[]) { return imagesByNotaryHash; }

  function getUserImages(address userAddress) constant returns (bytes32[]) { return Users[userAddress].myImages; }

  function getImage(bytes32 SHA256notaryHash) constant returns (string,uint) {
    return (notarizedImages[SHA256notaryHash].imageURL,notarizedImages[SHA256notaryHash].timeStamp);
  }

Son olarak, (yukarıdaki) erişimci işlevleri, her bir kullanıcıyı veya resmi basitçe okumamıza veya tüm kullanıcıların veya tüm resimlerin tam beyaz sayfa listelerini almamıza izin verir. Bu işlevlerin sabit verileri döndürdüğünü unutmayın; bu, temel olarak salt okunur oldukları, “durum değiştiren” olmadıkları ve çağrı yapmakta özgür oldukları ve verileri hemen döndürdükleri anlamına gelir, bir sonraki bloğa kadar beklemeniz gerekmez. Temel olarak sadece global eşlemelerimizi/dizilerimizi çağırırız ve ilgili verileri döndürürüz: adrese göre kullanıcılar veya notaryHash tarafından resimler.

Akıllı Sözleşme Derleme ve Test Etme

Şimdi akıllı sözleşmemizi bir test ortamında yerel olarak gerçekten test etmek istiyoruz. Basit Truffle komutlarını kullanmak gerçekten çok kolay, ancak öncelikle test etmek için yerel bir ethereum düğümüne ihtiyacımız var. İşte burada Ethereum TestRPC devreye giriyor. TestRPC temelde sahte bir düğümdür, sadece bir düğüm gibi davranan ve bir düğüm gibi yanıt veren ince bir program yerel ana makinenize yanıt verir. TestRPC, normal bir ethereum düğümü gibi 8545 numaralı bağlantı noktasında çalışır ve Solidity akıllı sözleşmelerini EVM koduna derleme ve bu kodu çalıştırma yeteneğine sahiptir, ayrıca gerçek ethereum ağında beklemek zorunda kalmadan test için anında yanıtlar alırsınız. Şimdi, Truffle testi derleme/dağıtım komutlarını gerçek bir ethereum düğümüne karşı çalıştırabilirsiniz, ancak bu gerçek Ether’e mal olur, ayrıca ihtiyacınız yoksa kendi düğümünüzü çalıştırmak zaman alıcı ve bellek tüketir. Bu yüzden birkaç hızlı kurulum komutu yapıyoruz:

npm i -g ethereum-testrpc

Bu, TestRPC’yi belirtilen bir “tohum” ifadesi ile başlatır ve çıktı olarak şöyle bir şey görmelisiniz:

EthereumJS TestRPC v3.0.5

Available Accounts
==================
(0) 0x0ac21f1a6fe22241ccd3af85477e5358ac5847c2
(1) 0xb0a36610de0912f2ee794d7f326acc4b3d4bc7bc
...
(9) 0x4c1cc45ef231158947639c1eabec5c5cb187401c

Private Keys
==================
(0) 91e639bd434790e1d4dc4dca95311375007617df501e8c9c250e6a001689f2c7
(1) afaeff0fc68439c4057b09ef1807aaf4e695294db57bd631ce0ddd2e8332eea7
...
(9) dcc51540372fa2cf808efd322c5e158ad5b0dbf330a809c79b540f553c6243d7

HD Wallet
==================
Mnemonic:      sample dog come year spray crawl learn general detect silver jelly pilot
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

Truffle veya Web3.js aracılığıyla akıllı sözleşmenizi dağıtırken ve etkileşimde bulunurken, bu pencerede TestRPC çalışırken bazı etkinlikler göreceksiniz. Tamam, test dağıtımı için hazırız. Truffle’ın derlemesini ve dağıtmasını bilmesi için /migrations/2_deploy_contracts.js dosyasını akıllı sözleşmenizin adını içerecek şekilde değiştirmeniz gerekir. Bu komutu yapıyoruz:

truffle compile

Her şey yolunda giderse, “eserlerin kaydedildiğini” söyleyen bir mesaj göreceksiniz ve hata mesajı yok. Yalan söylemeyeceğim, eğer sözleşmenizde sözdizimi hataları veya başka sorunlar varsa, göreceğiniz derleyici hata mesajları muhtemelen gizemli ve yorumlanması zor olacaktır! “Yığın boyutu” hakkında bir hata alırsanız, bu muhtemelen bir işlev çağrısına/çağrışından geçirilen çok fazla değişkeniniz olduğu anlamına gelir. Ayrıca, Solidity akıllı sözleşmelerinin özel yapı veri türlerini döndüremediğini unutmayın, bu nedenle bunun üzerinde de çalışmanız gerekecek, genellikle dahili eşlemelerimde yalnızca dizileri ve diğer yapıların işaretçilerini/adreslerini döndürürüm. “Yığın” hakkında çalışma zamanı hataları mesajı alırsanız, bu, kodunuzda kötü bir koşula sahip olduğunuz anlamına gelebilir.

truffle migrate

Bu komut (yukarıda), akıllı sözleşmenizin TestRPC düğümünüze test dağıtımını yapar. Çıktısı;

Running migration: 1_initial_migration.js
  Deploying Migrations...
  Migrations: 0xd06a1935230c5bae8c7ecf75fbf4f17a04564ed8
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying Geekt...
  Geekt: 0xe70ff0fa937a25d5dd4172318fa1593baba5a027
Saving successful migration to network...
Saving artifacts..

Akıllı sözleşmemize (“Geekt” olarak adlandırılır) başarıyla dağıtıldığında Ethereum blok zincirinde bir adres verilir, yukarıda görebilirsiniz, adres 0xe70ff0fa937a25d5dd4172318fa1593baba5a027‘dir. Gerçek, canlı bir ethereum ağında, sözleşmenizi dağıtmak için gaz ödersiniz ve adres asla değişmez. TestRPC’de, TestRPC’yi kapatırsanız her şeyi unutur ve TestRPC’yi tekrar başlattığınızda, sözleşmenizi yeniden dağıtmanız gerekir ve akıllı sözleşmeniz için farklı bir adres alırsınız. Akıllı sözleşmenizin adresi, insanların onunla etkileşime geçmek, durum değiştiren işlemler yapmak veya sadece ethereum blok zincirinden veri okumak için mesajlarla işlemler gönderebileceği yerdir. Akıllı sözleşmeler de bu adresler aracılığıyla “mesajlar” kullanarak birbirleriyle doğrudan etkileşime girebilir. Bu ethereum blok zinciri “mesajları” aracılığıyla verileri depolamak, değiştirmek veya okumak için diğer akıllı sözleşmelerle etkileşime giren akıllı sözleşmeler, Merkezi Olmayan Otonom Kuruluşlar veya DAO’lar olarak bilinir.

Tamam, şimdi eğlenceli kısım geliyor. Aslında bazı başlangıç ​​testleri yapmaya ve akıllı sözleşmemizle etkileşime geçmeye hazırız. Truffle “konsolunu” başlatıyoruz ve her şeyin çalıştığından emin olmak için TestRPC yerel ana bilgisayar düğümümüze karşı bazı sorgular yapıyoruz ve kullanıcılar ve görüntüler ekleyip bunları düzgün bir şekilde alabiliyoruz.

truffle console
> Geekt = Geekt.deployed()
> Geekt.then(function(instance){return JSON.stringify(instance.abi);})
> Geekt.then(function(instance){return instance.registerNewUser("Tectract","Denver","CO","USA");})

> Geekt.then(function(instance){return instance.addImageToUser('www.myimageURL.com','0x6c3e007e281f6948b37c511a11e43c8026d2a16a8a45fed4e83379b66b0ab927');})

> Geekt.then(function(instance){return instance.getUser('0x0ac21f1a6fe22241ccd3af85477e5358ac5847c2');}) > Geekt.then(function(instance){return instance.getUsers();})
> Geekt.then(function(instance){return instance.getImages();})
> Geekt.then(function(instance){return instance.getImage('0x6c3e007e281f6948b37c511a11e43c8026d2a16a8a45fed4e83379b66b0ab927');})

Buradaki önemli bir kavram, akıllı sözleşmenizle etkileşim kurmak için işlev adlarını ve giriş/çıkışları tanımlayan javascript biçimli bir nesne olan ABI’dir, akıllı sözleşmeniz için Uygulama Programlayıcı Arayüzü (API) açıklamasına benzer, bu, insanlara bunun için nasıl mesajlar oluşturulacağını söyler. registerNewUser() işlevim çalışıyor! Bunu konsol penceresinde registerNewUser() işlev çağrısına yanıt olarak görüyorum:

{ tx: '0x1b9f55971871921ccd23a9aa7620620c6c958a893af334087283926d4c6d60b1',
  receipt:
   { transactionHash: '0x1b9f55971871921ccd23a9aa7620620c6c958a893af334087283926d4c6d60b1',
     transactionIndex: 0,
     blockHash: '0x2be4fab68daaf8db199e2a6adea101c0f1ed06f46aba21e8e4c06e752ca3325c',
     blockNumber: 5,
     gasUsed: 145215,
     cumulativeGasUsed: 145215,
     contractAddress: null,
     logs: [] },
  logs: [] }

AddImageToUser() işlevi, benzer şekilde başarıyı döndürür ve artık ethereum blok zincirinden bireysel kullanıcı kayıtlarını veya noter tasdikli görüntü kayıtlarını alabildiğimde, getUser() işlev çağrım şunu döndürür:

[ 'Tectract',
  '0x44656e7665720000000000000000000000000000000000000000000000000000',
  '0x434f000000000000000000000000000000000000000000000000000000000000',
  '0x5553410000000000000000000000000000000000000000000000000000000000',
  [ '0x6c3e007e281f6948b37c511a11e43c8026d2a16a8a45fed4e83379b66b0ab927' ] ]
and I can grab that image data via the 32-byte SHA256Notary hash string I have associated with it, my getImage() function returns:

[ 'www.myimageURL.com',
  { [String: '1496256315'] s: 1, e: 9, c: [ 1496256315 ] } ]

Bu harika görünüyor. Her şey çalışıyor, TestRPC ve Truffle‘da test edildi ve dünyanın ethereum blok zincirindeki kullanıcı kaydımız ve görüntü noterimiz ile etkileşime geçebilmesi için Ðapp için harika bir grafik kullanıcı arayüzü oluşturmaya hazırız.

Temel Ethereum ÐApp Tasarımı

Localhost Tasarım ve Testi

Gitmeye hazırız, Solidity dilli akıllı sözleşmemiz başarıyla derlendi ve yerel testRPC ethereum düğümümüze dağıtıldı. Artık, kullanıcıların bazı temel web programlamalarını ve özellikle Ethereum düğümleri ve akıllı sözleşmelerle etkileşime girmek için yapılmış özel Web3.js javascript modülünü kullanarak web tarayıcıları aracılığıyla akıllı sözleşmeyle etkileşime girmesine olanak tanıyan basit bir ÐApp‘i hızlı bir şekilde oluşturabiliriz.

Bu demoyu (açık kaynaklı github depoları), insanların web3.js kullanarak Ethereum ÐApps oluştururken kullanmaları için bir referans olarak yaptım, Bu demo Create-React-App adlı kullanımı kolay bir araçla yapıldı, bir Facebook dahili web dili React, ancak herhangi bir React koduna odaklanmayacağız, sadece web.js javascript komutları gerekli. Kodum CommonJS’de, neredeyse tamamen eski ES6 javascript ile aynı.

Yani web uygulamanızda, “npm i -S web3” gibi bir komutla düğüm-modül web3’ü kurarsınız ve kullanıyorsanız, package.json dosyanıza kaydeder. Böylece, bir “” etiketinin içinde veya bir .js dosyasının içinde, web3 modülünün kendisini yüklemek için şöyle bir satıra sahip olursunuz:

import Web3 from ‘web3’;

(or, in ES6 javascript)

var Web3 = require(‘web3’);

Bağlanabilmesi için Web3’e düğümümüz ve akıllı sözleşmemiz hakkında bazı ayrıntılar hakkında bilgi vermeliyiz. Bunun gibi satırlar göreceksiniz:

# this line specificies our localhost node IP:port settings
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

# our smart-contract address, from above
var GeektAddress = '0xe70ff0fa937a25d5dd4172318fa1593baba5a027';

# our smart-contract ABI, as raw javascript object, not quoted string!
var GeektABI = [{"constant":true,"inputs":[],"name":"getUsers","outputs":[{"name":"",   (...)

# this loads the smart-contract into our web3 object
GeektContract = web3.eth.contract(GeektABI).at(GeektAddress);

# this finds the default account listed for the node connection (account 0 from TestRPC above)
defaultAccount = web3.eth.accounts[0];
Here are some lines that demonstrate read-only functions interfacing with our smart-contract, via web3:

# the below function is activated when the page loads, to get the "white-pages" of all known user addresses
GeektContract.getUsers(function(err,usersResult){

# the below function grabs an image as needed, and stores them in browser memory...
GeektContract.getImage(imageHash,function(err,imageResult){

Bu basit demo ÐApp sadece bilinen tüm kullanıcı adreslerini yükler ve gerçek kullanıcı resmi ayrıntılarını alır ve görüntü gerektiğinde anında kendini kaydeder.

Bu noktada TestRPC istemcimi yeniledim ve yerel ana bilgisayar TestRPC düğümüne karşı akıllı sözleşmeyi dağıtan “truffle migrate” komutunu yaptım. Arayüzün, butona tıklayıp ilk kullanıcıyı “kaydetmem” için hazır olduğunu görebilirsiniz. Bu düğmeyi tıkladığımda, akıllı sözleşmemdeki registerNewUser() işlevim çağrılacak ve bu kullanıcı verilerini yukarıda belirttiğimiz akıllı sözleşme adresindeki (yerel ana bilgisayar testi) ethereum blok zinciri düğümüne ekleyecek. Blok zinciri “depolama”sına kullanıcı verilerini eklemek gaza mal olacak ve sadece bilimsel bir çılgın tahmin (SWAG) yapmak yerine ne kadar gaz ödememiz gerektiğini bulmamız gerekiyor. İşte bu “Sign Guestbook” düğmesi tıklandığında çağrılan kod:

GeektContract.registerNewUser.estimateGas(
outerThis.state.defaultHandle,
outerThis.state.defaultCity,
outerThis.state.defaultState,
outerThis.state.defaultCountry,
{from:defaultAccount},
function(err, result){

...

  var myGasNum = result;
  GeektContract.registerNewUser.sendTransaction(
  outerThis.state.defaultHandle,
  outerThis.state.defaultCity,
  outerThis.state.defaultState,
  outerThis.state.defaultCountry,
  {from:defaultAccount, gas: myGasNum},
  function(err, result){

Gördüğünüz gibi, aslında ethereum gazı (gerçek veya testnet gazı) ile ödememiz gereken durum değiştiren bir işlem yaptığımızda, önceden bu registerNewUser.estimateGas() işlevini çağıracağız ve sonra bu tahmini miktarı kullanacağız. registerNewUser.sendTransaction() işlevini kullanarak durum değiştirme işlevini gerçek olarak çağırdığımızda gazın değeri.

TestRPC’yi başlattığımızda ve bizim için bazı test cüzdan adreslerini tükürdüğünde, bu hesaplar, tam düğümlü bir cüzdan gibi, bir tam düğüm çalıştırıp ona karşı bir getAccounts RPC komutu uyguladığınızda sahip olacağınız hesaba benzer. TestRPC, başladığında size bazı ücretsiz testnet paraları, hesap başına 100 testnet Ether verir.

localhost test aşamasında, TestRPC düğümümüze karşı registerNewUser() veya addImageToUser() gibi durum değiştiren bu işlevleri çağırdığımızda, TestRPC sadece sizin için testnet gazını öder ve işlemin sonucunu hemen döndürür. Tam bir yerel ana bilgisayar düğümünde, işlem ana ağda başarılı olmadan önce bu hesabın “kilidini açmanız” gerekir ve gaz tahminimizin yeterli olduğunu varsayarak işleminizi almak için bir sonraki bloğu ana ağda beklemeniz gerekir! Ama her zaman daha iyi bir yol vardır dostlarım 🙂

Ðapp’inizi Mainnet’e bağlama

Akıllı sözleşmeyi ethereum Mainnet’e bir web sunucusundan dağıtabilirsiniz. Dağıtıp, çalıştırırsanız, muhtemelen şöyle bir şey göreceksiniz:

Ağa bağlantı görüldü:
Varsayılan hesap görüldü: (web3.eth düğüm bağlantısı yok)

Peki bu, ethereum Mainnet ile etkileşim kurmak için tam bir ethereum düğümüne veya bağlanmak için bir Virtual Private Server (VPS) tam düğümüne ihtiyacınız olduğu anlamına mı geliyor? Yakın zamana kadar bu doğruydu, ancak şimdi Metamask (Chrome tarayıcısı için) adlı bu harika chrome eklentimiz var, bu da tarayıcınızdaki ethereum Mainnet’e bağlanmanıza izin veriyor ve Metamask adamları temel olarak sizin için tam bir düğüme bağlantı sağlıyor.

Kodumda, onların ethereum tam düğümüne düğüm bağlantısını kuran metamask eklentisinden özel “enjekte edilmiş” web3 nesnesi için tespit ettiğimi görebilirsiniz. İşte otomatik olarak normal istemcinize (localhost) veya metamask web3 bağlantınıza geçiş yapan ilgili kod:

function loadWeb3() {
  let web3Injected = window.web3;
  if(typeof web3Injected !== 'undefined'){
    console.log("saw injected web3!");
    web3 = new Web3(web3Injected.currentProvider);
  } else {
    console.log("did not see web3 injected!");
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
  }
}

Metamask Plugin’i kurun ve tarayıcıda ethereum Mainnet’e bağlanın! Zaten “Geekt” Ziyaretçi Defteri demo akıllı sözleşmemizde ziyaretçi defterine birkaç kullanıcı eklediğimi görebilirsiniz. ÐApp arayüzü, kullanıcıları seçmenize ve resimlerine göz atmanıza izin verir ve henüz bir kullanıcı kaydetmemiş bir adresten bağlanırsanız, Ziyaretçi Defterini İmzala sayfasını görürsünüz.

Kullanıcı hesabınıza eklemek istediğiniz resmin URL’sini yapıştırabilmeniz için bazı kodlar ekledim ve bu, resme eklemeniz için SHA256 noter karmasını getirecek ve ayrıca SHA256 noter karmasını kontrol edecek. resimler sayfaya yüklendikçe size küçük bir yeşil onay işareti veya o URL’deki resmin ve noter karmasının hala eşleşip eşleşmediğine bağlı olarak kırmızı bir ‘X’ verir.

Metamask eklentisi, bu web3 ethereum işlemi için gerçek Ethereum gazı ile ödeme yapmam gerektiğini tespit etti ve bu işlemi kabul edip etmeyeceğimi sormak için küçük bir pencere açtı. Bu Metamask cüzdanına biraz gerçek Ether gönderdim ve işlemi tamamlamaya yetecek kadar var, bu yüzden ‘kabul et’i tıklıyorum.

Son Düşünceler, Derin Düşünceler, Sonuç Bağlamı

İşte bu, çalışıyor! Bu demo makalesi ve kod deposu, harika bir Ethereum Solidity Programlama Dili ve ÐApp geliştiricisi olmanıza büyük ölçüde yardımcı olacaktır! Metamask Plugin’i yükleyebilir, Ethereum Mainnet’e bağlanabilir ve Ziyaretçi Defterimizi / Noter Demo uygulaması ve aynı kullanıcıları ve görüntüleri görebilir ve hatta ziyaretçi defterini imzalayabilirsiniz. Ve isterseniz resimleri de tasdik edin 🙂

Bu şeyle fazla kontrolden çıkmamanız için, akıllı kontrat “sahibine” küçük bir moderasyon yeteneği ekledim, bunu dahili olarak akıllıyı dağıtmak için ilk ödemeyi yapanın adresine ayarladım. Bu özel yönetici yeteneğinin nasıl çalıştığını size gerçekten hızlı bir şekilde göstermek istiyorum çünkü bu tür yönetici kullanıcı kodu kalıbını görmek oldukça yaygındır:

address GeektAdmin;
  function Geekt() payable {  // this is the CONSTRUCTOR (same name as contract) it gets called ONCE only when contract is first deployed
    GeektAdmin = msg.sender;  // just set the admin, so they can remove bad users or images if needed, but nobody else can
  }
  modifier onlyAdmin() {
      if (msg.sender != GeektAdmin)
        throw;
      // Do not forget the "_;"! It will be replaced by the actual function body when the modifier is used.
      _;
  }
  function removeUser(address badUser) onlyAdmin returns (bool success) {
    delete Users[badUser];
    return true;
  }
  function removeImage(bytes32 badImage) onlyAdmin returns (bool success) {
    delete notarizedImages[badImage];
    return true;
  }

Sözleşmenin kendisi ile aynı ada sahip, sözleşme blok zincirine ilk kez dağıtıldığında yalnızca bir kez çağrılan özel bir yapıcı işlevimiz var, Geekt(). Bu işlev, yönetici kullanıcıyı akıllı sözleşmeyi dağıtmak için ödeme yapan msg.sender‘ın adresine ayarlar. Ayrıca, daha sonra removeUser() ve removeImage() işlevlerimize uygulanan ve bu işlevleri yalnızca msg.sender adresi yönetici kullanıcı adresi olduğunda etkinleştirilebilecek şekilde kısıtlamak için uygulanan özel bir onlyAdmin() değiştirici işlevimiz vardır.

Artık gerekirse tüm kötü kullanıcıları kaldırmanın bir yolu var 🙂 Bana bunu yaptırmayın!

Bahsetmek istediğim son bir nokta da, burada sadece yüzeyi çizdiğimizdir. Ele almadığım bir tür temel özellik, güncellemeleri tarayıcıya geri göndermenin bir yolu olan Solidity “olayları”dır, yeni bir kayıtlı kullanıcı veya görüntü algılanır. Ethereum ve Solidity’nin gerçekten en havalı kısımları, Oracles ile etkileşime giren akıllı sözleşmelerden ve “mesajlar” (DAO’lar) kullanarak kendi aralarında konuşan ve hareket eden akıllı sözleşmelerden gelir.

Ethereum ve Solidity‘nin gerçekten en havalı kısımları, Oracles ile etkileşime giren akıllı sözleşmelerden ve “mesajlar” (DAO’lar) kullanarak kendi aralarında konuşan ve hareket eden akıllı sözleşmelerden gelir. Ayrıca, akıllı sözleşmenizde gerçek ethereum depolamaya ve işlev çağrılarına dayanarak insanlara göndermeden önce, öğrenmeniz gereken oldukça ciddi güvenlik hususları da var, bir grup insan bunun için yaklaşık Milyon dolar kaybetti ve sona erdi. Ethereum ağını çekişmeli bir hard-fork’ta bölmek. Bu gerçekten dikkat etmeniz gereken bir şey ve muhtemelen bunu başka bir makalede ele almalıyız, elbette 🙂 Bu makale, sizi harekete geçirmek ve dediğim gibi “tehlikeli” olmak için iyi olmalı ve bunu öğrenmenizi, hatta almanızı tavsiye ederim. Eğer yapabilirsen öğrenmen için sana para verecek güzel bir şirket ama bu yolda daha çok yol var.

Bir diğeri, bahsetmek istediğim son nokta, ethereum’un yapısı ve şu anda akıllı sözleşmeleri kullanmanın gerçek maliyeti. Ethereum, herkesin orada verilere erişmek ve depolamak için ödeme yapabileceği, büyük, tek, halka açık bir blok zinciri üzerinde çalışan bir ağdır. Ancak, aslında bunu yapmak biraz pahalıdır. Yukarıdaki kodlarda görebileceğiniz gibi, bir resim URL’sini, SHA256 noter karmasını ve 196 baytlık zaman damgasını Ethereum Mainnet’e depolamak için bugün gerçek ABD doları cinsinden 0,96 ABD dolarına eşdeğer olan Ether ücret alınıyordu. Bu, MB başına yüksek bir veri depolama maliyetine karşılık gelir!

Bu kelimenin tam anlamıyla delice pahalı. Gaz maliyeti için ethereum Whitepaper’da açıklanan orijinal fikir, gaz maliyetinin ideal olarak bir şekilde sabit kalması gerektiğini, ancak gaz maliyetinin gerçek uygulamada blok numarasına bağlı olduğunu ve blok numarasının mevcut kadar hızlı artmadığını söylüyor. Ethereum’un piyasa fiyatı, bu nedenle gaz gerçek anlamda çok daha pahalı hale geliyor. Ayrıca, hard-fork durumu, bunun gerçekten bir halka açık zincir olduğunu ve eğer üzerinde gerçekten çekişmeli bir şey olursa, çatallanabileceğini ve verilerinizin teorik olarak geri alınabileceğini veya dayanak varlık sınıfının fiyatının keskin bir şekilde düşebileceğini gösteriyor. Verilerin maliyeti ve depolanmayı bekleyen devasa veri okyanusları, herhangi bir zincirde depolanabilen veri miktarının sınırlandırılması gerekebileceği veya kendi kendini sınırlayabileceği anlamına gelir.

Ethereum, zincir üzerinde olması için yalnızca küçük bir miktar kamuya açık veri deposuna ihtiyaç duyan şeyler için en uygun olabilir, örneğin bir çevrimiçi itibar sistemi veya bir veri noter projesi gibi. Örneğin, tüm ABD widget endüstrisi verilerini ethereum blok zincirine koymak için bir blok zinciri projesi oluşturmak mantıklı olmayabilir, çünkü tüm bu bilgilerin kamuya açık olmasını istemeyebilirsiniz ve bu işlem ücretlerini sizin için aşağı çekmeniz gerekir. Blok zinciri projeniz için Nakamoto hisse ispatına karşı konsensüs güvenlik modelinin teorik olarak zayıflamasını temsil etse bile, bir hisse ispatı blok zinciri modelinin daha enerji verimli olabileceğini düşünebilirsiniz.

Yeni bir blockchain projesine başlamadan önce, kullanmak istediğiniz platformu dikkatlice düşünün, oradaki en yeni şeylere bakın ve keşfetmekten korkmayın ve ayrıca insanları indirmeye çekecek düğüm teşvikini dikkatlice düşünün. Bir programcının alabileceği en iyi iltifat, insanların kodlarını gerçek dünyada kullanması ve onunla üretken olmasıdır.

Kodun Son Hali

pragma solidity ^0.4.4;

// Simple Solidity intro/demo contract for BlockGeeks Article
contract Geekt {

  address GeektAdmin;

  mapping ( bytes32 => notarizedImage) notarizedImages; // this allows to look up notarizedImages by their SHA256notaryHash
  bytes32[] imagesByNotaryHash; // this is like a whitepages of all images, by SHA256notaryHash

  mapping ( address => User ) Users;   // this allows to look up Users by their ethereum address
  address[] usersByAddress;  // this is like a whitepages of all users, by ethereum address

  struct notarizedImage {
    string imageURL;
    uint timeStamp;
  }

  struct User {
    string handle;
    bytes32 city;
    bytes32 state;
    bytes32 country;
    bytes32[] myImages;
  }

  function Geekt() payable {  // this is the CONSTRUCTOR (same name as contract) it gets called ONCE only when contract is first deployed
    GeektAdmin = msg.sender;  // just set the admin, so they can remove bad users or images if needed, but nobody else can
  }

  modifier onlyAdmin() {
      if (msg.sender != GeektAdmin)
        throw;
      // Do not forget the "_;"! It will be replaced by the actual function body when the modifier is used.
      _;
  }

  function removeUser(address badUser) onlyAdmin returns (bool success) {
    delete Users[badUser];
    return true;
  }

  function removeImage(bytes32 badImage) onlyAdmin returns (bool success) {
    delete notarizedImages[badImage];
    return true;
  }

  function registerNewUser(string handle, bytes32 city, bytes32 state, bytes32 country) returns (bool success) {
    address thisNewAddress = msg.sender;
    // don't overwrite existing entries, and make sure handle isn't null
    if(bytes(Users[msg.sender].handle).length == 0 && bytes(handle).length != 0){
      Users[thisNewAddress].handle = handle;
      Users[thisNewAddress].city = city;
      Users[thisNewAddress].state = state;
      Users[thisNewAddress].country = country;
      usersByAddress.push(thisNewAddress);  // adds an entry for this user to the user 'whitepages'
      return true;
    } else {
      return false; // either handle was null, or a user with this handle already existed
    }
  }

  function addImageToUser(string imageURL, bytes32 SHA256notaryHash) returns (bool success) {
    address thisNewAddress = msg.sender;
    if(bytes(Users[thisNewAddress].handle).length != 0){ // make sure this user has created an account first
      if(bytes(imageURL).length != 0){   // ) {  // couldn't get bytes32 null check to work, oh well!
        // prevent users from fighting over sha->image listings in the whitepages, but still allow them to add a personal ref to any sha
        if(bytes(notarizedImages[SHA256notaryHash].imageURL).length == 0) {
          imagesByNotaryHash.push(SHA256notaryHash); // adds entry for this image to our image whitepages
        }
        notarizedImages[SHA256notaryHash].imageURL = imageURL;
        notarizedImages[SHA256notaryHash].timeStamp = block.timestamp; // note that updating an image also updates the timestamp
        Users[thisNewAddress].myImages.push(SHA256notaryHash); // add the image hash to this users .myImages array
        return true;
      } else {
        return false; // either imageURL or SHA256notaryHash was null, couldn't store image
      }
      return true;
    } else {
      return false; // user didn't have an account yet, couldn't store image
    }
  }

  function getUsers() constant returns (address[]) { return usersByAddress; }

  function getUser(address userAddress) constant returns (string,bytes32,bytes32,bytes32,bytes32[]) {
    return (Users[userAddress].handle,Users[userAddress].city,Users[userAddress].state,Users[userAddress].country,Users[userAddress].myImages);
  }

  function getAllImages() constant returns (bytes32[]) { return imagesByNotaryHash; }

  function getUserImages(address userAddress) constant returns (bytes32[]) { return Users[userAddress].myImages; }

  function getImage(bytes32 SHA256notaryHash) constant returns (string,uint) {
    return (notarizedImages[SHA256notaryHash].imageURL,notarizedImages[SHA256notaryHash].timeStamp);
  }

}

Bu içerik Ryan Molecke tarafından kaleme alınan içeirğin aslına sadık kalarak dilimize kazandırılmıştır.

Akıllı sözleşme geliştirme yolculuğunuz hakkında daha iyi rehberlik almak için Solidity nedir? Ethereum Akıllı Sözleşmelerinin Dili Rehberi içeirğimize göz atın. Dilerseniz Yeni Başlayanlar için Solidity – Akıllı Sözleşme Geliştirme Hızlandırılmış Kursuna katılın.

Çalışmaya nereden başlayacğaım diyenler için Blockchain ​​Developer Olmak İçin Yol Haritası içeriğine de muhakkak bakın.

Bu makaleyi okuduğunuz için teşekkürler! Bana destek olmak isterseniz;

Beni TwitterLinkedin ve YouTube‘da takip edin.

Kısa bir yorum bırakmayı UNUTMAYIN!

Hasan YILDIZ, Girişimci. Doktora Öğrencisi. Yazmayan YAZILIMCI. Veri Şeysi. Eğitmen...

Yazarın Profili
İlginizi Çekebilir

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir