WEB3DEV

Cover image for Como Enviar Dinheiro Utilizando Python: Um Tutorial Web3.py
Panegali
Panegali

Posted on • Atualizado em

Como Enviar Dinheiro Utilizando Python: Um Tutorial Web3.py

Um passo a passo técnico de uma biblioteca blockchain Ethereum para desenvolvedores Python.

Aviso de ativação: o tutorial a seguir contém elementos de criptografia explícita, serviços financeiros ponto a ponto e outros comportamentos transgressores. Os exemplos servem apenas para ilustrar o poder e a facilidade da blockchain para Python.

Olá a todos vocês Pythoners por aí!

Estou realmente dentro da comunidade Python. Como muitos, Python foi minha primeira linguagem de programação. O hackathon e os encontros do Python são incríveis. E, como bônus, eu amo Monty Python!

Pensei em juntar todos esses amores com meu trabalho atual: mostrar aos desenvolvedores como a programação da blockchain pode ser poderosa e como as habilidades são fáceis de aprender.

Este será um tutorial orientando os desenvolvedores Python através do básico do Web3.py, uma biblioteca blockchain (Ethereum). Faremos muito disso a partir do interpretador Python. (No próximo tutorial, vamos configurar um diretório adequado, mas vamos manter as coisas fáceis por enquanto!)

Observação: por motivos de segurança, enviaremos nosso dinheiro por uma rede de teste. Todas essas mesmas técnicas podem ser usadas na rede principal Ethereum.


Sumário

  1. Instalação

  2. Configurando a Conexão

  3. Inicialização

  4. Crie uma conta

  5. Contas ENS

  6. Enviar dinheiro

  7. Instanciação do Contrato

  8. Construindo a transação

  9. Assinar e enviar transação


Instalação

Vamos usar o pip para instalar o web3.py a partir de nossa linha de comando:

$ pip3 install web3
Linguagem de programação: Python (python)
Enter fullscreen mode Exit fullscreen mode

Para pessoas com ambos Python 2 e 3 instalados, você deve verificar para qual versão o comando pip utiliza. Alguns padrões para 2.7:

$ pip -V
pip 10.0.1 from /Library/Python/2.7/site-packages/pip-10.0.1-py2.7.egg/pip (python 2.7)

$ pip3 -V
pip 20.0.2 from /usr/local/lib/python3.7/site-packages/pip (python 3.7)
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Além disso, se você estiver usando virtualenv, aqui está alguma documentação sobre como configurar um ambiente limpo para Web3.py

Excelente! Estamos a caminho.

Configurando a conexão

Os sistemas blockchain são redes descentralizadas compostas por pessoas que executam software P2P dedicado individual ou “nós”. É semelhante a uma rede torrent: para interagir com a rede, você precisa hospedar um nó ou usar um serviço que hospeda um para você.

Como este é um tutorial básico, usaremos um serviço. O mais popular é o Infura. Você pode configurar sua própria conta gratuita (instruções aqui) ou pode usar o ID do produto abaixo. É crucial que você obtenha um ID de projeto e um endpoint de API - ele será nosso endpoint de API para a blockchain e o painel de análise é útil.

Dashboard infura

Copie o Endpoint e certifique-se de adicionar https:// ao endereço.

Uma vez que você tenha isso, você está pronto para se conectar a blockchain utilizando o Python!

Inicialização

Vamos iniciar nosso interpretador Python. Isso pode variar dependendo da sua instalação do Python, mas geralmente é realizado com a execução de qualquer palavra chave que você normalmente coloca antes de um arquivo python. Para mim, no meu iTerm Mac com o Pyton 2 e 3 instalado, é:

$ python3
Enter fullscreen mode Exit fullscreen mode
Python 3.8.2
[Clang 6.0 (clang-600.0.57)] on darwin
Digite "help", "copyright", "credits" ou "license" para obter mais informações.
>>> 
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Para verificar se toda a nossa configuração está correta, execute seu interpretador python e os seguintes comandos:

>>> from web3 import Web3, HTTPProvider
>>> import json
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

O comando acima importa alguns dos principais métodos web3.py que usaremos para nos conectar a blockchain, bem como à biblioteca nativa json sempre fiel.

Em seguida, criaremos um objeto, w3, que inicializamos com nosso endpoint de API Infura (prefixado com https://). Ela se tornará a principal maneira de trabalhar web3.py com a blockchain durante o restante do tutorial.

>>> w3 = Web3(Web3.HTTPProvider("https://rinkeby.infura.io/v3/8e4cd4b220fa42d3ac2acca966fd07fa"))
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Observação: Você precisa adicionar HTTPS:// na frente do seu endereço de API do Infura, caso contrário, você receberá um erro!

Também precisamos adicionar algum middleware para nos ajudar a trabalhar com o Infura e a rede de teste Rinkeby:

>>> from web3.middleware import geth_poa_middleware
>>> w3.middleware_onion.inject(geth_poa_middleware, layer=0)
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Agora, para ver se tudo correu bem, executamos:

>>> w3.isConnected()
Linguagem de programação: CSS (css)
Enter fullscreen mode Exit fullscreen mode

Se você conseguir True, parabéns! Você está conectado a blockchain!

Se você receber False, algumas coisas que você pode verificar:

  1. Se você teve que reiniciar o interpretador, você precisa reimportar as bibliotecas e reinicializar as variáveis
  2. Você copiou a chave de API Infura corretamente?
  3. Você instalou web3.py e instalou e importou a biblioteca Web3 e HTTPProvider?
  4. Você adicionou a chave de API com https:// ?

Crie uma conta

Se quisermos enviar dinheiro na blockchain, precisaremos de uma conta Ethereum. As contas Ethereum são a principal unidade de identidade na blockchain Ethereum – o endereço de uma conta é como o usuário é identificado na rede. A sustentação do sistema de contas é um protocolo de identidade descentralizado baseado em criptografia de chave pública. Essencialmente, a identidade em uma rede blockchain é confirmada pela autenticação de assinaturas digitais de uma única chave privada (mantida em segredo por um único usuário) por sua contraparte de endereço público (mantida por toda a rede). Embora tenha obstáculos significativos à experiência do usuário, ele fornece um protocolo de autenticação ponto a ponto rápido.

Gerar uma conta para usar na rede Ethereum é super fácil com web3.py.

Observação: nas próximas etapas, quebrarei algumas regras de criptografia e segurança. 1) Vou gerar uma chave privada com entropia inadequada (aleatoriedade) e 2) Vou postar uma chave privada online. Não vou usar essa chave além deste tutorial - é apenas para fins educacionais. Você deve sempre usar o gerenciamento de chave privada adequado, como o Geth ou a MetaMask, e nunca compartilhar sua chave privada publicamente.

>>> my_account = w3.eth.account.create('Ninguém espera a Inquisição Espanhola!')
>>> my_account._address
'0x5b580eB23Fca4f0936127335a92f722905286738'
>>> my_account._private_key
HexBytes('0x265434629c3d2e652550d62225adcb2813d3ac32c6e07c8c39b5cc1efbca18b3')
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

O comando acima usa a entrada de string para gerar o objeto my_account, que contém uma chave privada (my_account._private_key) e seu endereço Ethereum associado (my_account._address) . No entanto, como isso foi divulgado publicamente, alguém poderia gerar e usar a mesma chave privada. (Felizmente, estou usando apenas para este tutorial e apenas em uma rede blockchain de teste.)

Por esse motivo, os usuários normalmente delegam a criação e o gerenciamento de chaves privadas a softwares chamados clientes (como o Geth) ou carteiras (como a MetaMask). Esses projetos oferecem uma maneira incrivelmente segura de gerar e lidar com chaves privadas para interações de blockchain.

Contas ENS

Os endereços Ethereum são números hexadecimais longos. Eles são quase impossíveis de digitar ou lembrar, então a comunidade Ethereum criou o Ethereum Name System (ENS). Ele serve o mesmo benefício do Domain Name System, que substitui os números do servidor do site (216.58.194.46) por nomes legíveis (google.com). Em vez de um domínio .com, a maioria dos nomes do ENS usa um domínio .eth.

Por exemplo, eu tenho uma conta Ethererum em, 0x4d3dd8471a289E820Aa9E2Dc5f437C1b2E22F598 mas usei o ENS para mapear o nome mais legível coogan.eth para o endereço. Se você digitá-los em aplicativos ou projetos que suportam ENS (como web3.py!), ele substituirá o endereço hexadecimal Ethereum. Infelizmente, não poderemos usá-lo para este tutorial, pois os nomes de domínio .eth só funcionam na rede principal… mas talvez no próximo tutorial!

Enviar dinheiro

Para esta última seção, enviaremos algum dinheiro da conta que acabamos de criar para outra conta Ethereum. Tudo a partir do interpretador python!

Uma resposta razoável ao envio de dinheiro é: “Não é apenas dinheiro engraçado da internet que está sempre flutuando com uma trajetória descendente?” E, sim, os preços das criptomoedas em USD são extremamente voláteis. Isso causou hesitação nas empresas – por que você aceitaria uma moeda com um preço incerto?

No entanto, há uma nova solução alternativa construída no ecossistema Ethereum. O Ethereum é chamado de “o computador mundial” porque é um sistema distribuído que permite aos desenvolvedores fazer upload e executar seu próprio código. O código carregado no Ethereum dessa maneira é chamado de contrato inteligente. Uma vez carregado na rede, torna-se uma entidade autônoma, com seu próprio endereço, armazenamento de memória e acesso à rede. Contratos inteligentes deram origem a uma rica comunidade de desenvolvedores do Ethereum que é criativa e incansável ao enfrentar desafios, como a volatilidade de preços inerente das blockchains.

Em uma tentativa de criar uma fonte estável de valor para o Ethereum, um grupo de desenvolvedores escreveu e carregou um código para o Ethereum chamado Dai. É um token digital que sempre vale cerca de US$ 1. (Os detalhes técnicos para alcançar essa estabilidade são fascinantes, mas estão além do escopo deste tutorial — se você quiser ler mais sobre a mecânica, pode encontrar mais aqui). Assim que tivermos o token Dai, podemos trocá-lo com outros usuários pela mesma taxa de dólares americanos. Faremos isso agora!

(Observação: para obter o Dai para uma conta diferente da do tutorial, você pode cunhar a sua própria na rede de teste, usando este endereço de contrato, Metamask e sua própria conta. Siga as etapas do tutorial aqui)

Instanciação do Contrato

Primeiro, para interagir com o código que foi carregado por um desenvolvedor para o Ethereum, precisamos saber quais métodos o código carregado expõe. Web3.py sabe como interagir nativamente com o software principal do Ethereum, mas precisa de orientação para interagir com o código de terceiros. Fornecemos essa orientação fornecendo ao Web3.py uma Application Binary Interface (ABI). Semelhante a uma interface de programação de aplicativos (API), a ABI permite que nossa máquina saiba quais funções estão disponíveis para nós e quais parâmetros essas funções esperam. As ABIs não estão disponíveis na blockchain e são fornecidas pelo desenvolvedor em sites como Github ou Etherscan.

Aqui está a rede de teste Dai ABI que usaremos, clique e copie o trecho de código inteiro:

Observação: este código é muito longo, tome cuidado especial para copiá-lo completamente!

abi = '[{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"}]'
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Precisamos analisá-lo usando json:

>>> abi = json.loads(abi)
Enter fullscreen mode Exit fullscreen mode

Também precisamos dizer a web3.py onde encontrar esse código na rede Ethereum. Fazemos isso com o seguinte código:

>>> address = '0xc3dbf84Abb494ce5199D5d4D815b10EC29529ff8'
Linguagem de programação: JavaScript (javascript)

Enter fullscreen mode Exit fullscreen mode

Em seguida, usamos a ABI e o endereço para instanciar um objeto de contrato inteligente. Isso nos dará acesso às funções expostas pelo código:

>>> dai = w3.eth.contract(address=address, abi=abi)
Enter fullscreen mode Exit fullscreen mode

Para testar se instanciamos corretamente o contrato, chamaremos uma função que nos diz quanto Dai é retido pelo contrato:

>>> dai.functions.totalSupply().call()
10100000000000101001376883458034812485564519
Linguagem de programação: CSS (css)
Enter fullscreen mode Exit fullscreen mode

(O saldo pode ser diferente no momento em que você executa isso)

Construindo a transação

Para transferir o Dai da nossa conta da Inquisição Espanhola (my_account), usaremos a função transfer do contrato inteligente Dai, mostrada abaixo:

Transferência do token

Podemos ver que precisamos passar dois parâmetros para o contrato: to, que será um address Ethereum hexadecimal e value, que é uint256. Lidar com inteiros sem sinal de 256 bits (uint256) pode ser um desafio até mesmo para desenvolvedores experientes. É uma prova de programação incomum que precisa ser feita no nível do contrato inteligente e frequentemente me deixa confuso. Web3.py tem um método que podemos usar para converter valores de inteiro para o formato necessário para este contrato inteligente, toHex. Vamos enviar 10 Dai, e como o valor que estamos enviando está abaixo de 16, vamos apenas colocar um 0x na frente. Para address, coloque o endereço para quem você deseja enviar o Dai.

Portanto, nossa transação atualmente se parece com isso:

transaction = dai.functions.transfer(TO_ADDRESS, 0x10)

Esses parâmetros são bons para o contrato Dai (não teremos um erro lá), mas precisamos de mais parâmetros para que nossa transação seja executada na rede Ethereum. Esses valores são chainId, gas e nonce.

.buildTransaction({'chainId': 4, 
                   'gas':70000, 
                   'nonce': w3.eth.getTransactionCount(my_account._address)})
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

ChainId ajuda web3.py a saber para qual rede a transação está sendo enviada. Redes diferentes têm peculiaridades diferentes (como vimos quando instalamos o middleware Rinkeby no início) e isso ajuda web3.py a agrupar a transação corretamente. O ID de rede de Rinkeby é 4, aqui está uma lista completa de IDs de rede.

Gas é o pequeno pagamento que você faz aos mineradores na rede para executar sua transação. Muitas pessoas ficam surpresas com isso, mas o valor é pequeno (nossa transação custará 0,00007000 ETH, por exemplo, mas está demarcada em uma denominação específica chamada Gwei). Gas ajuda a administrar a rede de forma descentralizada e segura.
Nonce é uma variável global específica para cada conta Ethereum. Ele tem a mesma finalidade que o número na parte inferior do cheque: permite ordenar corretamente os pagamentos de diferentes contas. Ele aumenta um após cada transação enviada. Web3.py tem um método para encontrar o nonce atual do endereço: w3.eth.getTransactionCount(ETHEREUM_ADDRESS).

Usaremos o método web3.py .buildTransaction para incorporar essas três variáveis ​​em nossa transação. Também estou adicionando o endereço Ethereum do meu amigo e enviarei 10 Dai:

>>> transaction = dai.functions.transfer('0xafC2F2bBD4173311BE60A7f5d4103b098D2703e8', 0x10).buildTransaction({'chainId': 4, 'gas':70000, 'nonce': w3.eth.getTransactionCount('0x5b580eB23Fca4f0936127335a92f722905286738')})
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Assinar e enviar transação

Agora que temos nossa transaction, precisamos assiná-la com nossa chave privada. É assim que o protocolo ponta a ponta do Ethereum saberá que é essa conta que deseja enviar o dinheiro. Para assinar, colocamos o objeto transaction e o nosso my_account._private_key na seguinte função:

>>> signed_txn = w3.eth.account.signTransaction(transaction, '0x265434629c3d2e652550d62225adcb2813d3ac32c6e07c8c39b5cc1efbca18b3')
Linguagem de programação: JavaScript (javascript)
Enter fullscreen mode Exit fullscreen mode

Observação: Você nunca deve postar sua chave privada real online! Isso está sendo feito apenas para fins educacionais. Observação dupla: Até que esta conta seja drenada de test ether ou test dai, o comando acima será válido para a rede Rinkeby

Com nossa transação assinada, tudo o que precisamos fazer agora é enviá-la para a rede através do nosso endpoint de API Infura. Fazemos isso através do nosso objeto w3 com o seguinte comando:

>>> txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
Enter fullscreen mode Exit fullscreen mode

Se passar, parabéns! Você acabou de enviar dinheiro usando Python!

Para encontrar sua transação, você pode imprimir txn_hash e levar o valor da string para Etherscan para Rinkeby. Aqui está o hash que eu tenho (o seu será diferente!):

>>> txn_hash
HexBytes('0xc5f98cbe6f1eaef16916b148e6c4ae926b11ab9dde750e188362745da39d560e')
Linguagem de programação: JavaScript (javascript)

Enter fullscreen mode Exit fullscreen mode

Você pode vê-lo na rede de testes Ethereum aqui.

Como você pode ver, usar web3.py abre todos os tipos de possibilidades com seus aplicativos. No próximo tutorial, espero fazer algo mais desenvolvido com arquivos e diretórios adequados. Por enquanto, eu só queria mostrar algumas das opções incríveis que a blockchain pode oferecer. Espero que tenha encontrado algo interessante! A comunidade está realmente ansiosa para se envolver com novas pessoas, não deixe de entrar em contato.

Obrigado a Daniel Ellison por seus comentários e comentários, às vezes copiados literalmente!

Este artigo foi escrito por Coogan Brennan e traduzido por Marcelo Panegali. O original em inglês pode ser encontrado aqui.


Enviar dinheiro usando Python é apenas o ponto de partida; os treinamentos incríveis da WEB3DEV representam a chave de entrada para o emocionante cenário web3. 🌐 Não espere mais! Corra para o nosso site agora mesmo e garanta sua inscrição nos próximos builds. A sua empolgante jornada rumo à maestria das aplicações web3 está prestes a começar! 🚀🔗

Top comments (0)