От нуля до героя: изучение Web3 с помощью Infura и Python

От нуля до героя: изучение Web3 с помощью Infura и Python

15 апреля 2023 г.

Web3, технология блокчейна и криптовалюта – увлекательные темы. Технологии, приложения, экосистема и влияние на общество развиваются с невероятной скоростью. В этой статье мы поговорим об изучении веб-разработки с точки зрения опытного разработчика, который является полным новичком в веб-3.

Мы рассмотрим предварительные условия для разработки web3, используем Python для доступа к блокчейну через Infura, лучший сервис API web3, и рассмотрим простой проект по управлению кошельком.

С чего начать

Несмотря на то, что я программирую с конца 1990-х годов, я действительно новичок в мире web3. Я не эксперт, поэтому не буду пытаться объяснять основы.

Существует множество отличных руководств и руководств по контенту. Я предлагаю начать с документации Infura, которая очень всеобъемлющая и понятная.

Существует также дискорд сообщества, если вы предпочитаете более интерактивный стиль обучения.

В любом случае, давайте начнем с некоторых основ. Нам нужна учетная запись Infura, кошелек для хранения нашей криптовалюты и деньги для игры.

Открытие счета в Infura

Infura — поставщик API-интерфейсов блокчейна и инструментов для разработчиков. Это означает, что если вы хотите получить доступ к блокчейну, вам не нужно запускать узел самостоятельно. Вместо этого вы просто получаете доступ к дружественному API, а Infura делает всю тяжелую работу за вас.

Infura бесплатна и полностью безопасна, так как не хранит ваши закрытые ключи и не имеет возможности изменять ваши транзакции или воспроизводить их несколько раз.

Вы можете открыть здесь аккаунт бесплатно; кредитная карта не требуется.

Создание проекта Infura

В проекте все становится интересно. Каждый проект имеет ключ API, который идентифицирует его и позволяет использовать Infura. Следуйте инструкциям здесь.

Настройка криптокошелька

Следующая часть головоломки — крипто-кошелек. Здесь резина встречается с дорогой. В среде блокчейна криптокошельки содержат балансы, которые полностью контролируются набором цифровых ключей. Не существует такого понятия, как личное владение аккаунтом.

Каждая учетная запись имеет открытый ключ - который виден в блокчейне - и закрытый ключ, который контролирует учетную запись. Тот, кто владеет закрытым ключом, имеет полный контроль над учетной записью. Вы также можете управлять несколькими учетными записями как набором закрытых ключей.

Кошельки предоставляют вам безопасный способ управления вашими учетными записями/личными ключами, а также другие преимущества, такие как удобство, портативность и совместимость.

Infura рекомендует MetaMask. Вы можете установить MetaMask как расширение для браузера.

Отлично, у нас есть криптокошелек. Теперь поговорим о деньгах!

Получение денег

Блокчейн не является бесплатным. Криптоэкономика намного выше моей зарплаты, но, говоря простым языком, каждая транзакция стоит денег. Если вы хотите играть на блокчейне, вам нужны средства. К счастью для разработчиков, существуют тестовые сети, которые позволяют бесплатно получать пробные деньги.

Вы не можете обменять его на реальные деньги, но вы можете использовать его для разработки и тестирования приложений web3.

Кстати говоря, существуют разные типы сетей. Здесь мы сосредоточимся на блокчейне Ethereum.

В этом проекте я использовал тестовую сеть Sepolia. Вы можете получить тестовый ETH от Sepolia, перейдя на сайт крана. (ETH — это собственная криптовалюта Ethereum. Вы используете ее для оплаты транзакций в сети Ethereum. Тестирование ETH необходимо для разработки Ethereum.)

Сайт сборщика может перевести небольшое количество тестовой сети ETH на ваш кошелек. Некоторые сборщики потребуют от вас майнинга, чтобы заработать деньги, а некоторые будут периодически дарить вам деньги. Мне удалось успешно использовать сборщик ConsenSys Sepolia, который выдает 0,5 Sepolia ETH в день на адрес.

ХОРОШО. Мы рассмотрели все основы. Давайте проверим Infura API.

Доступ к Infura API

Infura предоставляет API JSON-RPC через HTTPS (REST) ​​и WebSockets. Он имеет несколько категорий, и вы можете прочитать о них все здесь.

Кроме того, Infura API поддерживает несколько различных сетей. Каждая сеть имеет собственную конечную точку HTTP, которую вы используете в качестве базового URL-адреса при доступе к API.

Вот конечные точки для Ethereum:

Основная сеть

* Ethereum Mainnet JSON-RPC через WebSocket — wss://mainnet.infura.io/ws/v3/

Гёрли

* Тестовая сеть Ethereum Goerli JSON-RPC через WebSocket — wss://goerli.infura.io/ws/v3 /

Сеполия

* Тестовая сеть Ethereum Sepolia JSON-RPC через WebSocket — wss://sepolia.infura.io/ws/v3 /

Просто чтобы проверить, можем ли мы получить доступ к API, давайте получим баланс нашего кошелька с помощью curl.

Я сохранил ключ API Infura и секрет ключа API в переменных среды, называемых просто:

INFURA_API_KEY и INFURA_API_KEY_SECRET. Я также сохранил открытый ключ кошелька MetaMask в переменной среды с именем SEPOLIA_ACCOUNT.

Команда curl:

$ curl --user ${INFURA_API_KEY}:${INFURA_API_KEY_SECRET} 
       -X POST 
       -H "Content-Type: application/json" 
       --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["'"${SEPOLIA_ACCOUNT}"'","latest"],"id":1}' 
  https://sepolia.infura.io/v3/${INFURA_API_KEY}

{"jsonrpc":"2.0","id":1,"result":"0x1d7e6e62f1523600"}

Как видите, у меня ОГРОМНЫЙ баланс 0x1d7e6e62f1523600!!!! Но не нужно слишком волноваться; балансовые единицы - Вэй. Один ETH равен 10^18 Wei. Если мы подсчитаем цифры, то увидим, что на моем счету чуть больше 2 ETH. Конечно, это все деньги тестовой сети.

Обратите внимание, что мне не нужно было использовать закрытый ключ моей учетной записи для проверки баланса. Любой желающий может проверить баланс любой учетной записи в блокчейне. Баланс любого счета не является конфиденциальной информацией.

Однако личность учетной записи и лица, владеющего закрытым ключом, является важной и конфиденциальной.

Хорошо… мы повеселились, напрямую обратившись к Infura API. Давайте напишем код.

Разработка Web3 с помощью Python

Экосистема web3 поддерживает множество языков программирования. Доступ к API-интерфейсам Infura можно получить из популярных библиотек на JavaScript (web3.js и ethers.js), Golang (github.com/ethereum/go- Ethereum) и Python (web3.py).

Выберите свое оружие  — web3.py

Несмотря на то, что кодирование в настоящее время в основном выполняется на JavaScript/Node.js и Ruby, Python отлично подходит для изучения новой темы. Библиотека web3.py кажется мощной, зрелой и хорошо документированной. Итак, я решил пойти с ним.

Выберите цель — Управление кошельком

Мир web3 может быть ошеломляющим: транзакции, смарт-контракты, IPFS, DAO (децентрализованные автономные организации), defi (децентрализованные финансы) и NFT. Я решил выбрать простую концепцию менеджера кошелька для этого тестового проекта web3.

Менеджер кошелька — это своего рода проект «Hello Web3 World», потому что все, что он делает, — это получает ваш баланс и отправляет деньги на счет назначения. Поскольку я получил свои деньги от сборщика Sepolia, я решил вернуть часть средств. Давайте проверим код.

Децентрализованное приложение Web3-Test

Код доступен на Github здесь. (Особая благодарность the-gigi!)

Я использовал Poetry для создания каркаса приложения. README содержит пошаговые инструкции по настройке.

Прежде чем мы углубимся в код, давайте запустим программу и посмотрим, что произойдет:

$ poetry run python main.py

balance before transaction: 2.1252574454
send 20,000 gwei to 0xea4d57b2dd421c5bfc893d126ec15bc42b3d0bcd (Sepolia faucet account)
balance after transaction: 2.125184945399832

Как видите, мой баланс изначально был чуть больше 2 ETH тестовой сети. Затем я отправил 20 000 Gwei (что составляет 20 миллиардов Wei) на счет сборщика Sepolia, с которого я получил деньги в первую очередь. Как видите, это почти не повлияло на мой баланс. Это просто показывает, насколько крошечной единицей является Вэй.

Код довольно прост. Есть только один файл с именем main.py. Файл содержит функцию main() и класс WalletManager. Начнем с функции main(), которая является точкой входа в программу.

Функция main() не принимает аргументов командной строки или файлов конфигурации. Все жестко закодировано для простоты. Во-первых, функция создает экземпляр класса WalletManager; затем он определяет открытый ключ учетной записи сборщика Sepolia.

Теперь приступаем к действию. Функция получает баланс кошелька, вызывая метод get_balance() WalletManager; затем он передает запрошенный блок (эфир) и отображает его на экране.

Затем функция вызывает метод send_eth() для отправки 20 000 Gwei на целевой аккаунт. Наконец, он снова получает и отображает баланс после отправки денег.

def main():
    wm = WalletManager()

    sepolia_faucet_account = wm.w3.toChecksumAddress('0xea4d57b2dd421c5bfc893d126ec15bc42b3d0bcd')

    balance = str(wm.get_balance('ether'))
    print(f'balance before transaction: {balance}')

    print(f'send 20,000 gwei to {sepolia_faucet_account} (Sepolia faucet account)')
    wm.send_eth(sepolia_faucet_account, 20000, 'gwei')

    balance = str(wm.get_balance('ether'))
    print(f'balance after transaction: {balance}')

if __name__ == '__main__':
    main()

Давайте рассмотрим класс WalletManager. Он имеет четыре метода:

  1. __init__()
  2. __create_web3_instance()
  3. get_balance()
  4. sent_eth()

Способ 1: __init__()

Давайте рассмотрим их один за другим. Метод __init__(), который является конструктором, сначала вызывает метод __create_web3_instance() и сохраняет результат в переменной с именем w3.

Затем __init__() извлекает пару переменных окружения и сохраняет их. Он продолжает вычислять пару комиссий за газ (это топливо, на котором работает блокчейн) и вознаграждения, которые получают люди, подтверждающие транзакции.

Если вы хотите узнать больше о газе и сборах, прочитайте это.

Он также хранит идентификатор цепочки, который идентифицирует тестовую сеть Sepolia (в данном случае). Этот идентификатор понадобится нам позже при отправке транзакций в тестовую сеть Sepolia.

import base64
import os
import web3

class WalletManager:
    def __init__(self):
        self.w3 = self.__create_web3_instance()
        self.account = os.environ['SEPOLIA_ACCOUNT']
        self.account_private_key = os.environ['METAMASK_PRIVATE_KEY']
        self.max_fee_per_gas = self.w3.toWei('250', 'gwei')
        self.max_priority_fee_per_gas = self.w3.eth.max_priority_fee
        self.chain_id = self.w3.eth.chain_id

Способ 2: __create_web3_instance()

Давайте посмотрим, что происходит внутри метода __create_web3_instance(). __create_web3_instance() — это статический метод, поскольку ему не требуется никакой информации из класса WalletManager.

Он получает ключ API Infura и секрет ключа API из среды, а затем кодирует их в токен базовой аутентификации. Он подготавливает надлежащую конечную точку для нашего проекта в тестовой сети Sepolia, а затем создает экземпляр объекта web3 из библиотеки web3 со всей информацией.

Этот объект позволит нам вызывать Infura API через удобный интерфейс Python (вместо построения запросов JSON-RPC и анализа результатов).

@staticmethod
def __create_web3_instance():
    infura_api_key = os.environ['INFURA_API_KEY']
    infura_api_key_secret = os.environ['INFURA_API_KEY_SECRET']
    data = f'{infura_api_key}:{infura_api_key_secret}'.encode('ascii')
    basic_auth_token = base64.b64encode(data).strip().decode('utf-8')

    infura_sepolia_endpoint = f'https://sepolia.infura.io/v3/{infura_api_key}'

    headers = dict(Authorization=f'Basic {basic_auth_token}')
    return web3.Web3(web3.HTTPProvider(infura_sepolia_endpoint, request_kwargs=dict(headers=headers)))

Способ 3: get_balance()

Хорошо, следующий метод get_balance().

Это чрезвычайно простой метод. Он просто вызывает метод w3.eth.get_balance() объекта web3 и передает нашу учетную запись. eth.get_balance() всегда возвращает результат в формате Wei, который часто слишком мал.

Наш метод дает нам возможность преобразовать результат в другое наименование, такое как Gwei или Ether. Он делает это, вызывая метод w3.fromWei(), предоставленный нашим экземпляром web3. Обратите внимание, что нам не нужно было использовать наш закрытый ключ для проверки баланса.

balance = self.w3.eth.get_balance(selpytf.account)
if unit != 'wei':
    return self.w3.fromWei(balance, unit)

Способ 4: send_eth()

Последним, но не менее важным, является метод send_eth(). Здесь много всего происходит, поэтому давайте разобьем его на несколько блоков.

Сначала send_eth() преобразует сумму для отправки в Wei (при необходимости), а затем получает количество транзакций учетной записи и сохраняет его как одноразовый номер. Одноразовый номер позволяет нам перезаписывать ожидающие транзакции, если это необходимо.

def send_eth(self, target_account, amount, unit='wei'):
    if unit != 'wei':
        amount = self.w3.toWei(amount, unit)

    nonce = self.w3.eth.get_transaction_count(self.account)

Затем он создает объект транзакции. Наиболее важными полями являются from (учетная запись кошелька), to (получатель транзакции) и value (сколько отправить) . Затем есть поля, которые определяют, сколько газа платить.

(Чем больше газа, тем больше вероятность того, что валидаторы включат транзакцию.) chainId идентифицирует сеть, в которой будет выполняться эта транзакция, и несколько административных полей (пустые данные и тип).

tx = {'nonce': nonce,
      'maxFeePerGas': self.max_fee_per_gas,
      'maxPriorityFeePerGas': self.max_priority_fee_per_gas,
      'from': self.account,
      'to': target_account,
      'value': amount,
      'data': b'',
      'type': 2,
      'chainId': self.chain_id}
tx['gas'] = self.w3.eth.estimate_gas(tx)

ХОРОШО. У нас есть транзакция, можем ли мы ее отправить? Не так быстро. Во-первых, нам нужно подписать его нашим закрытым ключом. Это то, что не позволяет другим людям переводить деньги с нашего счета.

Подписание транзакции закрытым ключом позволяет валидаторам подтвердить, что закрытый ключ соответствует открытому ключу аккаунта.

signed_tx = self.w3.eth.account.sign_transaction(tx, self.account_private_key)

Теперь мы можем отправить транзакцию как необработанную транзакцию. Это означает, что Infura никогда не увидит наш закрытый ключ и не сможет изменить нашу транзакцию или направить наш перевод на другую учетную запись. Это магия блокчейна в действии.

После отправки транзакции мы получаем хэш-код и ждем завершения транзакции. Если статус результата равен 1, то все хорошо. В противном случае код вызывает исключение.

tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)

result = self.w3.eth.wait_for_transaction_receipt(tx_hash)
if result['status'] != 1:
    raise RuntimeError('transaction failed: {tx_hash}')

Это все, что нужно для простейшего, но безопасного взаимодействия с блокчейном.

Заключение: начните свое путешествие в Web3 с Infura

Погружение с головой в мир web3 может быть пугающим даже для опытного программиста. Мы многому научились; в основном, мы узнали, что нам нужно еще многому научиться!

Infura упростила задачу, предоставив надежный API, отличное руководство и надежную интеграцию с другими компонентами экосистемы, такими как MetaMask и библиотека web3.py.

Если вы находитесь в аналогичном положении и хотите изучить разработку веб-3 - или даже хотите начать карьеру в веб3 - я настоятельно рекомендую начать с Infura. Посмотрите, куда вас приведет путешествие!


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE