Web3-Python-Development
January 15

Dapps Автоматизация | python

Кратко разбираем взаимодейтвие с Dapps на Python

План:

  1. Инструменты + Подготовка Окружения
  2. Код
  3. Анализ

1. Инструменты + Подготовка Окружения

Писал в прошлом материале - https://teletype.in/@vartcall/wallet_create_python

Пункт №1

2. Код

from web3 import Web3
infuraUrl = "https://sepolia.infura.io/v3/InfuraKey"
web3 = Web3(Web3.HTTPProvider(infuraUrl))
if web3.is_connected():    
    print("Connected to the Ethereum network ✅")    
    print("Current block number:", web3.eth.block_number)
    
    # let's interact with Dapps - 1. Uniswap
    uniswap_rounter_address = "0xeE567Fe1712Faf6149d80dA1E6934E354124CfE3" 
    # sepolia    
    final_uniswap_rounter_address = web3.to_checksum_address(uniswap_rounter_address)
    
    uniswap_router_abi = [        
        {            
           "constant": True,            
           "inputs": [],            
           "name": "WETH",            
           "outputs": [{"name": "", "type": "address"}],            
           "payable": False,            
           "stateMutability": "view",            
           "type": "function"        
        },        
        
        {            
           "constant": False,            
           "inputs": [                
               {"name": "amountOutMin", "type": "uint256"},                
               {"name": "path", "type": "address[]"},                
               {"name": "to", "type": "address"},                
               {"name": "deadline", "type": "uint256"}            
               ],            
               "name": "swapExactETHForTokens",            
               "outputs": [{"name": "amounts", "type": "uint256[]"}],            
               "payable": True,            
               "stateMutability": "payable",            
               "type": "function"        
          }    
       ]
    uniswap_router = web3.eth.contract(address=final_uniswap_rounter_address, abi=uniswap_router_abi)
    # get WETH from ETH
    weth_abi = [        
             {            
             "constant": False,            
             "inputs": [],            
             "name": "deposit",            
             "outputs": [],            
             "payable": True,            
             "stateMutability": "payable",            
             "type": "function"        
            },        
            
            {            
            "constant": True,            
            "inputs": [{"name": "owner", "type": "address"}],            
            "name": "balanceOf",            
            "outputs": [{"name": "balance", "type": "uint256"}],            
            "payable": False,            
            "stateMutability": "view",            
            "type": "function"        
            }    
         ]
    weth_address = uniswap_router.functions.WETH().call()    
    weth_contract = web3.eth.contract(address=weth_address, abi=weth_abi)
    amount_in_wei = web3.to_wei(0.001, "ether")  
      
    sender_address = "ВашКошелек"    
    private_key = "ВашПриватныйКлюч"    
    print("WETH address:", weth_address)
    
    # TX to swap ETH for WETH
    nonce_ETH_WETH = web3.eth.get_transaction_count(sender_address)  
      
    tx_ETH_WETH = weth_contract.functions.deposit().build_transaction({        
         'from': sender_address,        
         'value': amount_in_wei,        
         'gas': 2000000,        
         'gasPrice': web3.to_wei('50', 'gwei'),        
         'nonce': nonce_ETH_WETH    
       })
       
    signed_tx_ETH_WETH = web3.eth.account.sign_transaction(tx_ETH_WETH, private_key)    
    tx_hash_ETH_WETH = web3.eth.send_raw_transaction(signed_tx_ETH_WETH.raw_transaction)    
    print("SWAP ETH -> WETH Completed ✅")
    
    # check if WETH is at the balance    
    balance = weth_contract.functions.balanceOf(sender_address).call()    
    print("Your $WETH balance:", web3.from_wei(balance, "ether"))
    
    usdt_address = "0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0"    
    final_usdt_address = web3.to_checksum_address(usdt_address)
    
    # transaction to swap weth for usdt    
    amount_in_wei = web3.to_wei(0.01, "ether")    
    amount_out_min = web3.to_wei(0.001, "ether") # minimum amount of tokens to receive    
    path = [weth_address, final_usdt_address] 
    # weth to usdt   
    
    to = sender_address   
    deadline = web3.eth.get_block('latest')['timestamp'] + 60 * 20 # 20 minutes from now
    nonce = web3.eth.get_transaction_count(sender_address)    
    
    tx = uniswap_router.functions.swapExactETHForTokens(       
         amount_out_min,         
         path,         
         to,         
         deadline        
         ).build_transaction({ 
             'from': sender_address,            
             'value': amount_in_wei,            
             'gas': 2000000,            
             'gasPrice': web3.to_wei('60', 'gwei'),            
             'nonce': nonce        
         })        
         
     signed_tx = web3.eth.account.sign_transaction(tx, private_key)    
     tx_hash = web3.eth.send_raw_transaction(signed_tx.raw_transaction)    
     
     print("Transaction completed ✅")    
     print(f"Transaction hash: 0x{tx_hash.hex()}")
else:    
     print("Failed to connect to the Ethereum network ❌")

3. Анализ

Начнем с того, что у Uniswap есть два вида смарт-контрактов

Factory Contract Address и V2Router02 Contract Address

Factory отвечает за:

1. Создание новых пар токенов ERC-20. При вызове функции createPair(address tokenA, address tokenB) он генерирует адрес нового контракта пары для указанных токенов.

2. Управление парами: Factory отслеживает все созданные пары, предоставляя информацию о них через функции getPair(address tokenA, address tokenB) и allPairs(uint index).

3. Сборы: Factory управляет адресом получения сборов через функцию feeTo(), а также адресом, уполномоченным изменять этот адрес, через feeToSetter().

V2 Router02 отвечает за:

1. Взаимодействие с пользователями - интерфейс для пользователей (добавление ликвидность, удаление ею и обмени токенов. Он упрощает взаимодействие с парами токенов, созданными через Factory.

2. Добавление ликвидности: Функция addLiquidity(address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline) позволяет пользователям добавлять ликвидность в пул для выбранной пары токенов.

3. Удаление ликвидности: Функция removeLiquidity(address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline) позволяет удалять ликвидность из пула, получая обратно соответствующие токены.

4. Обмен токенов: Функции swapExactTokensForTokens, swapTokensForExactTokens и другие позволяют пользователям обменивать одни токены на другие, используя ликвидность, предоставленную в пулах.

Процесс работы скрипта:

  1. Получаем V2 Router02 контракт в Sepolia в документации
  2. Получаем ABI этого контракта на https://sepolia.etherscan.io/
  3. Создаем объект контракта Uniswap V2 Route (uniswap_router)
  4. Получаем ABI $WETH токена https://sepolia.etherscan.io/
  5. Получение адреса WETH из контракта маршрутизатора Uniswap (weth_address)
  6. Создание экземпляра контракта WETH (weth_contract) и выводим его адрес
  7. Указываем наш кошелек и его приватник (как получить приватный ключ?)
  8. Создаем Транзакцию для обмена $ETH -> $WETH
  9. Подписываем и отправляем эту транзакцию
  10. Проверяем наш кошелек на наличие $WETH
  11. Обмениваем $WETH -> $USDT
  12. Создаем, подписываем и отправляем транзакцию
  13. Вводим сообщение об успешном обмене токенов + хеш транзакции

Теперь мы разобрались как взаимодействовать с Dapps!

Все обновление по блокчейн-разработке в моем Telegram-Канале:

t.me/code_vartcall

всем спасибо за прочтение!

Vartcall

15.01.2025