| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Получить адрес из приватного ключа | crypto.HexToECDSA(), crypto.PubkeyToAddress() |
Адрес common.Address |
| Получить nonce для адреса | client.PendingNonceAt(ctx, fromAddress) |
Число uint64 — номер следующей транзакции |
| Получить цену газа (legacy) | client.SuggestGasPrice(ctx) |
*big.Int — цена за газ |
| Создать транзакцию (legacy) | types.NewTransaction(nonce, to, value, gasLimit, gasPrice, data) |
*types.Transaction |
| Подписать транзакцию | types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey) |
Подписанный *types.Transaction |
| Отправить транзакцию | client.SendTransaction(ctx, signedTx) |
Ошибка или nil, tx hash можно получить через signedTx.Hash() |
// Пример: получить адрес из приватного ключа
privateKey, _ := crypto.HexToECDSA("your_private_key_hex")
publicKey := privateKey.Public()
publicKeyECDSA := publicKey.(*ecdsa.PublicKey)
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
fmt.Println("Address:", fromAddress.Hex())
// Получить nonce для адреса
nonce, err := client.PendingNonceAt(ctx, fromAddress)
// Получить цену газа (legacy)
gasPrice, err := client.SuggestGasPrice(ctx)
// Создать и подписать транзакцию
tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
// Отправить транзакцию
err = client.SendTransaction(ctx, signedTx)
fmt.Println("Tx sent! Hash:", signedTx.Hash().Hex())| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Создать объект ABI из JSON | abi.JSON(strings.NewReader(abiJSON)) |
abi.ABI |
| Закодировать вызов метода | contractABI.Pack("methodName", params...) |
Байты calldata |
| Выполнить call (без газа) | client.CallContract(ctx, ethereum.CallMsg{To: &address, Data: data}, nil) |
Результат (байты), которые потом нужно декодировать |
| Раскодировать ответ | contractABI.Unpack("methodName", returnedBytes) |
Распарсенные значения |
// Загрузить ABI
contractABI, err := abi.JSON(strings.NewReader(abiJSON))
// Запаковать вызов метода (без аргументов)
data, err := contractABI.Pack("methodName")
// Выполнить вызов
msg := ethereum.CallMsg{
To: &contractAddress,
Data: data,
}
res, err := client.CallContract(ctx, msg, nil)
// Распаковать результат
var result YourReturnType
err = contractABI.UnpackIntoInterface(&result, "methodName", res)
fmt.Println("Result:", result)| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Заполнить calldata вызова | contractABI.Pack("methodName", params...) |
Байты calldata |
| Получить gas estimate | client.EstimateGas(ctx, ethereum.CallMsg{From: ..., To: &address, Data: calldata, Value: ...}) |
gasLimit uint64 |
| Создать и подписать транзакцию | types.NewTransaction(...), types.SignTx(...) |
Подписанная транзакция |
| Отправить транзакцию | client.SendTransaction(ctx, signedTx) |
tx hash |
// Подготовить calldata
data, err := contractABI.Pack("methodName", arg1, arg2)
// Оценить gasLimit
msg := ethereum.CallMsg{
From: fromAddress,
To: &contractAddress,
Data: data,
Value: big.NewInt(0),
}
gasLimit, err := client.EstimateGas(ctx, msg)
// Создать и подписать транзакцию
tx := types.NewTransaction(nonce, contractAddress, big.NewInt(0), gasLimit, gasPrice, data)
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
// Отправить
err = client.SendTransaction(ctx, signedTx)
fmt.Println("Tx sent! Hash:", signedTx.Hash().Hex())
| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Создать фильтр логов | ethereum.FilterQuery{Addresses: []common.Address{contractAddress}, Topics: [][]common.Hash{...}} |
Фильтр для события |
| Получить логи | client.FilterLogs(ctx, query) |
Список логов |
| Раскодировать логи | contractABI.Unpack(eventName, log.Data) |
Распарсенные данные событий |
// Создать фильтр
query := ethereum.FilterQuery{
Addresses: []common.Address{contractAddress},
Topics: [][]common.Hash{{contractABI.Events["EventName"].ID}},
}
// Получить логи
logs, err := client.FilterLogs(ctx, query)
// Раскодировать логи
for _, vLog := range logs {
var event EventStruct
err := contractABI.UnpackIntoInterface(&event, "EventName", vLog.Data)
fmt.Println("Event:", event)
}
| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Считать баланс токенов | Вызвать balanceOf(address) через CallContract |
Баланс в *big.Int |
| Отправить токены | Создать транзакцию с calldata для transfer(to, amount) |
Отправленная tx, проверка в Etherscan |
// Вызов balanceOf
data, _ := contractABI.Pack("balanceOf", userAddress)
res, _ := client.CallContract(ctx, ethereum.CallMsg{To: &erc20Address, Data: data}, nil)
var balance *big.Int
contractABI.UnpackIntoInterface(&balance, "balanceOf", res)
fmt.Println("Balance:", balance.String())
| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Резолвить имя в адрес | Вызвать resolver.addr(namehash) через контракт ENS |
common.Address |
| Получить запись TXT/ABI | Вызов методов text / abi из ENS контракта |
Соответствующие данные |
// Подключиться к ENS контракту (адрес в mainnet: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e)
// Сделать call к функции resolver
// Затем вызвать resolver.addr(namehash)
// Для namehash и других утилит можно использовать github.com/wealdtech/go-ens
// Пример вызова резолвера — чуть сложнее, нужно посмотреть go-ens репозиторий
| Что делать | Go-ethereum методы / структуры | Результат / проверка |
|---|---|---|
| Получить блок по номеру | client.BlockByNumber(ctx, number) |
Структура types.Block |
| Получить транзакцию по хешу | client.TransactionByHash(ctx, txHash) |
types.Transaction |
| Получить receipt по транзакции | client.TransactionReceipt(ctx, txHash) |
types.Receipt |
// Получить блок по номеру
block, err := client.BlockByNumber(ctx, big.NewInt(1234567))
fmt.Println("Block hash:", block.Hash().Hex())
fmt.Println("Transactions count:", len(block.Transactions()))
// Получить транзакцию по хешу
tx, _, err := client.TransactionByHash(ctx, txHash)
fmt.Println("Tx to:", tx.To().Hex())
// Получить receipt транзакции
receipt, err := client.TransactionReceipt(ctx, txHash)
fmt.Println("Gas used:", receipt.GasUsed)
Проверять ошибку после каждого вызова
Использовать context с таймаутами
Логировать tx.Hash() для отслеживания в Etherscan
Сравнивать gas estimate и реально использованный газ (receipt.GasUsed)
📌 Что ты сделаешь:
CLI- или TUI-интерфейс на Go для депозита ETH из L1 в L2 через официальный bridge.
Используешь go-ethereum, ABI-вызывальщик, EstimateGas, SuggestGasPrice, types.NewTransaction.
Обрабатываешь очередь tx, подписываешь через keystore или ledger.
🎯 Цель:
Понимание взаимодействия между L1 ↔ L2.
Работа с gas, nonce, chainID, value.
📌 Что ты сделаешь:
Go-сервис, который подписан на новые блоки и следит за адресами.
При приходе средств отправляет уведомление в Telegram (через Bot API).
Расширяемость: можно логировать все входящие транзакции, мониторить ERC20-токены.
🎯 Цель:
Работа с ethclient.SubscribeNewHead, FilterLogs, event topics.
Интерфейс между блокчейном и «реальным миром» (бот, оповещение).
📌 Что ты сделаешь:
Коннект к Uniswap Router (или 1inch API), обёртка вокруг swapExactETHForTokens.
Подсчёт слippage, расчёт gas, расчёт цены из getAmountsOut.
Использование Oracle (Chainlink) для расчёта курса.
🎯 Цель:
Понимание реальной DeFi-механики.
Работа с Router ABI, callOpts, transactOpts.