O objetivo deste artigo é demonstrar como criar um token ERC20 no menor tempo possível.
Vamos começar com o básico: O que é um token ERC20?
Nos últimos anos, a especificação de token ERC20 se tornou o padrão de fato para tokens Ethereum. Em outras palavras, a maioria dos contratos Ethereum que existem hoje são compatíveis com ERC20. Este artigo irá detalhar como você pode criar seu próprio token Ethereum, mas antes de começarmos, vamos dar uma olhada no padrão ERC20.
O que torna os tokens ERC20 tão atraentes e bem-sucedidos? Existem vários fatores em jogo:
Assim como outros tokens Ethereum, os tokens ERC20 são implementados como contratos inteligentes e executados na Máquina Virtual Ethereum (EVM) de maneira descentralizada.
Os contratos inteligentes da Ethereum são escritos em Solidity. Embora existam linguagens alternativas, quase ninguém as usa para este propósito. Solidity é semelhante ao JavaScript, então se você tem algum conhecimento de JavaScript, ou mesmo Java e outras linguagens como C, você não deve ter problemas para descobrir que um pedaço de código em Solidity tem, mesmo antes de realmente dominar Solidity o suficiente para usar isto.
É aqui que a diversão começa, pois você deverá ser capaz de começar a criar um contrato ERC20 simples em nenhum momento. Esta é uma tarefa direta, simples o suficiente para que este artigo demonstre como você pode escrever e implantar um token ERC20 em menos de uma hora.
O token que criaremos nesta demonstração será uma implementação básica do ERC20, sem muitos sinos e assobios. No entanto, tenho visto muitos tokens simples semelhantes no mundo real, e eles tendem a funcionar muito bem.
Simplificando, o padrão ERC20 define um conjunto de funções a serem implementadas por todos os tokens ERC20 de forma a permitir a integração com outros contratos, carteiras ou marketplaces. Este conjunto de funções é bastante curto e básico.
function totalSupply() public view returns (uint256); function balanceOf(address tokenOwner) public view returns (uint); function allowance(address tokenOwner, address spender) public view returns (uint); function transfer(address to, uint tokens) public returns (bool); function approve(address spender, uint tokens) public returns (bool); function transferFrom(address from, address to, uint tokens) public returns (bool);
As funções do ERC20 permitem que um usuário externo, digamos um aplicativo de cripto-carteira, descubra o saldo de um usuário e transfira fundos de um usuário para outro com a devida autorização.
cadeia de valor da internet das coisas
O contrato inteligente define dois eventos especificamente definidos:
event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens);
Esses eventos serão invocados ou emitido quando um usuário recebe direitos para retirar tokens de uma conta e depois que os tokens são realmente transferidos.
Além das funções padrão do ERC20, muitos tokens ERC20 também apresentam campos adicionais e alguns tornaram-se uma parte de fato do padrão ERC20, se não por escrito, então na prática. Aqui estão alguns exemplos de tais campos.
string public constant name; string public constant symbol; uint8 public constant decimals;
Aqui estão alguns pontos sobre a nomenclatura ERC20 e Solidity:
public
função pode ser acessada fora do próprio contratoview
basicamente significa constante, ou seja, o estado interno do contrato não será alterado pela funçãoevent
é a maneira da Solidity de permitir que os clientes. o frontend do seu aplicativo para ser notificado sobre ocorrências específicas dentro do contratoA maioria das construções da linguagem Solidity deve ser clara se você já possui habilidades essenciais em Java / JavaScript.
Agora que descrevemos o básico e explicamos o que é necessário para criar um token ERC20, é hora de começar a escrever alguma lógica.
Primeiro, precisamos definir dois objetos de mapeamento. Esta é a noção de solidez para uma matriz associativa ou chave / valor:
mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed;
A expressão mapping(address => uint256)
define uma matriz associativa cujas chaves são do tipo address
- um número usado para denotar endereços de contas e cujos valores são do tipo uint256
- um inteiro de 256 bits normalmente usado para armazenar saldos de token.
O primeiro objeto de mapeamento, balances
, manterá o saldo simbólico de cada conta do proprietário.
O segundo objeto de mapeamento, allowed
, incluirá todas as contas aprovadas para saques de uma determinada conta junto com a quantia de saque permitida para cada uma.
Como você pode ver, o campo de valor do mapeamento permitido é por si só um mapeamento que traça o endereço da conta para sua soma de retirada aprovada.
Esses mapeamentos, juntamente com todos os outros campos do contrato, serão armazenados no blockchain e serão minado resultando em mudanças sendo propagadas para todos os nós de usuário da rede.
O armazenamento em blockchain é caro e os usuários do seu contrato precisarão pagar por ele, de uma forma ou de outra. Portanto, você deve sempre tentar minimizar o tamanho do armazenamento e as gravações no blockchain.
Agora que temos as estruturas de dados necessárias no lugar, podemos começar a realmente escrever a lógica ERC20 nas funções apropriadas.
Como definimos o número de tokens ICO? Bem, existem várias maneiras de definir o número máximo de tokens ICO e esse assunto pode valer uma longa discussão por si só.
Para as necessidades de nosso tutorial ECR20, devemos usar a abordagem mais simples: definir a quantidade total de tokens no momento da criação do contrato e inicialmente atribuir todos eles ao 'proprietário do contrato', ou seja, a conta que implementou o contrato inteligente:
uint256 totalSupply_; constructor(uint256 total) public { totalSupply_ = total; balances[msg.sender] = _totalSupply; }
Um construtor é uma função especial chamada automaticamente pelo Ethereum logo após a implantação do contrato. Normalmente é usado para inicializar o estado do token usando parâmetros passados pela conta de implantação do contrato.
msg
é uma variável global declarada e preenchida pelo próprio Ethereum. Ele contém dados importantes para a execução do contrato. O campo que estamos usando aqui: msg.sender
contém a conta Ethereum executando a função do contrato atual.
Apenas a conta de implantação pode entrar no construtor de um contrato. Quando o contrato é iniciado, esta função aloca tokens disponíveis para a conta do 'proprietário do contrato'.
function totalSupply() public view returns (uint256) { return totalSupply_; }
Esta função retornará o número de todos os tokens alocados por este contrato, independentemente do proprietário.
function balanceOf(address tokenOwner) public view returns (uint) { return balances[tokenOwner]; }
balanceOf
retornará o saldo simbólico atual de uma conta, identificado pelo endereço de seu proprietário.
function transfer(address receiver, uint numTokens) public returns (bool) { require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender] — numTokens; balances[receiver] = balances[receiver] + numTokens; emit Transfer(msg.sender, receiver, numTokens); return true; }
Como o próprio nome sugere, o transfer
função é usada para mover numTokens
quantidade de tokens do saldo do proprietário para o de outro usuário, ou receiver
. O proprietário que está transferindo é msg.sender
ou seja, aquele que executa a função, o que implica que apenas o proprietário dos tokens pode transferi-los para outros.
programas iniciantes em c ++
A maneira de Solidity afirmar um predicado é require
. Nesse caso, a conta da transferência possui saldo suficiente para efetuar a transferência. Se um require
falha, a transação é imediatamente revertida sem nenhuma alteração escrita no blockchain.
Logo antes de sair, a função dispara o evento ERC20 Transfer
permitindo que os ouvintes registrados reajam à sua conclusão.
Essa função é usada com mais frequência em um cenário de mercado de token.
function approve(address delegate, uint numTokens) public returns (bool) { allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true; }
O que approve
faz é permitir um proprietário, ou seja, msg.sender
para aprovar uma conta de delegado - possivelmente o próprio mercado - para retirar tokens de sua conta e transferi-los para outras contas.
Como você pode ver, essa função é usada para cenários em que os proprietários estão oferecendo tokens em um mercado. Ele permite que o mercado finalize a transação sem esperar pela aprovação prévia.
No final de sua execução, esta função dispara um Approval
evento.
function allowance(address owner, address delegate) public view returns (uint) { return allowed[owner][delegate]; }
Esta função retorna o número atualmente aprovado de tokens por um proprietário para um delegado específico, conforme definido no approve
função.
O transferFrom
função é o par do approve
função, que discutimos anteriormente. Ele permite que um delegado aprovado para saque transfira fundos do proprietário para uma conta de terceiros.
function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) { require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner] — numTokens; allowed[owner][msg.sender] = allowed[from][msg.sender] — numTokens; balances[buyer] = balances[buyer] + numTokens; Transfer(owner, buyer, numTokens); return true; }
Os dois require
declarações no início da função são para verificar se a transação é legítima, ou seja, se o proprietário tem tokens suficientes para transferir e se o delegado tem aprovação para (pelo menos) numTokens
sacar.
Além de transferir o numTokens
montante do proprietário ao comprador, esta função também subtrai numTokens
do subsídio do delegado. Basicamente, isso permite que um delegado com um determinado subsídio o divida em várias retiradas separadas, o que é um comportamento típico de mercado.
para que é usada a programação c
Poderíamos parar aqui e ter uma implementação ERC20 válida. No entanto, queremos dar um passo adiante, pois queremos um token de força industrial. Isso exige que tornemos nosso código um pouco mais seguro, embora ainda possamos manter o token relativamente simples, se não básico.
SafeMath é uma biblioteca Solidity destinada a lidar com uma forma que os hackers são conhecidos por quebrar contratos: ataque de estouro de inteiro. Nesse tipo de ataque, o hacker força o contrato a usar valores numéricos incorretos, passando parâmetros que receberão os números inteiros relevantes passado seus valores máximos.
SafeMath protege contra isso testando o estouro antes de executar a ação aritmética, removendo assim o perigo de um ataque de estouro. A biblioteca é tão pequena que o impacto no tamanho do contrato é mínimo, não gerando nenhum desempenho e poucas penalidades de custo de armazenamento.
Vamos adicionar SafeMath ao nosso código:
library SafeMath { // Only relevant functions function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a — b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c>= a); return c; } }
SafeMath usa assert
instruções para verificar a exatidão dos parâmetros passados. Deve assert
falhar, a execução da função será interrompida imediatamente e todas as alterações do blockchain serão revertidas.
A seguir, vamos adicionar a seguinte declaração apresentando a biblioteca ao compilador Solidity:
using SafeMath for uint256;
Em seguida, substituímos a aritmética ingênua que usamos no início pelas funções SafeMath:
balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); balances[buyer] = balances[buyer].add(numTokens); balances[owner] = balances[owner].sub(numTokens);
No Solidity, as funções e eventos de um contrato inteligente são agrupados em uma entidade chamada de contrato que você pode traduzir silenciosamente para uma 'classe blockchain'. Abaixo está o contrato compatível com ERC20 que criamos, incluindo um resumo do nosso código. Os campos de nome e símbolo podem ser alterados à vontade. A maioria dos tokens mantém o valor decimal em 18, então faremos o mesmo.
Chegou a hora de implantar nosso contrato no blockchain . Após a implantação, nosso contrato será transferido para todos os nós participantes da rede. Todas e quaisquer alterações feitas no contrato serão propagadas para todos os nós participantes.
Os desenvolvedores Ethereum geralmente empregam ferramentas de implantação, como Brigadeiro . Mesmo Truffle é um exagero para as necessidades limitadas deste artigo, e uma ferramenta online simples chamada Remix será suficiente.
Para usá-lo, você precisará instalar o Plugin MetaMask em seu navegador e uma conta Rinkeby (rede de teste Ethereum) com pelo menos algum Rinkeby Ether. Essas são etapas relativamente simples, então não entraremos em detalhes.
Caso você não tenha nenhum, vá para MetaMask e Rinkeby para obter links de download e obter instruções claras de instalação e uso.
Agora que temos todos os blocos de construção no lugar, iremos para Remix e cole o código acima, incluindo a linha pragma e a biblioteca SafeMath, no editor online.
Em seguida, saltaremos para a segunda guia à direita chamada “ Corre ”E clique em“ Implantar . ” Um pop-up MetaMask aparecerá solicitando a confirmação da transação. Claro, vamos aprovar.
Glass Steagall Act causou recessão
Essência : https://gist.github.com/giladHaimov/8e81dbde10c9aeff69a1d683ed6870be#file-basicerc20-sol
Parabéns! Você acabou de implantar seu primeiro token ERC20, como um verdadeiro Ethereum profissional . Conforme prometido, o token é simples e leve, mas totalmente funcional, em conformidade com o padrão ERC20 e protegido com MathSafe. Ele está pronto para ser comprado, pago e transferido por todo o Blockchain.
Não, nem perto disso, pois nossa breve demonstração mal arranha a superfície e trata apenas de um aspecto do desenvolvimento de contrato inteligente.
Contratos inteligentes podem ser muito mais complexos dependendo da sua lógica de negócios, sua modelagem da interação do usuário, se você permite ou não a criação e gravação de tokens, mudanças de ciclo de vida que você introduz no contrato, a necessidade de recursos de nível de administrador que geralmente vem com um conjunto de funções autorizadas pelo administrador e assim por diante. Você começa a foto.
Ainda assim, se você puder replicar o que fizemos aqui, essa é uma base sólida para expandir seu conhecimento e avançar para contratos mais complexos quando necessário.
Um contrato inteligente é um pedaço de código executado na Máquina Virtual Ethereum. Um contrato inteligente Ethereum é imutável e pode enviar ou receber éter e dados.
Simplificando, os tokens ERC20 são contratos que implementam o padrão ERC20. As operações tratadas por esses contratos incluem obter o suprimento total e o saldo de tokens e os métodos usados para transferi-los.
O desenvolvimento do Ethereum é atualmente conduzido em Solidity, uma linguagem de programação orientada a contratos inspirada em JavaScript, Python e C ++.
ERC significa Ethereum Request for Comment. O número 20 é atribuído a esta solicitação, daí o sufixo.