
Olá pessoal! Neste artigo, mostrarei como iniciar um contrato inteligente de coleta de dinheiro para sua ICO no Ethereum em 5 minutos e vários comandos no terminal. Este ensaio potencialmente economizará dezenas de milhares de dólares, já que qualquer programador - e também não um programador - poderá lançar um contrato inteligente auditado e seguro (em vez de pagar US $ 15.000 a US $ 75.000 pelo desenvolvimento). Em resumo, você pode enviar dinheiro para este contrato inteligente e receber tokens ERC20 por ele. Pode-se dizer que este artigo é uma coleção de toda a experiência adquirida ao lançar uma OIC para o meu projeto.
Na Internet, esses já estão cheios de artigos sobre contratos inteligentes, mas assim que você começa a escrever um, você se depara com o fato de que as informações são repetidas em todos os lugares e simplesmente não há tutoriais sobre como enganar seu ERC20, ou eles já estão desatualizados. A propósito, para que este artigo permaneça relevante, tentarei indicar possíveis locais onde ele pode se tornar obsoleto (e como corrigi-lo). Vamos lá!
Solidez
Esse é o nome do idioma principal que a equipe de kefir desenvolveu para lançar contratos inteligentes. Se você é um programador, basta examinar a
documentação da linguagem - é indecentemente simples. A propósito, eles simplificaram o processo, tornando mais difícil cometer um erro ao escrever um contrato inteligente. Portanto,
absolutamente qualquer programador, pelo menos no nível júnior, será capaz de descobrir isso.
Não há absolutamente nenhum sentido em pagar grandes quantias de dinheiro a desenvolvedores que conhecem solidez - será uma ordem de magnitude mais barata treinar um desenvolvedor existente.
Contratos inteligentes
... e tudo que você precisa saber sobre eles. Pule esta seção se você não for um programador. Um contrato inteligente é um pedaço de código. Em princípio, esta é uma classe de solidez (OOP, sim), que possui dois tipos de funções: mudança de estado e não mudança de estado. Bem, para executar funções em um contrato inteligente apenas enviando kefir, é necessário marcar esta função como
payable
.
State é um data warehouse, blockchain, EPT. Os contratos podem alterar a blockchain (estado, armazenamento) - mas para alterar a blockchain você precisa pagar kefir aos mineradores. Como eles compartilharão o kefir não será analisado na estrutura deste artigo. O pagamento aos mineradores pela execução do código de alteração de estado é chamado Gás. Se alguém de fora jogar kefir para o endereço de um contrato inteligente com uma chamada para uma função marcada como
payable
mas não marcada
Constant
,
View
ou
Pure
, a quantidade necessária de kefir para pagamento aos mineiros será deduzida do valor enviado. Normalmente, nos tokens do ERC20, essas são funções que fornecem o remetente de token para kefir ou transferem tokens de um detentor de token para outro.
E se você marcar uma função no contrato com as palavras
Constant
ou
View
(elas significam a mesma coisa, elas permitem apenas a leitura do estado) ou
Pure
(a mesma coisa, você nem lê o estado), não precisará gastar kefir na execução dessa função! Vou dizer ainda mais que essas funções não precisam ser chamadas pelas transações - afinal, qualquer cliente de iogurte pode teoricamente executá-lo em casa - e ninguém precisa mais saber sobre isso (afinal, nada está escrito no blockchain).
E há duas coisas importantes na solidez: herança múltipla e modificadores de função. Você também precisa saber sobre eles.
O primeiro - contratos justos podem ser herdados simultaneamente de várias classes, como
TimedCrowdsale
,
CappedCrowdsale
,
MintedCrowdsale
,
Ownable
- enquanto as funções dos construtores também são lançadas uma após a outra - mas vou explicar isso mais tarde, como exemplo.
A segunda é a capacidade de criar funções que serão inseridas em outras funções. É como um encapsulamento simples, apenas um pouco mais flexível - é literalmente
um modelo de função. Ao criar um modificador, você escreve o caractere especial
_
onde quer dizer o código de uma função usando esse modificador. Ou seja, modificadores não são apenas funcionalidades encapsuladas que retornam um valor; esse é um modelo de função quando o código de um modificador é literalmente inserido em uma função usando esse modificador.
Vamos seguir praticando.
Ambiente de cozinha
Se você não souber o que é o Terminal, leia
este artigo aqui . Se você estiver no Windows, configure um terminal via WLS. Se você já está familiarizado com o Terminal, vamos continuar. Além disso,
coloque-se imediatamente Node.js - será necessário para as próximas etapas. É melhor instalar o LTS, mas, de fato, não faz diferença qual das versões modernas do nó instalar.
A primeira coisa que instalamos e iniciamos imediatamente o processo de sincronização do bloco é
geth
. Em resumo, este é um utilitário escrito em Go que nos permitirá executar o nó ether no computador local e conectar-se às redes reais e de teste. Você pode instalar
via instaladores , mas eu recomendo que você
geth
imediatamente no Terminal, conforme descrito
aqui . Você pode verificar se seus padrões
geth
estão
geth
executando o comando no Terminal:
geth version
Se você cuspir a versão geth - tudo está em aberto, continue o tutorial. Se não - ruim, correto; parece que você precisará fazer amor com o Terminal e o sistema operacional - mas não é a primeira vez que você descobre isso. Como instalar o geth, execute o comando no Terminal:
geth --testnet console
Isso iniciará o processo de sincronização do seu nó com o servidor de teste, cujos blocos podem ser visualizados
aqui . Você pode verificar se sincronizou com a rede no console
geth
:
eth.blockNumber
O processo de sincronização levou de 1 a 4 horas - quando como. Além disso, além da sincronização de blocos, você também precisará aguardar a sincronização de estado - geralmente é mais longa que a sincronização de blocos. Você também pode usar
geth
com o sinalizador
--light
-, a sincronização dura de alguns segundos a um minuto e ainda é possível implantar contratos.
Ok, instalamos o primeiro utilitário - coloque o próximo. Precisamos colocar um análogo de
geth
, apenas uma simulação de blockchain muito local -
testrpc
. Sim, temos
3 blockchains :
testrpc
- simulação local de blockchain; rápido, mas falso e armazenado apenas em sua máquinageth --testnet
já é um blockchain real, mas você não perde dinheiro onde pode obter kefir e testar todos os geth --testnet
gratuitamentegeth
- mainnet, principal, blockchain real, kefir real; tudo de uma maneira adulta, os erros aqui são as perdas de kefir real
Dessa forma, iniciaremos o contrato de teste com o
testrpc
, em seguida instalá-lo no
geth --testnet
e, em seguida, fazer o download diretamente no
geth
.
testrpc
executando o seguinte comando:
npm install -g ethereumjs-testrpc
Bem, ou sobe imediatamente com uma trufa, já que agora o
testrpc
sob a asa da trufa e é chamado
ganache-cli
. Embora o diabo saiba, tudo funcionou
testrpc
com o
testrpc
baunilha. E se funcionar, não toque, como fui ensinado na academia intergaláctica. Você também pode executá-lo para verificar a instalação registrando
truffle
no console, mas o blockchain de teste já está sincronizado conosco - não vamos incomodar.
Bem, descobri as cadeias? Agora existem nós e o teste está sincronizado? Colocamos um utilitário conveniente para trabalhar com contratos inteligentes no kefir -
truffle
, com o seguinte comando:
npm install -g truffle truffle version
O Truffle é uma ferramenta que permite manter contratos inteligentes em arquivos diferentes, importar outros arquivos e também compilar seu código de contrato inteligente em um bytecode grande (ilegível por uma pessoa); ele encontra automaticamente o
geth
execução local (teste e teste real). ) ou
testrpc
, implante seu contrato inteligente nessa rede. Além disso, verifica se há erros no código do contrato inteligente e as transações concluídas recentemente
também ajudam a depurar . Masthead, em suma.
Nesse estágio, você deve ter instalado:
testrpc
,
geth
,
truffle
- se algo estiver faltando ou a versão não for enviada ao console mediante solicitação, corrija-o; caso contrário, você não terá sucesso.
Além disso, joguei um script simples do bash que instalará tudo para você. Chamado assim:
source <(curl -s https://raw.githubusercontent.com/backmeupplz/eth-installer/master/install.sh)
- mas eu nunca testei ainda, então não tenho certeza do seu desempenho. No entanto, ficarei feliz em receber solicitações.
Contrato Figash
Tudo já foi inventado e escrito para você - isso é bom. Um pouco de estamenha será o mesmo - mas tentarei minimizá-lo para você.
Usaremos contratos ERC20 já prontos do OpenZeppelin - esse é agora o padrão do setor, eles passaram na auditoria e, de fato, todos usam seu código. Muito obrigado por sua contribuição ao código aberto.
Faça do
cd
uma pasta segura e depois escreva:
mkdir contract && cd contract
Nesta pasta, vamos trabalhar. Crie um esboço aqui para o nosso contrato inteligente:
truffle init
Tropeçar, claramente. Agora temos duas pastas muito importantes nas quais escalaremos:
contracts
e
migrations
. O primeiro é o código para nossos contratos, o segundo é o código para as trufas saberem o que fazer ao implantar contratos na blockchain.
Em seguida, precisamos pegar o código atual do contrato inteligente a partir da NPM e, de fato, iniciar o próprio projeto:
npm init -y
Bem, o código de contratos inteligentes do OpenZeppelin está no nosso bolso na pasta
node_modules/openzeppelin-solidity/contracts
. Agora vamos para a pasta principal dos
contracts
,
MyToken.sol
todos os arquivos e adicionamos os arquivos
MyToken.sol
e
MyCrowdsale.sol
- naturalmente, você
MyCrowdsale.sol
seus contratos de maneira diferente. O primeiro será um contrato para o nosso Token ERC20 e o segundo será um contrato da nossa OIC, que aceitará o kefir e distribuirá o
MyToken
pessoas. Este artigo pode estar desatualizado, mas você sempre pode ver como o OpenZeppelin sugere que você crie contratos
em seu repositório . É assim que o
MyToken.sol
se parecerá
MyToken.sol
:
pragma solidity ^0.4.23;
Bom - você tem um contrato inteligente com seu próprio token (basta alterar os nomes nas constantes)! Você pode ver que
MintableToken
herança existe no
MintableToken
- mas tudo é o mais simples possível. É um token que pode ser emitido (do inglês “Mint” - para mint), e somente o proprietário tem o direito de emiti-lo, pois o
MintableToken
também herda do
Ownable
. Além disso, o
MintableToken
também herda das classes de tokens do ERC20 escritas pelo OpenZeppelin, nas quais a interface do ERC20 é implementada:
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); }
Sim, aqui você tem toda a interface do ERC20. Isso é difícil? Eu acho que não. Ele oferece a oportunidade de verificar quantos tokens foram emitidos, verificar o saldo do endereço e transferir tokens para outro endereço, divulgando um evento de transferência para clientes de kefir leve na rede. E tudo isso você ganha de graça no
MyToken.sol
graças ao trabalho do OpenZeppelin - eles são ótimos.
E agora vamos para a parte principal da nossa OIC - precisamos aceitar o kefir e distribuir o
MyToken
! É assim que o seu
MyCrowdsale.sol
será:
pragma solidity ^0.4.23;
So-so-so-so, o que há conosco? Meninos, contratos inteligentes? Nossa venda pública de tokens herda três das propriedades mais populares: possui um limite máximo, que não pode mais ser coletado; tampa macia, não coletando quais ésteres são devolvidos; horário de início e término da venda do token. De fato, o que mais é necessário para a felicidade?
Programadores, observe como os construtores de várias classes de herança são organizados em uma linha e obtém argumentos do construtor principal de
MyCrowdsale
. Além disso, verificamos que a hardkey é maior que a softkey - Ales Gut! Além disso, não se
MyCrowdsale
parâmetros
MyCrowdsale
no construtor
MyCrowdsale
- nós os transmitiremos no estágio de implantação do contrato na trufa.
Isso é tudo - você tem contratos prontos de seu próprio token ERC20 e até mesmo um contrato inteligente da OIC, configurado de acordo com o seu desejo e distribuindo seus tokens para kefir. Além disso, é suportado por todas as carteiras ERC20 - um erro! Vamos passar para testes manuais e implantação.
Migrações
Como eu disse anteriormente, testaremos sequencialmente em três redes blockchain, mas o processo de teste com canetas será sempre o mesmo. Vamos começar com
testrpc
, depois seguir para
geth --testnet
e continuar com
geth
. Sou faróis, acabamos de escrever o código, vamos tentar compilá-lo. Na pasta do projeto, escreva:
truffle compile
Se tudo for compilado sem problemas, você verá a
build
, que conterá o krakozyab da trufa para que possa incorporar o bytecode de seus contratos inteligentes na blockchain. Antes de implantar contratos inteligentes, precisamos dizer à trufa o que fazer. A implantação de trufas de contratos inteligentes é chamada migração - bem, vamos nos ater a essa terminologia. Vá para
migrations/1_initial_migration.js
e altere-o da seguinte maneira:
const token = artifacts.require("../contracts/MyToken.sol"); const crowdsale = artifacts.require("../contracts/MyCrowdsale.sol"); module.exports = function(deployer, network, accounts) { const openingTime = 1514764800;
Este é o mesmo arquivo que será usado pela trufa para implantar contratos. Então, o que estamos fazendo aqui? Primeiro, solicitamos o
MyToken
e o
MyToken
compilados. Depois, definimos as constantes com todos os argumentos da nossa OIC - definimos os horários de início e término; quantos tokens as pessoas receberão por 1 vey de kefir (0,000000000000000001 eth = 1 wei; definir
decimals
indica quantos pedidos wei são necessários para obter 1 de seus tokens recém-criados); carteira, de onde virá o kefir obtido com a venda; tampa dura e tampa macia. Observe que o
openingTime
sempre deve ser posterior ao horário do bloco atual na blockchain - caso contrário, seu contrato inteligente não será bloqueado devido à verificação da condição no
TimedCrowdsale
. Eu entrei nesse rake e transações com falha não podem ser debitadas. Mude essas constantes como desejar.
O próximo passo é precisamente a implantação de contratos inteligentes. Nada de interessante aqui: temos um objeto
deployer
que implementa artefatos de contrato inteligentes e passa argumentos para lá. Observe que o MyToken é
MyToken
primeiro e somente depois o
MyCrowdsale
- e o endereço do primeiro é passado no segundo como argumento.
Então, o mais interessante é sobre o que eles não escrevem na documentação ou nos livros. Quando você cria um
MyToken
partir de uma carteira, essa carteira se torna o proprietário do
MyToken
na superclasse
Ownable
- o mesmo acontece com o
MyCrowdsale
. Se você se aprofundar no
MintableToken
, poderá ver que apenas o
Owner
pode cunhar moedas! E quem é o proprietário do
MyToken
? É isso mesmo: o endereço que o aborreceu. E quem enviará pedidos de cunhagem de moedas? Correto: contrato inteligente
MyCrowdsale
. Deixe-me lembrá-lo de que o endereço que criou o
MyToken
e o
MyCrowdsale
são dois endereços diferentes.
Portanto, estamos adicionando a terceira etapa de implantação não-ortodoxa, em que o endereço que desafiou os contratos (
web3.eth.accounts[0]
) chama a função
transferOwnership
no contrato
MyToken
,
MyToken
que o
MyCrowdsale
dono do
MyToken
e possa cunhar moedas. E o
MyCrowdsale
ainda está sob propriedade de
web3.eth.accounts[0]
- então tudo está incluído.
Observação sobre web3.eth.accounts[0]
: ao implantar um contrato inteligente, verifique se geth ou testrpc possui a carteira correta em web3.eth.accounts[0]
- não perca a chave privada, embora isso não o prejudique, mas de repente o proprietário precisará fazer algo mais tarde, mas a chave não está mais lá?
No testrpc
, como regra, as contas são criadas imediatamente na inicialização e são desbloqueadas imediatamente; no entanto, em um blockchain de teste e de ar real, vale a pena criar uma conta por meio do personal.newAccount()
- reabasteça esse endereço via Faucet no blockchain de teste ou kefir real no blockchain real. Não perca sua senha e chaves privadas.
Além disso, você pode adicionar uma carteira existente às suas contas chamando web3.personal.importRawKey('pvt_key', 'password')
, mas para isso é necessário chamar geth
com o parâmetro adicional --rpcapi="db,eth,net,web3,personal,web3"
. Eu acho que você vai descobrir.
Teste e implantação
Sim, os contratos estão prontos, as migrações são escritas, resta apenas implantar e verificar. Ambos,
geth
(test e real) e
testrpc
gerenciados da mesma maneira no
truffle console
- portanto, descreverei o método de verificação do
testrpc
e
testrpc
como habilitar o
geth
after. E assim, lançamos o blockchain de kefir local de teste:
testrpc
Hum ... isso é tudo. Você simula o blockchain de kefir localmente.
E para implantar no blockchain ether de teste, em vez deste comando, você obterá geth --testnet --rpc
. E para implantar no verdadeiro blockchain do éter, você simplesmente geth --rpc
. O sinalizador --rpc
necessário para que a trufa possa se conectar. As etapas de implantação e teste a seguir são mais ou menos as mesmas para todos os três tipos de blockchain. A única coisa é que depois de executar o teste ou o blockchain real via geth
, ele começará a sincronizar os blocos - e isso pode levar de quatro a cinco horas em uma boa conexão com a Internet. Uma observação sobre isso estava no começo do artigo. Antes de implantar contratos inteligentes, recomendo aguardar a sincronização completa. Além disso, o blockchain pesa na região de 60 a 100 gigabytes, portanto, prepare o espaço em disco para isso.
Além disso, verifique também se web3.eth.accounts[0]
desbloqueado. Geralmente, você pode registrar o testrpc
no console, que é aberto imediatamente, ou em uma janela Terminal separada no console, que é aberta via geth console
: eth.unlockAccount(eth.accounts[0], ", ", 24*3600)
- isso desbloqueará sua conta, o que deve criar um contrato inteligente
Agora abra uma nova janela do Terminal (não fechamos o
testrpc
- deve funcionar) e escreva-o na pasta do projeto:
truffle migrate --reset
Esse comando mágico compila um contrato inteligente (ou seja, você não precisa escrever uma
truffle compile
todas as vezes) e o implementa no micro servidor blockchain encontrado localmente aberto. Vale ressaltar que, se
testrpc
fizer isso instantaneamente, o teste e as cadeias reais incluirão a transação nos próximos blocos por muito mais tempo. Depois disso, você deve cuspir algo assim no console:
Using network 'development'. Running migration: 1_initial_migration.js Running step... Replacing MyToken... ... 0x86a7090b0a279f8befc95b38fa8bee6918df30928dda0a3c48416454e2082b65 MyToken: 0x2dc35f255e56f06bd2935f5a49a0033548d85477 Replacing MyCrowdsale... ... 0xf0aab5d550f363478ac426dc2aff570302a576282c6c2c4e91205a7a3dea5d72 MyCrowdsale: 0xaac611907f12d5ebe89648d6459c1c81eca78151 ... 0x459303aa0b79be2dc2c8041dd48493f2d0e109fac19588f50c0ac664f34c7e30 Saving artifacts...
Acho que você já percebeu que o console forneceu os endereços dos contratos inteligentes
MyToken
e
MyCrowdsale
. Isso é tudo! O contrato inteligente está incorporado na blockchain cujo microsservidor você abriu. Resta apenas verificar se os tokens são realmente distribuídos aos usuários que enviam kefir ao contrato inteligente
MyCrowdsale
. Escrevemos o seguinte no Terminal para entrar no console de trufas:
truffle console
Escrevemos o seguinte na trufa agora (sem comentários):
No caso de, testrpc
você pode verificar imediatamente o saldo de nossa carteira novamente, mas no caso de teste e blockchain real, é necessário aguardar até que nossa transação seja incluída no bloco - geralmente quando isso acontece, a trufa fornece o número da transação. Você já esperou? Verifique novamente nosso saldo em MyToken
:
Isso é tudo!
Primeiro a massa sobre o seu contrato testrpc
, então geth --testnet
, em seguida, deployte on geth
. Então você lançou seu próprio ICO! E você não precisou gastar dezenas de kilobaks para auditoria e lançamento. Estragar tudo o que os caras do OpenZeppelin nos forneceram é realmente muito difícil. E quando você o usa truffle
- é assim que o desenvolvimento solidário geralmente se transforma em um conto de fadas. Bem, exceto nos casos em que as transações são revertidas durante a execução de um contrato inteligente - estréia no inferno. Mas a depuração de contratos inteligentes é realmente digna de um artigo separado.Conclusão
Muito obrigado pela leitura até o final deste artigo! Se eu consegui economizar tempo ou dinheiro, ou se você aprendeu algo novo com este artigo, ficarei muito feliz com isso. Também ficaria muito grato se você compartilhar este artigo com seus amigos ou conhecidos que desejam realizar uma ICO - economize US $ 75.000 para sub-programadores que sugam dinheiro do mercado de criptografia como parasitas, copiando e colando as mesmas 25 linhas de código .Boa sorte no desenvolvimento de contratos inteligentes! Ainda tem dúvidas? Peço-lhe nos comentários. Ficarei feliz em responder a tudo e tentar ajudar com problemas.Bônus
Mas e se você quiser alterar a lógica pela qual o preço de compra dos tokens é considerado? Claro, você pode alterá-lo corretamente rate
ou usar uma das classes de contratos do OpenZeppelin, mas e se você quiser algo ainda mais pervertido? Em um contrato inteligente, você pode substituir a função da getTokenAmount
seguinte maneira: function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) { if (block.timestamp < 1533081600) {
Em geral, isso pode tornar o preço do token dependente do momento da compra - quanto mais longe na floresta, mais caros os tokens. Não tenha medo de experimentar e reescrever alguns dos recursos de contratos inteligentes - é divertido!