Dapps Автоматизация | python
Кратко разбираем взаимодейтвие с Dapps на Python
План:
1. Инструменты + Подготовка Окружения
Писал в прошлом материале - https://teletype.in/@vartcall/wallet_create_python
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
1. Создание новых пар токенов ERC-20. При вызове функции createPair(address tokenA, address tokenB) он генерирует адрес нового контракта пары для указанных токенов.
2. Управление парами: Factory отслеживает все созданные пары, предоставляя информацию о них через функции getPair(address tokenA, address tokenB) и allPairs(uint index).
3. Сборы: Factory управляет адресом получения сборов через функцию feeTo(), а также адресом, уполномоченным изменять этот адрес, через feeToSetter().
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 и другие позволяют пользователям обменивать одни токены на другие, используя ликвидность, предоставленную в пулах.
Процесс работы скрипта:
- Получаем V2 Router02 контракт в Sepolia в документации
- Получаем ABI этого контракта на https://sepolia.etherscan.io/
- Создаем объект контракта Uniswap V2 Route (uniswap_router)
- Получаем ABI $WETH токена https://sepolia.etherscan.io/
- Получение адреса WETH из контракта маршрутизатора Uniswap (weth_address)
- Создание экземпляра контракта WETH (weth_contract) и выводим его адрес
- Указываем наш кошелек и его приватник (как получить приватный ключ?)
- Создаем Транзакцию для обмена $ETH -> $WETH
- Подписываем и отправляем эту транзакцию
- Проверяем наш кошелек на наличие $WETH
- Обмениваем $WETH -> $USDT
- Создаем, подписываем и отправляем транзакцию
- Вводим сообщение об успешном обмене токенов + хеш транзакции
Теперь мы разобрались как взаимодействовать с Dapps!
Все обновление по блокчейн-разработке в моем Telegram-Канале: