Jak stworzyć własny token ERC-20? [Ethereum]
Wiele osób chciałoby mieć swoją kryptowalutę, lecz jest to dość ciężkie przedsięwzięcie do zrealizowania i trzeba mieć za sobą zespół deweloperów ze specjalistyczną wiedzą. Prostszym sposobem stworzenia cyfrowego aktywa jest wyemitowanie swojego tokenu, który będzie również zdecentralizowany, lecz zależny od istniejącego już blockchainu.
Tokeny są tworzone na bazie istniejących już blockchainów kryptowalutowych takich jak np. Ethereum, EOS, czy Waves. Można nimi zazwyczaj płacić za ściśle określony rodzaj usług. Takim rodzajem usług może być np. porada ekspercka czy wymiana tokenów na dobro materialne z oferty danego marketu. Tokeny również są wykorzystywane jako forma udziału w ramach “cyfrowych akcji”.
W tym poradniku pokaże jak stworzyć token w formacie ERC-20 na blockchainie Ethereum. Na podobnych zasadach funkcjonuje np. Tether (USDT) czy niegdyś Binance Coin (BNB).
Tworzymy token ERC-20 krok po kroku
Token będziemy tworzyć na maszynie wirtualnej Ethereum (w skrócie EVM – Ethereum Virtual Machine). Możemy wybrać z trzech najpopularniejszych:
Zintegrowane środowiska programistyczne (w skrócie IDE) różnią się interfejsem i niekiedy funkcjonalnością – w niektórych trzeba dany plugin samemu napisać w formie kodu. Każdy program działający na EVM jest powszechnie nazywany „inteligentnym kontraktem” (ang. „smart contract”). Najpopularniejsze języki, w których tworzy się inteligentne kontrakty w Ethereum to Solidity i Vyper, ale istnieją także inne, będące w fazie rozwoju. Nasz pierwszy token będziemy tworzyć na platformie Remix.
Zobacz również nasz poradnik, mówiący o tym jak tworzyć tokeny ERC-721.
1) Wchodzimy na stronę – https://remix.ethereum.org i klikamy ‘+’, aby stworzyć nowy kontrakt/program na blockchainie:
2) Nazywamy nasz projekt, żeby nie pomylić go w przyszłości: i klikamy “+”, aby stworzyć nowy smart contract (program na blockchainie):
3) Zatwierdzamy “OK” i przechodzimy do pisania naszego smart contractu, który będzie tokenem:
4) Wklejamy następujący kod (w całości) smart contractu, który odpowiada za tworzenie tokenu:
pragma solidity ^0.5.0;
// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// ----------------------------------------------------------------------------
contract ERC20Interface {
function totalSupply() public view returns (uint);
function balanceOf(address tokenOwner) public view returns (uint balance);
function allowance(address tokenOwner, address spender) public view returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
// ----------------------------------------------------------------------------
// Safe Math Library
// ----------------------------------------------------------------------------
contract SafeMath {
function safeAdd(uint a, uint b) public pure returns (uint c) {
c = a + b;
require(c >= a);
}
function safeSub(uint a, uint b) public pure returns (uint c) {
require(b <= a); c = a - b; } function safeMul(uint a, uint b) public pure returns (uint c)
{ c = a * b; require(a == 0 || c / a == b); }
function safeDiv(uint a, uint b) public pure returns (uint c) { require(b > 0);
c = a / b;
}
}
contract Token_Maurycego is ERC20Interface, SafeMath {
string public name;
string public symbol;
uint8 public decimals; // 18 decimals is the strongly suggested default, avoid changing it
uint256 public _totalSupply;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
/**
* Constrctor function
*
* Initializes contract with initial supply tokens to the creator of the contract
*/
constructor() public {
name = "Maurycy Konopacki";
symbol = "Maurycy";
decimals = 2;
_totalSupply = 10000;
balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
}
function totalSupply() public view returns (uint) {
return _totalSupply - balances[address(0)];
}
function balanceOf(address tokenOwner) public view returns (uint balance) {
return balances[tokenOwner];
}
function allowance(address tokenOwner, address spender) public view returns (uint remaining) {
return allowed[tokenOwner][spender];
}
function approve(address spender, uint tokens) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
return true;
}
function transfer(address to, uint tokens) public returns (bool success) {
balances[msg.sender] = safeSub(balances[msg.sender], tokens);
balances[to] = safeAdd(balances[to], tokens);
emit Transfer(msg.sender, to, tokens);
return true;
}
function transferFrom(address from, address to, uint tokens) public returns (bool success) {
balances[from] = safeSub(balances[from], tokens);
allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
balances[to] = safeAdd(balances[to], tokens);
emit Transfer(from, to, tokens);
return true;
}
}
5) W wierszu nr “35” wpisujemy nazwę naszego projektu (ta nazwa, którą wpisaliśmy na początku – punkt numer 1):
6) W wierszach 51-54 wpisujemy nasze parametry:
name = "Maurycy Konopacki"; <- nazwę naszego tokenu np. Tether lub Binance Coin symbol = "Maurycy"; <- skrót/symbol tokenu np. USDT lub BNB decimals = 2; <- liczba do ilu miejsc po przecinku jest możliwe dzielenie naszego tokenu _totalSupply = 10000; <- maksymalna ilość tokenu
7) Kolejnym krokiem jest zainstalowanie portfela MetaMask w formie wtyczki (plugina) na naszą przeglądarkę. MetaMask to portfel obsługujący Ethereum i tokeny, które się na nim znajdują:
Po zainstalowaniu – portfel powinien się pojawić w prawym górnym rogu naszej przeglądarki:
8) Po założeniu portfela wchodzimy na nasz w MetaMask zmieniamy na sieć testową “Ropsten”. Token możemy tworzyć na głównym łańcuchu Ethereum oraz na testowych, dla treningu warto potrenować na testowych sieciach.
Następnie kopiujemy nasz adres portfela:
9) Po przekopiowaniu naszego adresu wchodzimy na kranik (faucet) – dzięki któremu uzyskamy trochę testowych ETH:
Po kliknięciu “Send me test Ether” pojawi się potwierdzenie wysłanych testowych ETH, które wygląda identycznie jak na głównym łańcuchu ETH:
Do “wpuszczenia” w sieć naszego tokenu potrzebujemy jedynie dwóch wtyczek na platformie Remix. Wracamy na stronę https://remix.ethereum.org/ i wchodzimy w “PLUGIN MANAGER”:
W “search” wpisujemy:
- Solidity compiler;
- Deploy & run transactions;
– aktywujemy obie wtyczki.
10) Wchodzimy w “Solidity compiler” i z listy wyszukujemy wersję numer 0.5.0+commit.1d4f565a:
Klikamy “Compile Token_Maurycego.sol” – oczywiście tutaj będzie nazwa Waszego projektu. Plugin sprawdza poprawność naszego smart contractu – może to potrwać do minuty przy weryfikacji kodu tokenu.
Jeśli zrobiliśmy wszystko zgodnie z poradnikiem nie powinno być żadnych błędów podczas sprawdzania naszego smart contractu.
11) Wchodzimy w “Deploy & run transactions”. Z “Environment” wybieramy “Injected Web3”. Jeśli instalowaliśmy portfel MetaMask w trakcie pracy na remix.ethereum.org, wówczas konieczne będzie odświeżenie strony i ponowne skompilowanie naszego kodu.
Wirtualna maszyna ETH będzie prosiła o połączenie z naszym portfelem MetaMask:
*Oczywiście jeśli zmienimy sieć na główny łańcuch to smart contract będzie tam funkcjonował:
Następnie przechodzimy do pluginu Deploy & Run Transaction i z trzech możliwości wybieramy nazwę, którą wpisaliśmy w 35 wierszu, u mnie jest to “Token_Maurycego – browser/Token_Maurycego.sol” oraz klikamy “Deploy”, aby nasz smart contract w formie tokenu został stworzony:
IDE poprosi nas o uiszczenie opłaty za stworzenie smart contractu w formie GAS-u (mały ułamek ETH):
Klikamy “Potwierdź” i czekamy kilkanaście sekund na stworzenie naszego smart contractu:
Gdy pojawi się “hash” z linkiem oznaczać to będzie, że nasz smart contract został opublikowany na blockchainie:
Token trafił bezpośrednio na nasz adres.
12) Dodawanie tokena w portfelu MetaMask. Wchodzimy w MetaMask i klikamy trzy belki w lewym górnym rogu aplikacji:
Klikamy na samym dole “Dodaj token” następnie “Własny token”:
Kopiujemy adres contractu i wklejamy w “ADRES KONTRAKTU TOKENA” oraz klikamy “Dalej”.
MetaMask jeszcze raz spyta nas o potwierdzenie – klikamy “Dodaj tokeny”.
Gratulacje! Stworzyliście własny token, teraz możecie go wysyłać komu zechcecie:
Podsumowanie
Tokeny w formacie ERC-20 są prostym zastosowaniem smart contractu, który każdy z nas może napisać. Najczęściej tworzone są w celu zebrania funduszy na realizację projektu – czyli tzw. ICO (Initial Coin Offering). W zależności od twórców, token powinien mieć odgórnie określone zadanie:
- ‘użytkowe’ (utility) – dają uprawnienia w postaci np. pierwszeństwa do dóbr lub usług świadczonych przez emitenta;
- ‘zabezpieczające’ (security) – pozwalają użytkownikom brać udział w zyskach przedsięwzięcia, dają prawo głosu utytułowanym do tokenu;
- tokenów personalnych – reprezentują udział w zyskach generowanych przez osobę fizyczną lub umożliwiają wymianę na usługi świadczone przez emitenta.
Na stronie https://etherscan.io/tokens możemy sprawdzić aktualne statystyki związane z ilością tokenów ERC-20 (wyszczególnione są tokeny, które posiadają jakąkolwiek wartość odzwierciedloną w dolarach):
Śledź CrypS. w Google News. Czytaj najważniejsze wiadomości bezpośrednio w Google! Obserwuj ->
Zajrzyj na nasz telegram i dołącz do Crypto. Society. Dołącz ->
Andy
w p.5 mowa jest o wierszu “35” a na zdjęciu podświetlony jest wiersz”33″
p.6 mówi o wierszu “51-54” a na zdjęciu podświetlone są wiersze “49-52” dalej już nie “jadę”
jeśli na początku takie kwiatki.
<div class="apbct-real-user-wrapper"> <div class="apbct-real-user-author-name">Albert Czajkowski</div> <div class="apbct-real-user-badge" onmouseover="apbctRealUserBadgeViewPopup('apbct_trp_comment_id_642');" onmouseout="apbctRealUserBadgeClosePopup(event);"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img" style="align-self: center;"> <div class="apbct-real-user-popup apbct-trp-popup-desktop" id="apbct_trp_comment_id_642"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Albert Czajkowski</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div> <div class="apbct-real-user-popup apbct-trp-popup-mob" id="apbct_trp_comment_id_642"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Albert Czajkowski</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div>
Cześć Andy, dzięki za zwrócenie uwagi. Już poprawione.
Błąd wynikał z przeniesienia części kodu do nowych linii, tak by był bardziej czytelny. Zapomnieliśmy o zaktualizowaniu screenów.
Już jest wszystko w porządku.
Andy
ok. to tak żeby było profesjonalnie, mam pytanie czy wasza wiedza w tematach solidity, smart contract and ….. jest głębsza niż tylko generowanie nowych tokenów a co np. z tematem stablecoin ?
<div class="apbct-real-user-wrapper"> <div class="apbct-real-user-author-name">Maurycy Konopacki</div> <div class="apbct-real-user-badge" onmouseover="apbctRealUserBadgeViewPopup('apbct_trp_comment_id_689');" onmouseout="apbctRealUserBadgeClosePopup(event);"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img" style="align-self: center;"> <div class="apbct-real-user-popup apbct-trp-popup-desktop" id="apbct_trp_comment_id_689"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Maurycy Konopacki</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div> <div class="apbct-real-user-popup apbct-trp-popup-mob" id="apbct_trp_comment_id_689"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Maurycy Konopacki</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div>
Jasne, tego typu artykuły będą publikowane na bieżąco.
Andy
czy można się kontaktować na jakiś adres email ? mój jest andywodwod@gmail.com
<div class="apbct-real-user-wrapper"> <div class="apbct-real-user-author-name">Maurycy Konopacki</div> <div class="apbct-real-user-badge" onmouseover="apbctRealUserBadgeViewPopup('apbct_trp_comment_id_832');" onmouseout="apbctRealUserBadgeClosePopup(event);"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img" style="align-self: center;"> <div class="apbct-real-user-popup apbct-trp-popup-desktop" id="apbct_trp_comment_id_832"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Maurycy Konopacki</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div> <div class="apbct-real-user-popup apbct-trp-popup-mob" id="apbct_trp_comment_id_832"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Maurycy Konopacki</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div>
Znajdź nas na FB lub skontaktuj się z nami przez e-mail: redakcja@cryps.pl
ravv
cześć, Remix trochę się zmienił od tego czasu, planujecie aktualizację tego artykułu?
<div class="apbct-real-user-wrapper"> <div class="apbct-real-user-author-name">Filip Dzięciołowski</div> <div class="apbct-real-user-badge" onmouseover="apbctRealUserBadgeViewPopup('apbct_trp_comment_id_55364');" onmouseout="apbctRealUserBadgeClosePopup(event);"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img" style="align-self: center;"> <div class="apbct-real-user-popup apbct-trp-popup-desktop" id="apbct_trp_comment_id_55364"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Filip Dzięciołowski</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div> <div class="apbct-real-user-popup apbct-trp-popup-mob" id="apbct_trp_comment_id_55364"> <div class="apbct-real-user-title"> <p class="apbct-real-user-popup-header">The Real Person!</p> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/real_user.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Author <b>Filip Dzięciołowski</b> acts as a real person and verified as not a bot.</span> </div> <div class="apbct-real-user-popup-content_row"> <img src="https://cryps.pl/wp-content/plugins/cleantalk-spam-protect/css/images/shield.svg" class="apbct-real-user-popup-img"> <span class="apbct-real-user-popup-text">Passed all tests against spam bots. Anti-Spam by CleanTalk.</span> </div> </div> </div> </div>
Siemka 🙂
Tak, w swoim czasie na pewno to zrobimy
pozdrowienia!
rap
Siema, jakie są implikacje prawne emisji takiego tokena? Czy na emitencie spoczywają jakieś obowiązki prawne z tym związane i odpowiedzialność?