Cała historia ludzkości to nieprzerwane uwalnianie się od łańcuchów i tworzenie nowych, jeszcze silniejszych. (Autor anonimowy)
Analizując liczne projekty blockchain (Bitshares, Hyperledger, Exonum, Ethereum, Bitcoin i inne), rozumiem, że z technicznego punktu widzenia wszystkie one oparte są na tych samych zasadach. Blokchainy przypominają domy, które mimo różnorodności konstrukcji, dekoracji i przeznaczenia mają fundament, ściany, dach, okna, drzwi, które są ze sobą powiązane w określony sposób. Jeśli zrozumie się podstawowe zasady projektowania budynków, zna właściwości materiałów użytych do budowy, można określić celowe przeznaczenie konkretnego domu. Obecnie sytuacja z blockchainem wygląda tak, że wszyscy o nim słyszeli, ale mało kto rozumie architekturę i zasady działania. Powoduje to nieporozumienia co do tego, do czego i jak ma sens wykorzystać technologie blockchain.
W tym artykule przyjrzymy się wspólnym dla wszystkich blockchainów właściwościom i zasadom. Następnie zobaczymy zadania, które można rozwiązywać za pomocą blockchaina, a dla utrwalenia materiału zbudujemy mały, ale prawdziwy blockchain na swoim wirtualnym serwerze!
Zatem przypomnijmy sobie, jakie problemy początkowo rozwiązał blockchain.
Jestem pewien, że wielu powie o rozproszonej, zdecentralizowanej, publicznej i niezmiennej bazie danych. Ale po co to wszystko było potrzebne?
Preferuję zaczynać naukę każdej technologii od czytania standardów, ponieważ to na nich opierają się wszystkie artykuły i książki na dany temat. Ale obecnie nie ma standardów blockchaina, w ISO utworzono tylko do ich opracowania. W tej chwili w każdym publicznym projekcie blockchain istnieje dokument White paper, który de facto jest specyfikacją techniczną. Pierwszym powszechnie znanym projektem blockchain jest sieć Bitcoin. Wchodzimy na oficjalną stronę sieci i jak to wszystko się zaczęło.
Zadanie blockchaina
Zatem zadaniem, które rozwiązał blockchain w pionierskiej sieci Bitcoin, jest dokonanie zaufanego transferu własności digitalnych aktywów (assets) w niezaufanym środowisku bez pośredników. Na przykład w sieci Bitcoin aktywem cyfrowym są cyfrowe monety bitcoin. Wszystkie techniczne rozwiązania Bitcoin i innych blockchainów sprowadzają się do rozwiązania tego zadania.
Problemy, które rozwiązuje blockchain
Załóżmy, że pewna instytucja finansowa mówi, że zbudowała sieć na całym świecie, dzięki której można przesyłać pieniądze do każdego człowieka. Czy uwierzysz jej? Jeśli ta instytucja to Visa lub MasterCard, to prawdopodobnie uwierzysz, a jeśli powiedzmy, AnonymousWorldMoney, to raczej nie. Dlaczego tak jest? Ponieważ doskonale rozumiemy, jak prywatne firmy tworzą rozproszone systemy, w jakim celu i do czego to może prowadzić. Przyjrzyjmy się bliżej problemom takich systemów i jak mogą być one rozwiązane przy użyciu technologii blockchain.
Załóżmy, że w hipotetycznej AnonymousWorldMoney znajdują się serwery z bazami danych, i dobrze, jeśli będzie ich kilka w różnych centrach danych. Kiedy nadawca przesyła pieniądze, rejestrowana jest transakcja, która replikowana jest na wszystkich serwerach, a pieniądze docierają do odbiorcy.

W idealnym świecie taki schemat działa doskonale, w naszym natomiast pojawiają się następujące problemy:
- Problem identyfikacji uczestników z jednej strony i potrzeba anonimowości transakcji z drugiej. Tzn. należy przelać pieniądze określonemu odbiorcy tak, aby nikt poza uczestnikami transakcji nie wiedział o tej transakcji. Banki mają numery kont i kart kredytowych przypisanych do konkretnych osób fizycznych lub prawnych, a tajemnica bankowa chroni informacje o transakcjach. A kto gwarantuje, że hipotetyczna AnonymousWorldMoney nie wykorzystuje danych osobowych i informacji o transakcjach do własnych celów?
- Jak upewnić się, że odbiorca otrzymał dokładnie tę kwotę, którą mu przelano? Powiedzmy, że nadawca przelał 100 $, a odbiorca otrzymał 10 $. Nadawca przychodzi do biura AnonymousWorldMoney z paragonem, a pracownik pokazuje swoją wersję, w której zapisano, że nadawca przelał tylko 10 $.
- Problem braku zaufania w środowisku, na przykład oszustwa nazywanego double-spending. Niesumienny uczestnik może wydać swoje saldo wielokrotnie, zanim płatność zostanie zreplikowana na wszystkich serwerach. , oczywiście, nikomu nie został odwołany, a spójność w końcu zostanie osiągnięta, ale ktoś nie otrzyma pieniędzy za świadczone usługi lub towary. Dlatego jeśli nie ma pełnego zaufania do instytucji płatniczej lub uczestników transakcji, należy zbudować sieć opartą nie na zaufaniu, lecz na kryptografii.
- Podstawowy system AnonymousWorldMoney dysponuje ograniczoną liczbą serwerów, które mogą stać się niedostępne zarówno przypadkowo, jak i celowo.
- AnonymousWorldMoney pobierze swoją zauważalną prowizję.
- Możliwość zarządzania. W trakcie używania Bitcoin okazało się, że ludzie chcą nie tylko przesyłać sobie nawzajem monety, ale także sprawdzać różne warunki transakcji, programować scenariusze działania oraz automatycznie wykonywać operacje w zależności od warunków itd.
Jak blockchain rozwiązuje te problemy
- Identyfikacja uczestników odbywa się za pomocą pary kluczy: prywatnego i publicznego, a algorytm podpisu cyfrowego jednoznacznie identyfikuje nadawcę i odbiorcę, pozostawiając ich tożsamości anonimowe.
- Transakcje są zbierane w blokach, obliczany jest hash bloku, który jest zapisywany w następnym bloku. Taka sekwencja zapisu hashy w blokach nazwała tę technologię blockchain, a także sprawia, że zmiana lub usunięcie bloków czy pojedynczych transakcji z bloków jest niemożliwe. W ten sposób, jeśli transakcja znalazła się w blockchainie, można być pewnym, że jej dane pozostaną niezmienne.
- Oszustwo double-spending zapobiega się poprzez osiągnięcie konsensusu w sieci, które dane uznajeć za poprawne, a które odrzucać. W sieci Bitcoin konsensus osiąga się poprzez dowód pracy PoW (Proof-of-Work).
- Niezawodność działania sieci osiąga się dzięki temu, że blockchain jest publiczny, gdzie każdy uczestnik może uruchomić węzeł, uzyskać pełną kopię blockchaina i, co więcej, samodzielnie zacząć weryfikować transakcje pod kątem poprawności. Należy również zauważyć, że współczesne blockchainy pozwalają budować nie tylko publiczne (otwarte), ale i prywatne (zamknięte) blockchainy oraz korzystać z hybrydowych schematów.
- Całkowicie nie da się uniknąć prowizji w blockchainie, ponieważ trzeba płacić ludziom, którzy wspierają sieć, ale w blockchainie konieczność prowizji jest tak przekonująco udowodniona, że nie pozostawia wątpliwości co do jej potrzeby.
- Współczesne blockchainy mają możliwość realizacji logiki biznesowej, która w blockchainie nazywana jest Smart Contracts. Logika smart kontraktów jest realizowana w różnych językach wysokiego poziomu.
Przyjrzyjmy się tym rozwiązaniom dokładniej.
Architektura blockchaina
Składniki blockchaina
Każdy uczestnik może uruchomić swój węzeł z pełną kopią blockchaina (pełny węzeł). Pełne węzły, które mogą zapisywać transakcje w blockchainie, nazywane są węzłami konsensusu (świadek) lub górnikami (miner). Pełne węzły, które tylko weryfikują poprawność transakcji, nazywane są węzłami audytu (audit). Klienci lekkie (light clients) nie przechowują pełnych kopii blockchaina, a współdziałają z siecią, korzystając z pełnych węzłów.
Większość użytkowników do dokonywania transakcji korzysta z klientów lekkich lub portfeli webowych. Wszystkie węzły są ze sobą połączone. Przy takim zestawie elementów architektura sieci staje się bardziej odporna:

Cykl życia transakcji
Przyjrzyjmy się cyklowi życia transakcji i rozłożymy go na części:

Technologie blockchaina
Przyjrzymy się bliżej rozwiązaniom technicznym i ich powiązaniom ze sobą.
Identyfikacja
Każda transakcja blockchainowa musi być podpisana podpisem elektronicznym. Dlatego do dokonania transakcji każdy uczestnik musi mieć parę kluczy: prywatny / publiczny. Czasami parę kluczy nazywa się portfelem (wallet), ponieważ klucze są ściśle powiązane z unikatowym adresem cyfrowym i bilansem uczestnika. W rzeczywistości klucze i adresy to po prostu ciągi cyfr w różnych systemach liczbowych. Przykłady kluczy i adresu portfela:
Klucz prywatny: 0a78194a8a893b8baac7c09b6a4a4b4b161b2f80a126cbb79bde231a4567420f
Klucz publiczny: 0579b478952214d7cddac32ac9dc522c821a4489bc10aac3a81b9d1cd7a92e57ba
Adres: 0x3814JnJpGnt5tB2GD1qfKP709W3KbRdfb27VDo tworzenia podpisu elektronicznego w blockchainach używa się algorytmu opartego na krzywych eliptycznych: Elliptic Curve Digital Signature Algorithm (ECDSA). Do jego działania klucz prywatny (256-bitowa liczba) zazwyczaj jest losowo wybrany. Liczba możliwych kluczy wynosi 2 do potęgi 256, dlatego można mówić o praktycznej niemożności przypadkowego trafienia na te same wartości kluczy prywatnych.
Następnie klucz publiczny uzyskuje się z klucza prywatnego poprzez pomnożenie jego wartości przez współrzędne punktu znajdującego się na krzywej eliptycznej, w wyniku czego uzyskuje się współrzędne nowego punktu tej samej krzywej. To działanie gwarantuje uzyskanie pary kluczy, odpowiedniej do podpisów elektronicznych transakcji. A na koniec adres portfela jest jednoznacznie obliczany z klucza publicznego.
Istnieje wiele artykułów szczegółowo omawiających kryptografię stosowaną w blockchainie, na przykład:
Prywatny klucz musi być ściśle tajny i przechowywany w bezpiecznym miejscu. Klucz publiczny jest znany wszystkim. W przypadku utraty prywatnego klucza dostęp do aktywów (monet) nie może zostać przywrócony, a pieniądze zostaną utracone na zawsze. Dlatego zadanie niezawodnego przechowywania prywatnych kluczy jest niezwykle aktualne, ponieważ nie jest to bank, do którego zawsze można przyjść z paszportem i odzyskać konto. Istnieje cała branża produkująca tzw. zimne portfele kryptograficzne, podobne do pendrive'ów:

lub można zastosować bardziej niezawodne sposoby, na przykład wybić wartość prywatnego klucza na żetonach:

Transakcje
Więcej o strukturze transakcji można przeczytać w artykule . Ważne jest, aby zrozumieć, że każda transakcja ma co najmniej następujące dane:
From: 0x48C89c341C5960Ca2Bf3732D6D8a0F4f89Cc4368 - cyfrowy adres nadawcy
To: 0x367adb7894334678b90аfe7882a5b06f7fbc783a - cyfrowy adres odbiorcy
Value: 0.0001 - kwota transakcji
Transaction Hash: 0x617ede331e8a99f46a363b32b239542bb4006e4fa9a2727a6636ffe3eb095cef - hash transakcjiNastępnie transakcja jest podpisywana prywatnym kluczem i rozsyłana (zob. szczegóły pracy protokołu ) do wszystkich węzłów w blockchainie, które weryfikują transakcje pod kątem ważności. Algorytm weryfikacji transakcji jest złożony i obejmuje .
Bloki transakcji
Po zweryfikowaniu ważności transakcji, węzły formują z nich bloki. Oprócz transakcji, w bloku zapisywany jest hash poprzedniego bloku, liczba (licznik Nonce) i obliczany jest hash bieżącego bloku za pomocą algorytmu SHA-256. Hash musi spełniać określone warunki trudności. Na przykład w sieci Bitcoin trudność haszowania automatycznie zmienia się co 2 tygodnie w zależności od mocy sieci, tak aby blok był generowany w przybliżeniu co 10 minut. Trudność określa następujące kryterium: znaleziony hash musi być mniejszy od z góry ustalonej liczby. Jeśli to kryterium nie jest spełnione, do Nonce dodawana jest 1, a praca nad obliczaniem hasha jest powtarzana. Do znajdowania hasha używa się pola Nonce, ponieważ to jedyne dane w bloku, które można zmienić, pozostałe muszą pozostawać niezmienione. Prawidłowy hash musi mieć określoną liczbę zer na początku, na przykład jeden z rzeczywistych hashy:
000000000000000000000bf03212e7dd1176f52f816fa395fc9b93c44bc11f91Udane znalezienie hashu jest dowodem wykonanego zadania (Proof-of-Work, PoW) dla sieci Bitcoin lub Ethereum. Proces znajdowania hashów nazywany jest kopaniem (mining), co analogicznie przypomina wydobycie złota. Nazwa dość dokładnie określa istotę procesu, ponieważ polega na prostym przeszukiwaniu możliwości, a jeśli ktoś znalazł odpowiedni hash, to rzeczywiście jest to szczęście. To jak znalezienie prawdziwego złotego samorodka w tonach pustego urobku. Nagroda za blok wynosi obecnie 12.5 BTC, a po pomnożeniu przez aktualny kurs bitcoina wynoszący $3900, otrzymuje się ponad kilogram czystego złota. Jest o co walczyć!
Po udanym znalezieniu hashu, blok oraz sam znaleziony hash zapisywane są w blockchainie jako kolejny blok. Szczegóły dotyczące struktury bloków można znaleźć w artykule , a poniżej przedstawiam uproszczony schemat:

Blockchain zaczyna się od bloku, który nie ma hasha poprzedniego bloku. Taki blok w blockchainie jest jeden i nosi nazwę Genesis block. Pozostałe bloki mają identyczną strukturę i różnią się jedynie liczbą transakcji. Rzeczywiste transakcje i bloki tworzone obecnie w Bitcoinie lub Ethereum można oglądać w .
Rozmiar bloków w Bitcoinie jest ograniczony do 1 MB, a przy minimalnej objętości informacji w transakcji wynoszącej około 200 bajtów, maksymalnie w bloku może być około 6000 transakcji. Stąd zresztą wynika wydajność Bitcoina, z której wszyscy się śmieją: blok generowany jest mniej więcej co 10 minut * 60 sek = 600 sek, co daje formalną wydajność około 10 TPS. Chociaż w rzeczywistości to nie jest wydajność, a świadomie zrealizowany algorytm pracy. W Ethereum dla konkurencji po prostu zredukowano czas generacji bloku do 15 sek., co formalnie zwiększyło wydajność. Dlatego w blockchainach wykorzystujących PoW jako konsensus nie ma sensu porównywać wydajności, ponieważ zależy ona bezpośrednio od trudności obliczenia hasha, którą można ustawić na dowolną.
Forks
Co się stanie, jeśli na przykład kilka węzłów znajdzie hashe spełniające warunki trudności, ale różne pod względem wartości (innymi słowy, dojdzie do różnych konsensusów) i zapisze bloki w łańcuchu bloków? Przyjrzyjmy się, jak łańcuch bloków broni się przed taką sytuacją. W takim przypadku mamy do czynienia z tzw. forkiem, i łańcuch bloków ma dwie wersje łańcucha:

Co dzieje się dalej? Następnie część sieci zaczyna pracować nad blokiem N+2 z jednego łańcucha, a część z drugiego:

Jeden z tych bloków zostanie znaleziony wcześniej i wysłany do łańcucha bloków i zgodnie z zasadami łańcucha bloków musi przełączyć się na dłuższy łańcuch i anulować wszystkie transakcje z alternatywnego bloku:

Może się zdarzyć, że transakcja uczestnika była tylko w jednym z bloków forka, który został anulowany. Dlatego, aby mieć pewność, że potrzebna transakcja została zapisana w łańcuchu bloków, istnieje ogólna rekomendacja — zanim zaufasz transakcji, poczekaj, aż kilka kolejnych bloków zostanie dodanych do łańcucha bloków. Rekomendacje dotyczące tego, ile bloków czekać w różnych łańcuchach bloków, różnią się. Na przykład w sieci Bitcoin minimum to 2 bloki, maksimum 6.
Taka sama sytuacja z forkiem bloków wystąpi również podczas tzw. ataku 51% — to wtedy grupa górników próbuje wyhodować alternatywny łańcuch bloków, dążąc do unieważnienia łańcucha ze swoimi oszukańczymi transakcjami. Chociaż obecnie, zamiast oszustwa, bardziej opłaca się wykorzystywać swoje moce obliczeniowe do uczciwej kopalni.
Konsensus
Aby zapisać blok w łańcuchu bloków, sieć musi dojść do konsensusu. Przypomnijmy sobie zadanie osiągnięcia konsensusu w komputerowych sieciach komunikacyjnych. Problem formułuje się jako zadanie wschodnich generałów BFT (). Pomijając barwne opisy problemów w wizantyjskiej armii, problem można sformułować tak: jak węzły sieci mogą dojść do wspólnego wyniku, jeżeli część węzłów sieci może świadomie je zniekształcać. Istniejące algorytmy rozwiązania zadania BFT pokazują, że sieć może działać poprawnie, jeśli oszustów jest mniej niż 1/3. Dlaczego w sieci Bitcoin nie zastosowano konsensusu BFT? Dlaczego użyto PoW? Istnieje kilka powodów:
- BFT dobrze działa z niewielkim, ustalonym zestawem węzłów, natomiast w publicznym blockchainie liczba węzłów jest nieprzewidywalna i co więcej, węzły mogą być dowolnie włączane i wyłączane.
- Należy zmotywować ludzi do uruchamiania węzłów blockchain. W tym celu ludzie muszą otrzymywać nagrody. W BFT formalnie nie ma za co otrzymywać nagrody, podczas gdy w PoW wszystkim jest jasne na poziomie intuicyjnym, że chodzi o energię elektryczną zużytą przez procesor podczas znajdowania hashu bloku.
Oprócz PoW istnieje jeszcze kilka konsensów, które są stosowane w nowoczesnych blockchainach, na przykład:
- PoS (Proof-of-Stake) — w blockchainie
- DPoS (Delegated Proof-of-Stake) — w blockchainie
- Modyfikacje BFT: SBFT (Simplified BFT) i PBFT (Practical BFT), na przykład w blockchainie
Zatrzymajmy się na chwilę przy konsensie PoS, ponieważ to właśnie PoS i jego odmiany zyskały największą popularność w prywatnych blockchainach. Dlaczego właśnie w prywatnych? Z jednej strony, charakterystyki PoS są lepsze w porównaniu do PoW, ponieważ do osiągnięcia konsensusu potrzebne są mniejsze zasoby obliczeniowe, co zwiększa szybkość zapisywania danych w blockchainie. Ale z drugiej strony, w PoS istnieje więcej możliwości do oszustwa, dlatego aby zneutralizować to, wszyscy uczestnicy blockchaina muszą być znani.
Konsens PoS opiera się na wyborze węzła, który może zapisać blok z transakcjami w blockchainie w zależności od liczby środków na koncie, a właściwie, nie na koncie, ale w zastawie. Im więcej masz środków w zastawie, tym większa szansa, że sieć wybierze twój węzeł do zapisu bloku. Zastaw nie zostanie zwrócony, jeśli blok okaże się nieważny. W ten sposób realizowana jest ochrona przed oszustwami. Istnieją następujące wariacje PoS:
- Konsens Delegated PoS (DPoS) dzieli uczestników na "głosujących" i "walidujących". Posiadacze monet (głosujący uczestnicy) delegują swoje prawo do weryfikacji i zapisywania transakcji w blockchainie innym uczestnikom. Dzięki temu walidatorzy wykonują całą pracę obliczeniową i otrzymują za to nagrody, a obecność głosujących uczestników gwarantuje uczciwość walidatorów, ponieważ można ich zmienić w dowolnym momencie.
- Konsensus LPoS (Leased Proof-of-Stake) pozwala na wynajem swoich środków innym węzłom, aby miały większe szanse na weryfikację bloków. Dzięki temu można otrzymywać prowizję za transakcje, nie uczestnicząc jednocześnie w samej weryfikacji transakcji ani w wydobywaniu bloków.
Istnieje jeszcze szereg innych konsensusów, które jak na razie nie zyskały szerokiego uznania, tutaj po prostu je wymienię dla informacji, a przegląd samych algorytmów konsensusu można zobaczyć, na przykład, w artykule: .
- PoET (Proof-of-Elapsed Time)
- PoC (Proof-of-Capacity)
- PoB (Proof-of-Burn)
- PoWeight (Proof-of-Weight)
- PoA (Proof-of-Activity) — PoW + PoS
- PoI (Proof-of-Importans)
Wiarygodność i modele wdrażania blockchainów
Publiczny blockchain
Odporność Publiczny lub inne nazewnictwo Blockchain bez zezwolenia osiągane jest poprzez umożliwienie każdemu podłączenia się i przeglądania informacji lub nawet podłączenia własnego węzła, a zaufanie budowane jest na konsensusie PoW.
Prywatny blockchain
Prywatny lub Blockchain prywatny z zezwoleniem. W tych blockchainach tylko określona grupa uczestników (organizacji lub osób) ma dostęp do informacji. Takie blockchainy budują organizacje w celu zwiększenia ogólnych korzyści lub efektywności. Ich wiarygodność zapewniana jest wspólnymi celami uczestników oraz algorytmami konsensusu PoS i BFT.
Konsorcjum blockchainowe
Istnieją Konsorcjum lub Publiczny blockchain z zezwoleniem. To takie blockchainy, do których każdy może się podłączyć w celu przeglądania, ale dodawanie informacji lub podłączanie własnego węzła może być realizowane tylko za zgodą innych uczestników. Takie blockchainy budują organizacje w celu zwiększenia zaufania ze strony klientów lub konsumentów produktów lub społeczeństwa jako całości. Tutaj także wiarygodność osiągana jest poprzez obecność zaufania pomiędzy uczestnikami oraz tymi samymi algorytmami konsensusu PoS i BFT.
Smart contracts
W blockchainach stworzonych po Bitcoinie, w mniejszym lub większym stopniu dodano możliwość wykonywania smart contracts. Zasadniczo smart contract to transakcja, w której umieszczony jest kod programowy do wykonania. Smart contracts w sieci Ethereum są realizowane w EVM (Ethereum Virtual Machine). Aby rozpocząć wykonanie smart contract, należy go wyraźnie uruchomić inną transakcją, lub muszą zostać spełnione warunki wstępne do jego wykonania. Wyniki wykonania smart contract również zostaną zapisane w blockchainie. Otrzymywanie danych z zewnątrz blockchaina jest możliwe, ale bardzo ograniczone.
Jaką logikę biznesową można zaimplementować za pomocą smart kontraktu? W rzeczywistości nie jest ich zbyt wiele, na przykład weryfikacja warunków na podstawie danych z blockchaina, zmiana właścicieli aktywów cyfrowych w zależności od tych warunków oraz zapis danych w stałej pamięci wewnątrz blockchaina. Logika jest implementowana w specjalnym języku wysokiego poziomu Solidity.
Klasycznym przykładem funkcjonalności, którą realizuje się przy użyciu smart kontraktów, jest emisja tokenów na potrzeby ICO. Na przykład stworzyłem smart kontrakt na emisję skromnych 500 000 000 AlexToken. Z znajduje się
źródłowy kod smart kontraktu w języku Solidity
pragma solidity ^0.4.23;
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
**/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
**/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
**/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
**/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
**/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender account.
**/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
**/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
**/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title ERC20Basic interface
* @dev Basic ERC20 interface
**/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
**/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
**/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
uint256 totalSupply_;
/**
* @dev total number of tokens in existence
**/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
**/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
**/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
}
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
**/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
**/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
**/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
**/
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
**/
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
/**
* @title Configurable
* @dev Configurable varriables of the contract
**/
contract Configurable {
uint256 public constant cap = 1000000000*10**18;
uint256 public constant basePrice = 100*10**18; // tokens per 1 ether
uint256 public tokensSold = 0;
uint256 public constant tokenReserve = 500000000*10**18;
uint256 public remainingTokens = 0;
}
/**
* @title CrowdsaleToken
* @dev Contract to preform crowd sale with token
**/
contract CrowdsaleToken is StandardToken, Configurable, Ownable {
/**
* @dev enum of current crowd sale state
**/
enum Stages {
none,
icoStart,
icoEnd
}
Stages currentStage;
/**
* @dev constructor of CrowdsaleToken
**/
constructor() public {
currentStage = Stages.none;
balances[owner] = balances[owner].add(tokenReserve);
totalSupply_ = totalSupply_.add(tokenReserve);
remainingTokens = cap;
emit Transfer(address(this), owner, tokenReserve);
}
/**
* @dev fallback function to send ether to for Crowd sale
**/
function () public payable {
require(currentStage == Stages.icoStart);
require(msg.value > 0);
require(remainingTokens > 0);
uint256 weiAmount = msg.value; // Calculate tokens to sell
uint256 tokens = weiAmount.mul(basePrice).div(1 ether);
uint256 returnWei = 0;
if(tokensSold.add(tokens) > cap){
uint256 newTokens = cap.sub(tokensSold);
uint256 newWei = newTokens.div(basePrice).mul(1 ether);
returnWei = weiAmount.sub(newWei);
weiAmount = newWei;
tokens = newTokens;
}
tokensSold = tokensSold.add(tokens); // Increment raised amount
remainingTokens = cap.sub(tokensSold);
if(returnWei > 0){
msg.sender.transfer(returnWei);
emit Transfer(address(this), msg.sender, returnWei);
}
balances[msg.sender] = balances[msg.sender].add(tokens);
emit Transfer(address(this), msg.sender, tokens);
totalSupply_ = totalSupply_.add(tokens);
owner.transfer(weiAmount);// Send money to owner
}
/**
* @dev startIco starts the public ICO
**/
function startIco() public onlyOwner {
require(currentStage != Stages.icoEnd);
currentStage = Stages.icoStart;
}
/**
* @dev endIco closes down the ICO
**/
function endIco() internal {
currentStage = Stages.icoEnd;
// Transfer any remaining tokens
if(remainingTokens > 0)
balances[owner] = balances[owner].add(remainingTokens);
// transfer any remaining ETH balance in the contract to the owner
owner.transfer(address(this).balance);
}
/**
* @dev finalizeIco closes down the ICO and sets needed varriables
**/
function finalizeIco() public onlyOwner {
require(currentStage != Stages.icoEnd);
endIco();
}
}
/**
* @title LavevelToken
* @dev Contract to create the Lavevel Token
**/
contract AlexToken is CrowdsaleToken {
string public constant name = "AlexToken";
string public constant symbol = "ALT";
uint32 public constant decimals = 18;
}oraz binarna reprezentacja, jak ją widzi sieć
60806040526000600355600060045533600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560146101000a81548160ff021916908360028111156200006f57fe5b0217905550620001036b019d971e4fe8401e74000000600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200024a6401000000000262000b1d179091906401000000009004565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550620001986b019d971e4fe8401e740000006001546200024a6401000000000262000b1d179091906401000000009004565b6001819055506b033b2e3c9fd0803ce8000000600481905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6b019d971e4fe8401e740000006040518082815260200191505060405180910390a362000267565b600081830190508281101515156200025e57fe5b80905092915050565b611cb880620002776000396000f300608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146104c7578063095ea7b31461055757806318160ddd146105bc57806323b872dd146105e7578063313ce5671461066c578063355274ea146106a3578063518ab2a8146106ce57806366188463146106f957806370a082311461075e57806389311e6f146107b55780638da5cb5b146107cc578063903a3ef61461082357806395d89b411461083a578063a9059cbb146108ca578063bf5839031461092f578063c7876ea41461095a578063cbcb317114610985578063d73dd623146109b0578063dd62ed3e14610a15578063f2fde38b14610a8c575b60008060008060006001600281111561012757fe5b600560149054906101000a900460ff16600281111561014257fe5b14151561014e57600080fd5b60003411151561015d57600080fd5b600060045411151561016e57600080fd5b3494506101a7670de0b6b3a764000061019968056bc75e2d6310000088610acf90919063ffffffff16565b610b0790919063ffffffff16565b9350600092506b033b2e3c9fd0803ce80000006101cf85600354610b1d90919063ffffffff16565b111561024c576101f66003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b915061022e670de0b6b3a764000061022068056bc75e2d6310000085610b0790919063ffffffff16565b610acf90919063ffffffff16565b90506102438186610b3990919063ffffffff16565b92508094508193505b61026184600354610b1d90919063ffffffff16565b6003819055506102886003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b6004819055506000831115610344573373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156102dd573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b610395846000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a361045184600154610b1d90919063ffffffff16565b600181905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f193505050501580156104bf573d6000803e3d6000fd5b505050505050005b3480156104d357600080fd5b506104dc610b52565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561051c578082015181840152602081019050610501565b50505050905090810190601f1680156105495780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561056357600080fd5b506105a2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8b565b604051808215151515815260200191505060405180910390f35b3480156105c857600080fd5b506105d1610c7d565b6040518082815260200191505060405180910390f35b3480156105f357600080fd5b50610652600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c87565b604051808215151515815260200191505060405180910390f35b34801561067857600080fd5b50610681611041565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b3480156106af57600080fd5b506106b8611046565b6040518082815260200191505060405180910390f35b3480156106da57600080fd5b506106e3611056565b6040518082815260200191505060405180910390f35b34801561070557600080fd5b50610744600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105c565b604051808215151515815260200191505060405180910390f35b34801561076a57600080fd5b5061079f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112ed565b6040518082815260200191505060405180910390f35b3480156107c157600080fd5b506107ca611335565b005b3480156107d857600080fd5b506107e16113eb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561082f57600080fd5b50610838611411565b005b34801561084657600080fd5b5061084f6114ab565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561088f578082015181840152602081019050610874565b50505050905090810190601f1680156108bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108d657600080fd5b50610915600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114e4565b604051808215151515815260200191505060405180910390f35b34801561093b57600080fd5b50610944611703565b6040518082815260200191505060405180910390f35b34801561096657600080fd5b5061096f611709565b6040518082815260200191505060405180910390f35b34801561099157600080fd5b5061099a611716565b6040518082815260200191505060405180910390f35b3480156109bc57600080fd5b506109fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611726565b604051808215151515815260200191505060405180910390f35b348015610a2157600080fd5b50610a76600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611922565b6040518082815260200191505060405180910390f35b348015610a9857600080fd5b50610acd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119a9565b005b600080831415610ae25760009050610b01565b8183029050818382811515610af357fe5b04141515610afd57fe5b8090505b92915050565b60008183811515610b1457fe5b04905092915050565b60008183019050828110151515610b3057fe5b80905092915050565b6000828211151515610b4757fe5b818303905092915050565b6040805190810160405280600981526020017f416c6578546f6b656e000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600154905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610cc457600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d1157600080fd5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d9c57600080fd5b610ded826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610e80826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f5182600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b6b033b2e3c9fd0803ce800000081565b60035481565b600080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508083111561116d576000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611201565b6111808382610b3990919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600191505092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561139157600080fd5b60028081111561139d57fe5b600560149054906101000a900460ff1660028111156113b857fe5b141515156113c557600080fd5b6001600560146101000a81548160ff021916908360028111156113e457fe5b0217905550565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561146d57600080fd5b60028081111561147957fe5b600560149054906101000a900460ff16600281111561149457fe5b141515156114a157600080fd5b6114a9611b01565b565b6040805190810160405280600381526020017f414c54000000000000000000000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561152157600080fd5b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561156e57600080fd5b6115bf826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611652826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b60045481565b68056bc75e2d6310000081565b6b019d971e4fe8401e7400000081565b60006117b782600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a4157600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6002600560146101000a81548160ff02191690836002811115611b2057fe5b021790555060006004541115611c0a57611ba5600454600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611c89573d6000803e3d6000fd5b505600a165627a7a723058205bbef016cc7699572f944871cb6f05e69915ada3a92a1d9f03a3fb434aac0c2b0029Więcej szczegółów na temat smart kontraktów można znaleźć w artykule: .
Podsumowanie
Wymieniliśmy technologie, na których zbudowane są współczesne blockchainy i jak są ze sobą powiązane. Teraz sformułujmy, jakie problemy można rozwiązać przy pomocy blockchaina, a które rozwiązania będą, w najlepszym razie, mało efektywne. Zatem, korzystanie z blockchaina nie jest konieczne, jeśli:
- Transakcje odbywają się w zaufanym środowisku;
- Obecność prowizji pośredników nie pogarsza sytuacji uczestników;
- Uczestnicy nie mają własności, którą można by przedstawić w formie aktywów cyfrowych;
- Nie ma rozproszenia w aktywach cyfrowych, tzn. wartość posiada lub dostarcza tylko jeden uczestnik.
Jakie przyszłości czekają na blockchain? Obecnie można jedynie przypuszczać możliwe kierunki rozwoju technologii blockchain:
- Blockchain stanie się tak powszechną technologią baz danych, jak np. SQL czy NoSQL do rozwiązywania określonego kręgu problemów;
- Blockchain stanie się powszechnym protokołem, tak jak HTTP dla Internetu;
- Blockchain stanie się podstawą nowego systemu finansowego i politycznego na świecie!
W następnej części przyjrzymy się, jakie blockchainy istnieją obecnie i do czego są wykorzystywane w różnych branżach.
To dopiero początek!
Źródło: habr.com
