Погружение в EIP-7702. Часть 3
Полный account abstraction предполагает, что каждый аккаунт в Ethereum будет представлять собой смарт-аккаунт, что приведет к существенным улучшениям как в плане безопасности, так и в плане удобства использования:
1. Больше схем подписи: В настоящее время EOA поддерживают только один тип подписи. С полной account abstraction станет возможным использование множества схем подписи, включая варианты, работающие со смартфонами и другими устройствами (например, passkeys). Это значительно повысит безопасность и удобство использования.
2. Опции восстановления по умолчанию: Смарт-аккаунты могли бы предлагать встроенные функции восстановления по умолчанию, или же пользователи могли бы легко отказаться от них. Это значительно снизит риск потери средств из-за ошибок или утери приватных ключей.
3. Спонсируемые транзакции: Каждый смарт-аккаунт будет иметь возможность подписывать спонсируемые транзакции. Это избавит пользователей от необходимости беспокоиться о комиссиях за газ и управлении цепочками, позволяя им сосредоточиться исключительно на удобстве и прибыльности dapp, с которой они взаимодействуют.
Пакетные транзакции и сеансовые ключи: Смарт-аккаунты могут «входить» в dapps, обеспечивая пользовательский опыт, схожий с централизованными приложениями. Это позволит быстро и без проблем осуществлять такие действия, как торговля и игры, без необходимости постоянного одобрения транзакций.
Шаги по достижению полной account abstraction
Для того, чтобы полностью реализовать АА, необходимо осуществить несколько ключевых изменений:
1. Интеграция ядра: АА должна быть полностью встроена в основной протокол Ethereum. В то время как ERC-4337 в настоящее время работает на прикладном уровне, усовершенствования на уровне протокола, такие как RIP-7560, сделают транзакции более газоэффективными и объединят все транзакции под одним мемпулом, устранив необходимость в отдельном мемпуле для операций ERC-4337.
2. Смарт-аккаунты по умолчанию: Все новые учетные записи Ethereum по умолчанию должны быть смарт-аккаунтами, при этом новые EOA создаваться не будут. Новые пользователи с самого начала смогут воспользоваться расширенными возможностями смарт-аккаунтов.
3. Перенос EOA на смарт-аккаунты: Существующие EOA необходимо преобразовать в Smart Accounts. Это особенно важно для пользователей, которые хотят сохранить свои оригинальные адреса из-за ценных непередаваемых активов, таких как soul-bound tokens. EIP-7702 играет решающую роль в этом переходе, но для удаления доступа к закрытому ключу EOA необходимы дополнительные меры. Ключевую роль здесь играет EIP-3607, который отменяет доступ к закрытому ключу, если аккаунт содержит код.
Проверка подписи
Смарт-аккаунты уже могут проверять подписи с помощью EIP-1271. Для завершения миграции необходимо обновить процессы проверки подписи, чтобы проверить, является ли подписант EOA или Смарт-аккаунтом. Если это Смарт-аккаунт, то подписи на основе закрытых ключей больше не должны валидироваться.
Соображения по поводу внесетевой проверки
Проверка подписи вне сети также должна учитывать возможность того, что учетная запись может быть EOA в одной сети, но Smart Account в другой. Верификаторы подписей должны быть ориентированы на конкретную сеть, обеспечивая правильную проверку подписей в зависимости от сети, из которой они были получены.
Такой оптимизированный путь к полной account abstraction в конечном итоге позволит создать бесшовную, безопасную и высокомасштабируемую экосистему Ethereum, в которой каждый аккаунт сможет воспользоваться расширенными возможностями смарт-аккаунтов.
#eip7702
Полный account abstraction предполагает, что каждый аккаунт в Ethereum будет представлять собой смарт-аккаунт, что приведет к существенным улучшениям как в плане безопасности, так и в плане удобства использования:
1. Больше схем подписи: В настоящее время EOA поддерживают только один тип подписи. С полной account abstraction станет возможным использование множества схем подписи, включая варианты, работающие со смартфонами и другими устройствами (например, passkeys). Это значительно повысит безопасность и удобство использования.
2. Опции восстановления по умолчанию: Смарт-аккаунты могли бы предлагать встроенные функции восстановления по умолчанию, или же пользователи могли бы легко отказаться от них. Это значительно снизит риск потери средств из-за ошибок или утери приватных ключей.
3. Спонсируемые транзакции: Каждый смарт-аккаунт будет иметь возможность подписывать спонсируемые транзакции. Это избавит пользователей от необходимости беспокоиться о комиссиях за газ и управлении цепочками, позволяя им сосредоточиться исключительно на удобстве и прибыльности dapp, с которой они взаимодействуют.
Пакетные транзакции и сеансовые ключи: Смарт-аккаунты могут «входить» в dapps, обеспечивая пользовательский опыт, схожий с централизованными приложениями. Это позволит быстро и без проблем осуществлять такие действия, как торговля и игры, без необходимости постоянного одобрения транзакций.
Шаги по достижению полной account abstraction
Для того, чтобы полностью реализовать АА, необходимо осуществить несколько ключевых изменений:
1. Интеграция ядра: АА должна быть полностью встроена в основной протокол Ethereum. В то время как ERC-4337 в настоящее время работает на прикладном уровне, усовершенствования на уровне протокола, такие как RIP-7560, сделают транзакции более газоэффективными и объединят все транзакции под одним мемпулом, устранив необходимость в отдельном мемпуле для операций ERC-4337.
2. Смарт-аккаунты по умолчанию: Все новые учетные записи Ethereum по умолчанию должны быть смарт-аккаунтами, при этом новые EOA создаваться не будут. Новые пользователи с самого начала смогут воспользоваться расширенными возможностями смарт-аккаунтов.
3. Перенос EOA на смарт-аккаунты: Существующие EOA необходимо преобразовать в Smart Accounts. Это особенно важно для пользователей, которые хотят сохранить свои оригинальные адреса из-за ценных непередаваемых активов, таких как soul-bound tokens. EIP-7702 играет решающую роль в этом переходе, но для удаления доступа к закрытому ключу EOA необходимы дополнительные меры. Ключевую роль здесь играет EIP-3607, который отменяет доступ к закрытому ключу, если аккаунт содержит код.
Проверка подписи
Смарт-аккаунты уже могут проверять подписи с помощью EIP-1271. Для завершения миграции необходимо обновить процессы проверки подписи, чтобы проверить, является ли подписант EOA или Смарт-аккаунтом. Если это Смарт-аккаунт, то подписи на основе закрытых ключей больше не должны валидироваться.
Соображения по поводу внесетевой проверки
Проверка подписи вне сети также должна учитывать возможность того, что учетная запись может быть EOA в одной сети, но Smart Account в другой. Верификаторы подписей должны быть ориентированы на конкретную сеть, обеспечивая правильную проверку подписей в зависимости от сети, из которой они были получены.
Такой оптимизированный путь к полной account abstraction в конечном итоге позволит создать бесшовную, безопасную и высокомасштабируемую экосистему Ethereum, в которой каждый аккаунт сможет воспользоваться расширенными возможностями смарт-аккаунтов.
#eip7702
👍3
Погружение в EIP-7702. Часть 4
Итак, как мы знаем, EIP-7702 представляет новый тип транзакции 0x04 в обновлении Pectra для Ethereum, который позволяет аккаунтами, принадлежащим внешним пользователям (EOA), выполнять временные функции смарт-контракта. Это усовершенствование Account Abstraction устраняет разрыв между EOA и смарт-контрактами, позволяя реализовать такие ключевые функции, как пакетные транзакции, спонсируемые платежи и контролируемое делегирование доступа.
EIP-7702 теперь активен в основной сети Ethereum, а также в тестовых сетях, таких как Sepolia, как часть обновления Pectra. Разработчики могут протестировать EIP-7702 в локальных средах Foundry - либо в свежей локальной сети, либо с помощью форка mainnet.
Транзакции EIP-7702
В то время как обычные транзакции Ethereum либо переводят средства, либо взаимодействуют со смарт-контрактами, новый тип транзакций 0x04 позволяет EOA выполнять код напрямую.
Благодаря новому стандарту EOA могут выполнять логику смарт-контракта непосредственно со своего собственного адреса, что делает возможным:
1. Пакетные транзакции: Объединять несколько действий в одну атомарную транзакцию (одобрение токенов, обмен, передача).
2. Делегирование ограниченного доступа: Предоставление временных, ограниченных полномочий без раскрытия ключей.
3. Спонсорство: Позволяет третьей стороне (например, paymaster) покрывать комиссию за газ для ваших транзакций.
4. Восстановление кошелька: Реализуйте механизм восстановления при потере приватного ключа.
Подписание авторизации
Пользователь (EOA) подписывает сообщение авторизации, которое включает в себя идентификатор цепочки, nonce, адрес делегирования и части подписи (y_parity, r, s). В результате генерируется подписанная авторизация, гарантирующая, что только утвержденный контракт может выполнять транзакции, и защищающая от атак повторного воспроизведения.
Для каждого разрешенного адреса делегирования пользователь (EOA) хранит обозначение делегирования - указатель на контракт реализации, которому EOA будет делегировать полномочия. Когда пользователь (или спонсор) выполняет транзакцию EIP-7702, он загружает и запускает код с адреса, указанного этим указателем.
Конструкция транзакции
В типичной транзакции Ethereum, если вы хотите вызвать функцию смарт-контракта, вы устанавливаете в поле to адрес этого контракта и включаете соответствующие данные для вызова его функции. В EIP-7702 вы устанавливаете в поле to адрес EOA и включаете данные для вызова функции контракта реализации в подписанное сообщение авторизации.
Анатомия транзакции EIP-7702
Приведенный ниже фрагмент кода демонстрирует, как с помощью клиента кошелька Viem создать пакетную транзакцию для смарт-аккаунта EIP-7702.
1. Он генерирует авторизационную подпись для определенного контракта.
2. Затем создается транзакция, в которой в поле to устанавливается собственный адрес смарт-счета.
3. Поле данных создается путем кодирования вызова функции execute с помощью массива из двух объектов call. Функция execute должна быть определена в контракте реализации и обрабатывать логику пакетной транзакции.
4. Наконец, транзакция включает подписанную авторизацию в authorizationList, что позволяет смарт-аккаунту делегировать выполнение контракту реализации.
Если другой кошелек (спонсор) захочет выполнить эту транзакцию (спонсируемая транзакция), он может использовать ту же подпись авторизации, чтобы делегировать выполнение контракту реализации.
Примечание: Контракты должны быть разработаны для обработки пакетных транзакций и других возможностей, предусмотренных EIP-7702. Кроме того, они должны включать механизмы защиты.
#eip7702
Итак, как мы знаем, EIP-7702 представляет новый тип транзакции 0x04 в обновлении Pectra для Ethereum, который позволяет аккаунтами, принадлежащим внешним пользователям (EOA), выполнять временные функции смарт-контракта. Это усовершенствование Account Abstraction устраняет разрыв между EOA и смарт-контрактами, позволяя реализовать такие ключевые функции, как пакетные транзакции, спонсируемые платежи и контролируемое делегирование доступа.
EIP-7702 теперь активен в основной сети Ethereum, а также в тестовых сетях, таких как Sepolia, как часть обновления Pectra. Разработчики могут протестировать EIP-7702 в локальных средах Foundry - либо в свежей локальной сети, либо с помощью форка mainnet.
Транзакции EIP-7702
В то время как обычные транзакции Ethereum либо переводят средства, либо взаимодействуют со смарт-контрактами, новый тип транзакций 0x04 позволяет EOA выполнять код напрямую.
Благодаря новому стандарту EOA могут выполнять логику смарт-контракта непосредственно со своего собственного адреса, что делает возможным:
1. Пакетные транзакции: Объединять несколько действий в одну атомарную транзакцию (одобрение токенов, обмен, передача).
2. Делегирование ограниченного доступа: Предоставление временных, ограниченных полномочий без раскрытия ключей.
3. Спонсорство: Позволяет третьей стороне (например, paymaster) покрывать комиссию за газ для ваших транзакций.
4. Восстановление кошелька: Реализуйте механизм восстановления при потере приватного ключа.
Подписание авторизации
Пользователь (EOA) подписывает сообщение авторизации, которое включает в себя идентификатор цепочки, nonce, адрес делегирования и части подписи (y_parity, r, s). В результате генерируется подписанная авторизация, гарантирующая, что только утвержденный контракт может выполнять транзакции, и защищающая от атак повторного воспроизведения.
Для каждого разрешенного адреса делегирования пользователь (EOA) хранит обозначение делегирования - указатель на контракт реализации, которому EOA будет делегировать полномочия. Когда пользователь (или спонсор) выполняет транзакцию EIP-7702, он загружает и запускает код с адреса, указанного этим указателем.
Конструкция транзакции
В типичной транзакции Ethereum, если вы хотите вызвать функцию смарт-контракта, вы устанавливаете в поле to адрес этого контракта и включаете соответствующие данные для вызова его функции. В EIP-7702 вы устанавливаете в поле to адрес EOA и включаете данные для вызова функции контракта реализации в подписанное сообщение авторизации.
Анатомия транзакции EIP-7702
Приведенный ниже фрагмент кода демонстрирует, как с помощью клиента кошелька Viem создать пакетную транзакцию для смарт-аккаунта EIP-7702.
1. Он генерирует авторизационную подпись для определенного контракта.
2. Затем создается транзакция, в которой в поле to устанавливается собственный адрес смарт-счета.
3. Поле данных создается путем кодирования вызова функции execute с помощью массива из двух объектов call. Функция execute должна быть определена в контракте реализации и обрабатывать логику пакетной транзакции.
4. Наконец, транзакция включает подписанную авторизацию в authorizationList, что позволяет смарт-аккаунту делегировать выполнение контракту реализации.
Если другой кошелек (спонсор) захочет выполнить эту транзакцию (спонсируемая транзакция), он может использовать ту же подпись авторизации, чтобы делегировать выполнение контракту реализации.
Примечание: Контракты должны быть разработаны для обработки пакетных транзакций и других возможностей, предусмотренных EIP-7702. Кроме того, они должны включать механизмы защиты.
#eip7702
👍6❤1
Погружение в EIP-7702. Часть 5
Вот представленный код из предыдущего поста и его визуальное представление.
А дальше мы поговорим, как все протестировать в Foundry.
#eip7702
Вот представленный код из предыдущего поста и его визуальное представление.
import { createWalletClient, http, parseEther } from 'viem'
import { anvil } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'
import { eip7702Actions } from 'viem/experimental'
import { abi, contractAddress } from './contract' // Assuming you have already deployed the contract and exported the ABI and contract address in a separate file
const account = privateKeyToAccount('0x...')
const walletClient = createWalletClient({
account,
chain: anvil,
transport: http(),
}).extend(eip7702Actions())
const authorization = await walletClient.signAuthorization({
contractAddress,
})
const hash = await walletClient.sendTransaction({
authorizationList: [authorization],
data: encodeFunctionData({
abi,
functionName: 'execute',
args: [
[
{
data: '0x',
to: '0xcb98643b8786950F0461f3B0edf99D88F274574D',
value: parseEther('0.001'),
},
{
data: '0x',
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.002'),
},
],
]
}),
to: walletClient.account.address,
})А дальше мы поговорим, как все протестировать в Foundry.
#eip7702
👍3
Погружение в EIP-7702. Часть 6
Сегодня начнем разбирать тему тестирования контрактов с EIP-7702 в Foundry. И для начала нам потребуется некоторая подготовительная работа.
Создадим проект и папку, установим зависимости и настроим remapping:
Теперь нам нужно обновить версию EVM для корректных тестов. Измените файл foundry.toml, чтобы обеспечить совместимость с EIP-7702, установив хардфорк Prague. Добавьте следующую строку в раздел [profile.default]:
Это необходимо, поскольку EIP-7702 доступен только с обновления Prague и далее.
Очистите преднастроенные контракты, тесты и скрипты. В папку src добавьте файл BatchCallAndSponsor, в папку test - файл BatchCallAndSponsor.t.sol, в папку noscript - файл BatchCallAndSponsor.s.sol из приложения к посту.
Контракт BatchCallAndSponsor - это простой контракт логики, который поддерживает пакетные транзакции и спонсорский газ.
P.S. Полный вариант реализации смотрите в файле BatchCallAndSponsor.sol. А в приведенных ниже контрактах дается краткий обзор возможностей.
Функция execute в контракте принимает массив структур Call, каждая из которых представляет отдельный вызов и указывает целевой адрес, значение (в Ether) и данные calldata.
Контракт проверяет подпись с помощью библиотеки OpenZeppelin ECDSA и MessageHashUtils. Подписанное сообщение содержит адрес вызывающей стороны, целевой контракт и вызовы.
В контракте поддерживается либо прямое, либо спонсируемое исполнение.
1. Прямое исполнение: Вызывающая сторона сама выполняет вызовы.
2. Спонсируемое исполнение: Спонсор выполняет вызовы от имени вызывающего абонента после проверки подписи, сделанной EOA.
Для предотвращения атак повторного воспроизведения в контракте используется nonce. После каждого успешного выполнения транзакции значение nonce увеличивается. Если бы nonce не был реализован, злоумышленник мог бы воспроизвести одну и ту же транзакцию несколько раз.
Далее поговорим о самих тестах.
#eip7702
Сегодня начнем разбирать тему тестирования контрактов с EIP-7702 в Foundry. И для начала нам потребуется некоторая подготовительная работа.
Создадим проект и папку, установим зависимости и настроим remapping:
forge init eip-7702-project
cd eip-7702-project
forge install foundry-rs/forge-std
forge install OpenZeppelin/openzeppelin-contracts
forge remappings > remappings.txt
Теперь нам нужно обновить версию EVM для корректных тестов. Измените файл foundry.toml, чтобы обеспечить совместимость с EIP-7702, установив хардфорк Prague. Добавьте следующую строку в раздел [profile.default]:
evm_version = «prague»
Это необходимо, поскольку EIP-7702 доступен только с обновления Prague и далее.
Очистите преднастроенные контракты, тесты и скрипты. В папку src добавьте файл BatchCallAndSponsor, в папку test - файл BatchCallAndSponsor.t.sol, в папку noscript - файл BatchCallAndSponsor.s.sol из приложения к посту.
Контракт BatchCallAndSponsor - это простой контракт логики, который поддерживает пакетные транзакции и спонсорский газ.
P.S. Полный вариант реализации смотрите в файле BatchCallAndSponsor.sol. А в приведенных ниже контрактах дается краткий обзор возможностей.
Функция execute в контракте принимает массив структур Call, каждая из которых представляет отдельный вызов и указывает целевой адрес, значение (в Ether) и данные calldata.
struct Call {
address to;
uint256 value;
bytes data;
}
function execute(Call[] calldata calls) external payable {
require(msg.sender == address(this), "Invalid authority");
_executeBatch(calls);
}
function _executeBatch(Call[] calldata calls) internal {
uint256 currentNonce = nonce;
nonce++;
for (uint256 i = 0; i < calls.length; i++) {
_executeCall(calls[i]);
}
emit BatchExecuted(currentNonce, calls);
}
function _executeCall(Call calldata callItem) internal {
(bool success,) = callItem.to.call{value: callItem.value}(callItem.data);
require(success, "Call reverted");
emit CallExecuted(msg.sender, callItem.to, callItem.value, callItem.data);
}Контракт проверяет подпись с помощью библиотеки OpenZeppelin ECDSA и MessageHashUtils. Подписанное сообщение содержит адрес вызывающей стороны, целевой контракт и вызовы.
bytes32 digest = keccak256(abi.encodePacked(nonce, encodedCalls));
require(ECDSA.recover(digest, signature) == msg.sender, "Invalid signature");
В контракте поддерживается либо прямое, либо спонсируемое исполнение.
1. Прямое исполнение: Вызывающая сторона сама выполняет вызовы.
2. Спонсируемое исполнение: Спонсор выполняет вызовы от имени вызывающего абонента после проверки подписи, сделанной EOA.
function execute(Call[] calldata calls) external payable {
// The caller executes the calls directly
}
function execute(Call[] calldata calls, bytes calldata signature) external payable {
// A sponsor executes the calls on behalf of the caller
}Для предотвращения атак повторного воспроизведения в контракте используется nonce. После каждого успешного выполнения транзакции значение nonce увеличивается. Если бы nonce не был реализован, злоумышленник мог бы воспроизвести одну и ту же транзакцию несколько раз.
function _executeBatch(Call[] calldata calls) internal {
uint256 currentNonce = nonce;
nonce++; // Increment nonce to protect against replay attacks
for (uint256 i = 0; i < calls.length; i++) {
_executeCall(calls[i]);
}
emit BatchExecuted(currentNonce, calls);
}Далее поговорим о самих тестах.
#eip7702
🔥7
Погружение в EIP-7702. Часть 7
А теперь пройдемся по тестовым контрактам.
Файл BatchCallAndSponsor.t.sol содержит тесты для контракта BatchCallAndSponsor. Они охватывают сценарии прямого и спонсорского выполнения, защиту от воспроизведения и обработку ошибок.
Тест прямого выполнения
Функция testDirectExecution проверяет прямое исполнение вызовов вызывающей стороной (т. е. Алисой). Она проверяет, что Алиса отправила 1 ETH и 100 токенов Бобу в одной транзакции.
В этом тесте Алиса уполномочивает контракт реализации выполнить транзакцию от ее имени. Мы используем чит-код signAndAttachDelegation, чтобы подписать сообщение авторизации и прикрепить его к транзакции.
Затем вызывается функция execute() на EOA Алисы с массивом вызовов, что невозможно без EIP-7702, самой Алисой.
Тест спонсированного выполнения
Функция testSponsoredExecution() проверяет спонсируемое выполнение вызовов спонсором (т. е. Бобом). Она проверяет, что третья сторона (Боб) может выполнить транзакцию от имени Алисы. Мы проверяем, что отправителем является Боб, а не Алиса, и что получатель получил средства.
В этом тесте Алиса подписывает сообщение, позволяющую реализации выполнять транзакции от ее имени. Боб прикрепляет его от имени Алисы и передает эфир.
Затем Алиса подписывает транзакцию, а Боб исполняет ее через временно назначенный контракт Алисы.
И наконец, функция execute() на EOA Алисы вызывается Бобом, а не Алисой.
Неверная подпись
Функция testWrongSignature() проверяет сценарий, в котором подпись неверна.
Тест защиты от воспроизведения
А теперь пройдемся по тестовым контрактам.
Файл BatchCallAndSponsor.t.sol содержит тесты для контракта BatchCallAndSponsor. Они охватывают сценарии прямого и спонсорского выполнения, защиту от воспроизведения и обработку ошибок.
Тест прямого выполнения
Функция testDirectExecution проверяет прямое исполнение вызовов вызывающей стороной (т. е. Алисой). Она проверяет, что Алиса отправила 1 ETH и 100 токенов Бобу в одной транзакции.
В этом тесте Алиса уполномочивает контракт реализации выполнить транзакцию от ее имени. Мы используем чит-код signAndAttachDelegation, чтобы подписать сообщение авторизации и прикрепить его к транзакции.
Затем вызывается функция execute() на EOA Алисы с массивом вызовов, что невозможно без EIP-7702, самой Алисой.
function testDirectExecution() public {
console2.log("Sending 1 ETH from Alice to Bob and transferring 100 tokens to Bob in a single transaction");
BatchCallAndSponsor.Call[] memory calls = new BatchCallAndSponsor.Call[](2);
// ETH transfer
calls[0] = BatchCallAndSponsor.Call({to: BOB_ADDRESS, value: 1 ether, data: ""});
// Token transfer
calls[1] = BatchCallAndSponsor.Call({
to: address(token),
value: 0,
data: abi.encodeCall(ERC20.transfer, (BOB_ADDRESS, 100e18))
});
vm.signAndAttachDelegation(address(implementation), ALICE_PK);
vm.startPrank(ALICE_ADDRESS);
BatchCallAndSponsor(ALICE_ADDRESS).execute(calls);
vm.stopPrank();
assertEq(BOB_ADDRESS.balance, 1 ether);
assertEq(token.balanceOf(BOB_ADDRESS), 100e18);
}Тест спонсированного выполнения
Функция testSponsoredExecution() проверяет спонсируемое выполнение вызовов спонсором (т. е. Бобом). Она проверяет, что третья сторона (Боб) может выполнить транзакцию от имени Алисы. Мы проверяем, что отправителем является Боб, а не Алиса, и что получатель получил средства.
В этом тесте Алиса подписывает сообщение, позволяющую реализации выполнять транзакции от ее имени. Боб прикрепляет его от имени Алисы и передает эфир.
Затем Алиса подписывает транзакцию, а Боб исполняет ее через временно назначенный контракт Алисы.
И наконец, функция execute() на EOA Алисы вызывается Бобом, а не Алисой.
function testSponsoredExecution() public {
// Arrange the call(s).
calls[0] = BatchCallAndSponsor.Call({to: recipient, value: 1 ether, data: ""});
// Alice signs a delegation allowing `implementation` to execute transactions on her behalf.
Vm.SignedDelegation memory signedDelegation = vm.signDelegation(address(implementation), ALICE_PK);
// Bob attaches the signed delegation from Alice and broadcasts it.
vm.startBroadcast(BOB_PK);
vm.attachDelegation(signedDelegation);
// Prepare the signature for the transaction.
(uint8 v, bytes32 r, bytes32 s) = vm.sign(ALICE_PK, MessageHashUtils.toEthSignedMessageHash(digest));
bytes memory signature = abi.encodePacked(r, s, v);
// Expect the event. The first parameter should be BOB_ADDRESS.
vm.expectEmit(true, true, true, true);
emit BatchCallAndSponsor.CallExecuted(BOB_ADDRESS, calls[0].to, calls[0].value, calls[0].data);
// As Bob, execute the transaction via Alice's temporarily assigned contract.
BatchCallAndSponsor(ALICE_ADDRESS).execute(calls, signature);
vm.stopBroadcast();
assertEq(recipient.balance, 1 ether);
}Неверная подпись
Функция testWrongSignature() проверяет сценарий, в котором подпись неверна.
function testWrongSignature() public {
// Bob attaches the signed delegation from Alice and broadcasts it.
vm.startBroadcast(BOB_PK);
vm.attachDelegation(signedDelegation);
// Sign with the wrong key (Bob's instead of Alice's).
(uint8 v, bytes32 r, bytes32 s) = vm.sign(BOB_PK, MessageHashUtils.toEthSignedMessageHash(digest));
bytes memory signature = abi.encodePacked(r, s, v);
vm.expectRevert("Invalid signature");
BatchCallAndSponsor(ALICE_ADDRESS).execute(calls, signature);
vm.stopBroadcast();
}Тест защиты от воспроизведения
🔥3
Функция testReplayProtection() тестирует механизм защиты от повторного воспроизведения. Она проверяет, откатывается ли исполнение, если одна и та же подпись используется несколько раз.
Далее поговорим о файле скрипта.
#eip7702
function testReplayAttack() public {
// Bob attaches the signed delegation from Alice and broadcasts it.
vm.startBroadcast(BOB_PK);
vm.attachDelegation(signedDelegation);
uint256 nonceBefore = BatchCallAndSponsor(ALICE_ADDRESS).nonce();
bytes32 digest = keccak256(abi.encodePacked(nonceBefore, encodedCalls));
(uint8 v, bytes32 r, bytes32 s) = vm.sign(ALICE_PK, MessageHashUtils.toEthSignedMessageHash(digest));
bytes memory signature = abi.encodePacked(r, s, v);
// First execution: should succeed.
BatchCallAndSponsor(ALICE_ADDRESS).execute(calls, signature);
vm.stopBroadcast();
// Attempt a replay: reusing the same signature should revert because nonce has incremented.
vm.expectRevert("Invalid signature");
BatchCallAndSponsor(ALICE_ADDRESS).execute(calls, signature);
}Далее поговорим о файле скрипта.
#eip7702
🔥3🙏1
Погружение в EIP-7702. Часть 8
Сегодня разберем скрипт деплоя для нашего теста.
Файл BatchCallAndSponsor.s.sol содержит тестовый скрипт для контракта BatchCallAndSponsor. Он делает деплой контракта, минтит токены и тестирует функции пакетного и спонсорского выполнения. Мы будем использовать этот скрипт для развертывания контракта и тестирования его функций в локальной сети.
Для начала запустим локальный блокчейн:
В другом терминале установим зависимости проекта и скомпилируем контракты:
Теперь можно запускать тесты:
В общем, у вас должно получиться следующее:
Теперь можно запустить наш скрипт. Тут мы используем команды:
--broadcast: Транслирует транзакции в вашу локальную сеть.
--rpc-url 127.0.0.1:8545: Подключается к вашей локальной сети.
--tc BatchCallAndSponsorScript: Указывает целевой контракт для сценария.
Может появиться предупреждающее сообщение, подобное следующему:
Это предупреждение ожидаемо, поскольку до применения EIP-7702, у EOA нет кода на блокчейн сети. Просто введите "y", чтобы продолжить.
После завершения работы скрипта вы увидите сообщения журнала, указывающие на то, что выполнение прошло успешно. Транзакции сохраняются в папке broadcast, а все конфиденциальные значения - в папке cache.
Вы можете просмотреть сохраненные транзакции, чтобы узнать больше о том, как выполняются транзакции EIP-7702. Например, в последней транзакции спонсируемого выполнения Боб является отправителем, а адрес контракта принадлежит Алисе. Кроме того, эта транзакция включает в себя список authorizationList, содержащий подписанные авторизации.
#eip7702
Сегодня разберем скрипт деплоя для нашего теста.
Файл BatchCallAndSponsor.s.sol содержит тестовый скрипт для контракта BatchCallAndSponsor. Он делает деплой контракта, минтит токены и тестирует функции пакетного и спонсорского выполнения. Мы будем использовать этот скрипт для развертывания контракта и тестирования его функций в локальной сети.
function run() external {
// Start broadcasting transactions with Alice's private key.
vm.startBroadcast(ALICE_PK);
// Deploy the delegation contract (Alice will delegate calls to this contract).
implementation = new BatchCallAndSponsor();
// Deploy an ERC-20 token contract where Alice is the minter.
token = new MockERC20();
// // Fund accounts
token.mint(ALICE_ADDRESS, 1000e18);
vm.stopBroadcast();
// Perform direct execution
performDirectExecution();
// Perform sponsored execution
performSponsoredExecution();
}Для начала запустим локальный блокчейн:
anvil --hardfork prague
В другом терминале установим зависимости проекта и скомпилируем контракты:
forge install
forge build
Теперь можно запускать тесты:
forge test -vvv
В общем, у вас должно получиться следующее:
Ran 4 tests for test/BatchCallAndSponsor.t.sol:BatchCallAndSponsorTest
[PASS] testDirectExecution() (gas: 128386)
Logs:
Sending 1 ETH from Alice to Bob and transferring 100 tokens to Bob in a single transaction
[PASS] testReplayAttack() (gas: 114337)
Logs:
Test replay attack: Reusing the same signature should revert.
[PASS] testSponsoredExecution() (gas: 110461)
Logs:
Sending 1 ETH from Alice to a random address while the transaction is sponsored by Bob
[PASS] testWrongSignature() (gas: 37077)
Logs:
Test wrong signature: Execution should revert with 'Invalid signature'.
Suite result: ok. 4 passed; 0 failed; 0 skipped;
Теперь можно запустить наш скрипт. Тут мы используем команды:
--broadcast: Транслирует транзакции в вашу локальную сеть.
--rpc-url 127.0.0.1:8545: Подключается к вашей локальной сети.
--tc BatchCallAndSponsorScript: Указывает целевой контракт для сценария.
forge noscript ./noscript/BatchCallAndSponsor.s.sol --tc BatchCallAndSponsorScript --broadcast --rpc-url 127.0.0.1:8545
Может появиться предупреждающее сообщение, подобное следующему:
Warning: Script contains a transaction to 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 which does not contain any code.
Do you wish to continue?
Это предупреждение ожидаемо, поскольку до применения EIP-7702, у EOA нет кода на блокчейн сети. Просто введите "y", чтобы продолжить.
После завершения работы скрипта вы увидите сообщения журнала, указывающие на то, что выполнение прошло успешно. Транзакции сохраняются в папке broadcast, а все конфиденциальные значения - в папке cache.
ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
Transactions saved to: /project-path/broadcast/...
Sensitive values saved to: /project-path/cache/...
Вы можете просмотреть сохраненные транзакции, чтобы узнать больше о том, как выполняются транзакции EIP-7702. Например, в последней транзакции спонсируемого выполнения Боб является отправителем, а адрес контракта принадлежит Алисе. Кроме того, эта транзакция включает в себя список authorizationList, содержащий подписанные авторизации.
#eip7702
👍6🔥1
Погружение в EIP-7702. Часть 9
Продолжаем разбирать этот необычный стандарт...
Хотя EIP-7702 привносит новую жизнь в экосистему Ethereum, введение новых сценариев применения также несет новые риски. Ниже приведены некоторые аспекты, с которыми участникам экосистемы следует быть осторожными во время практики.
Хранение приватного ключа
Несмотря на то, что EOA (Externally Owned Accounts) могут использовать встроенные в смарт-контракты механизмы социального восстановления для решения проблемы потери активов в результате утраты приватного ключа, они все равно не могут избежать риска самой утечки приватного ключа. Важно отметить, что после делегирования приватный ключ EOA по-прежнему имеет наивысший контроль над счетом; владение приватным ключом дает пользователю возможность свободно распоряжаться активами на аккаунте. Пользователи или поставщики услуг кошелька, завершив делегирование полномочий для EOA, не могут полностью исключить риск утечки закрытого ключа, особенно в случаях, когда возможны атаки на сеть.
Для пользователей защита приватного ключа всегда должна быть приоритетной. Очень важно помнить: Не ваши ключи, не ваши монеты.
Воспроизведение нескольких сетях
Когда пользователи подписывают разрешение на делегирование, они могут выбрать идентификатор сети, на которой будет действовать делегирование. Пользователи также могут выбрать идентификатор сети, равный 0, что позволяет воспроизводить делегирование на нескольких сетях.
Поставщики услуг кошелька должны проверять, соответствует ли блокчейн делегации текущей сети, и предупреждать пользователей о рисках, связанных с ними.
Пользователи также должны знать, что один и тот же адрес контракта в разных сетях не всегда может иметь один и тот же код. Важно понимать детали делегированной цели, прежде чем приступать к работе.
Проблема инициализации
Большинство основных кошельков смарт-контрактов используют прокси-модель, при которой прокси-кошелек вызывает функцию инициализации через DELEGATECALL для достижения атомарной инициализации и развертывания кошелька. Однако в EIP-7702 поле кода адреса будет только обновляться, а функция инициализации не может быть вызвана через делегированный адрес. Это ограничивает возможности EIP-7702 по инициализации кошелька по сравнению с прокси-контрактом ERC-1967, который может вызывать функцию инициализации во время развертывания.
Разработчикам следует обеспечить проверку прав доступа во время инициализации кошелька (например, с помощью ecrecover для проверки адреса подписи), чтобы избежать уязвимостей инициализации.
Управление хранилищем
При использовании делегирования EIP-7702 пользователям может потребоваться повторное делегирование на разные адреса контрактов в связи с изменениями в функциональности или обновлением кошелька. Разные контракты могут иметь разные структуры хранения (например, slot0 может представлять разные типы данных в разных контрактах), и повторное делегирование может привести к повторному использованию старых данных контракта, что приведет к блокировке аккаунта, потере активов и другим проблемам.
Пользователям следует внимательно относиться к ситуациям переделегирования.
Разработчики должны следовать формуле пространства имен, предложенной в ERC-7201, чтобы распределять переменные по определенным независимым местам хранения для уменьшения конфликтов хранения. Кроме того, ERC-7779 (draft) предлагает стандартный процесс повторного делегирования, специфичный для EIP-7702, включая предотвращение конфликтов хранения и проверку совместимости перед повторным делегированием.
Далее посмотрим на еще пару нюансов использования стандарта.
#eip7702
Продолжаем разбирать этот необычный стандарт...
Хотя EIP-7702 привносит новую жизнь в экосистему Ethereum, введение новых сценариев применения также несет новые риски. Ниже приведены некоторые аспекты, с которыми участникам экосистемы следует быть осторожными во время практики.
Хранение приватного ключа
Несмотря на то, что EOA (Externally Owned Accounts) могут использовать встроенные в смарт-контракты механизмы социального восстановления для решения проблемы потери активов в результате утраты приватного ключа, они все равно не могут избежать риска самой утечки приватного ключа. Важно отметить, что после делегирования приватный ключ EOA по-прежнему имеет наивысший контроль над счетом; владение приватным ключом дает пользователю возможность свободно распоряжаться активами на аккаунте. Пользователи или поставщики услуг кошелька, завершив делегирование полномочий для EOA, не могут полностью исключить риск утечки закрытого ключа, особенно в случаях, когда возможны атаки на сеть.
Для пользователей защита приватного ключа всегда должна быть приоритетной. Очень важно помнить: Не ваши ключи, не ваши монеты.
Воспроизведение нескольких сетях
Когда пользователи подписывают разрешение на делегирование, они могут выбрать идентификатор сети, на которой будет действовать делегирование. Пользователи также могут выбрать идентификатор сети, равный 0, что позволяет воспроизводить делегирование на нескольких сетях.
Поставщики услуг кошелька должны проверять, соответствует ли блокчейн делегации текущей сети, и предупреждать пользователей о рисках, связанных с ними.
Пользователи также должны знать, что один и тот же адрес контракта в разных сетях не всегда может иметь один и тот же код. Важно понимать детали делегированной цели, прежде чем приступать к работе.
Проблема инициализации
Большинство основных кошельков смарт-контрактов используют прокси-модель, при которой прокси-кошелек вызывает функцию инициализации через DELEGATECALL для достижения атомарной инициализации и развертывания кошелька. Однако в EIP-7702 поле кода адреса будет только обновляться, а функция инициализации не может быть вызвана через делегированный адрес. Это ограничивает возможности EIP-7702 по инициализации кошелька по сравнению с прокси-контрактом ERC-1967, который может вызывать функцию инициализации во время развертывания.
Разработчикам следует обеспечить проверку прав доступа во время инициализации кошелька (например, с помощью ecrecover для проверки адреса подписи), чтобы избежать уязвимостей инициализации.
Управление хранилищем
При использовании делегирования EIP-7702 пользователям может потребоваться повторное делегирование на разные адреса контрактов в связи с изменениями в функциональности или обновлением кошелька. Разные контракты могут иметь разные структуры хранения (например, slot0 может представлять разные типы данных в разных контрактах), и повторное делегирование может привести к повторному использованию старых данных контракта, что приведет к блокировке аккаунта, потере активов и другим проблемам.
Пользователям следует внимательно относиться к ситуациям переделегирования.
Разработчики должны следовать формуле пространства имен, предложенной в ERC-7201, чтобы распределять переменные по определенным независимым местам хранения для уменьшения конфликтов хранения. Кроме того, ERC-7779 (draft) предлагает стандартный процесс повторного делегирования, специфичный для EIP-7702, включая предотвращение конфликтов хранения и проверку совместимости перед повторным делегированием.
Далее посмотрим на еще пару нюансов использования стандарта.
#eip7702
👍5
Погружение в EIP-7702. Часть 10
И еще несколько нюансов, на которые следует обратить внимание.
Ложное пополнение
После делегирования полномочий EOA также могут выступать в качестве смарт-контрактов, что может привести к тому, что централизованные биржи (CEX) столкнутся с широко распространенными рисками пополнения счета смарт-контрактами.
CEX должны использовать проверку трассировки для мониторинга каждой транзакции пополнения, чтобы снизить риск фальшивых пополнений с помощью смарт-контрактов.
Конвертация аккаунта
С помощью делегирования EIP-7702 аккаунт пользователя может свободно конвертироваться между EOA и смарт-контрактом, что позволяет ему инициировать транзакции и быть вызванным. Это означает, что когда аккаунт вызывает сам себя или совершает внешний вызов, его msg.sender также будет tx.origin, что нарушает предположение о безопасности, согласно которому участвуют только EOA.
Разработчики контрактов не должны предполагать, что tx.origin всегда будет EOA. Аналогично, использование msg.sender == tx.origin в качестве защиты от атак реентранси больше не будет эффективным.
Разработчикам следует предположить, что в процессе разработки все будущие участники могут оказаться смарт-контрактами.
Совместимость с контрактами
Существующие токены ERC-721 и ERC-777 имеют хуковые функции при передаче токенов, то есть получатель должен реализовать соответствующую функцию обратного вызова, чтобы успешно получить токены.
Разработчики должны убедиться, что целевой контракт для делегирования пользователя реализует необходимые функции обратного вызова для обеспечения совместимости с основными токенами.
Фишинговые проверки
После реализации делегирования EIP-7702 активы в аккаунте пользователя могут контролироваться смарт-контрактами. Если пользователь делегирует свой счет вредоносному контракту, злоумышленники могут легко похитить активы.
Поставщики услуг кошельков должны оперативно поддерживать транзакции EIP-7702 и, когда пользователи подписывают делегирование, на видном месте отображать целевой контракт, чтобы снизить риск фишинговых атак.
Кроме того, глубокий автоматизированный анализ (проверка открытых источников, проверка разрешений и т. д.) делегированных целевых контрактов может помочь пользователям избежать подобных рисков.
#eip7702
И еще несколько нюансов, на которые следует обратить внимание.
Ложное пополнение
После делегирования полномочий EOA также могут выступать в качестве смарт-контрактов, что может привести к тому, что централизованные биржи (CEX) столкнутся с широко распространенными рисками пополнения счета смарт-контрактами.
CEX должны использовать проверку трассировки для мониторинга каждой транзакции пополнения, чтобы снизить риск фальшивых пополнений с помощью смарт-контрактов.
Конвертация аккаунта
С помощью делегирования EIP-7702 аккаунт пользователя может свободно конвертироваться между EOA и смарт-контрактом, что позволяет ему инициировать транзакции и быть вызванным. Это означает, что когда аккаунт вызывает сам себя или совершает внешний вызов, его msg.sender также будет tx.origin, что нарушает предположение о безопасности, согласно которому участвуют только EOA.
Разработчики контрактов не должны предполагать, что tx.origin всегда будет EOA. Аналогично, использование msg.sender == tx.origin в качестве защиты от атак реентранси больше не будет эффективным.
Разработчикам следует предположить, что в процессе разработки все будущие участники могут оказаться смарт-контрактами.
Совместимость с контрактами
Существующие токены ERC-721 и ERC-777 имеют хуковые функции при передаче токенов, то есть получатель должен реализовать соответствующую функцию обратного вызова, чтобы успешно получить токены.
Разработчики должны убедиться, что целевой контракт для делегирования пользователя реализует необходимые функции обратного вызова для обеспечения совместимости с основными токенами.
Фишинговые проверки
После реализации делегирования EIP-7702 активы в аккаунте пользователя могут контролироваться смарт-контрактами. Если пользователь делегирует свой счет вредоносному контракту, злоумышленники могут легко похитить активы.
Поставщики услуг кошельков должны оперативно поддерживать транзакции EIP-7702 и, когда пользователи подписывают делегирование, на видном месте отображать целевой контракт, чтобы снизить риск фишинговых атак.
Кроме того, глубокий автоматизированный анализ (проверка открытых источников, проверка разрешений и т. д.) делегированных целевых контрактов может помочь пользователям избежать подобных рисков.
#eip7702
👍6
Проект на виду. Часть 6. Нейронки не доступны
Сегодня хочу отвлечься от темы EIP-7702 и снова поговорить о нейронных сетях, AI, агентах и том, как они будут заменять программистов...
Понемногу каждый день я продолжаю изучать модели, обучение нейронок и как это может быть полезно в моей работе. И с каждым днем я прихожу к мысли, что полноценные нейронные сети одновременно и доступны и недостижимы для простых людей.
Да, мы в любой момент можем зайти в DeepSeek, GTP, Grok - написать хороший промт и получить прекрасный результат. Claude и Gemini все лучше пишут код, и казалось бы от оно счастье...
Пока вы не задумаете попробовать самому выбрать локальную нейронку для своих задач и попробовать обучить ее. Тут начинаются проблемы, а именно загвоздка в мощностях.
Для работы маломальски нормальной нейронки, не обрезанной\облегченной\нишевой, вам потребуется мощная видеокарта уровня 3090, а лучше 4090, и процессор минимум i7. И это будет "в целом ок" для моделей среднего уровня на 13-15 млрд параметров. А более хорошие модели на 32-36 млрд потребуют мощностей куда выше обозначенных. Кроме того, современные модели, например тот же DeepSeek может затянуть на 200 +млрд параметров и вообще запредельных мощностей, которые просто не организовать в домашних условиях.
И, если я правильно понял, то такие мощности требуются только для комфортной работы модели, а для ее переобучения нужно больше...
К чему я веду?
Нейронки (DeepSeek, chatGPT, etc) обучаются на огромных массивах данных, включая все языки, всю документацию, все примеры кода и т.д. Нет четкого фокуса - главное быть лучше и функциональнее конкурента. У разработчиков этих моделей нет задачи сделать их мастерами в React, Solidity или Python. Отсюда у нас идет хороший, но порой "не тот" код.
А дообучить\переобучить нейронку для определенного языка - у обычных пользователей нет ресурсов.
Вот и получается, что сейчас возможен период, когда компании будут формировать свои ресурсы вокруг опенсорсных моделей, нишево дообучать их для определенной цели и продавать доступ по подписке.
В ближайшие лет 5 текущие нейронки выйдут на хороший уровень по коду, но появится много надстроек, которые будут продавать фокусные решения. И пользователи будут платить за модель, которая отлично пишет код Solidity с акцентом на безопасности, чем брать просто хорошие основные сети для "всего".
Вот такой пятничный поток мыслей. А вы что думаете по этому поводу?
#offtop
Сегодня хочу отвлечься от темы EIP-7702 и снова поговорить о нейронных сетях, AI, агентах и том, как они будут заменять программистов...
Понемногу каждый день я продолжаю изучать модели, обучение нейронок и как это может быть полезно в моей работе. И с каждым днем я прихожу к мысли, что полноценные нейронные сети одновременно и доступны и недостижимы для простых людей.
Да, мы в любой момент можем зайти в DeepSeek, GTP, Grok - написать хороший промт и получить прекрасный результат. Claude и Gemini все лучше пишут код, и казалось бы от оно счастье...
Пока вы не задумаете попробовать самому выбрать локальную нейронку для своих задач и попробовать обучить ее. Тут начинаются проблемы, а именно загвоздка в мощностях.
Для работы маломальски нормальной нейронки, не обрезанной\облегченной\нишевой, вам потребуется мощная видеокарта уровня 3090, а лучше 4090, и процессор минимум i7. И это будет "в целом ок" для моделей среднего уровня на 13-15 млрд параметров. А более хорошие модели на 32-36 млрд потребуют мощностей куда выше обозначенных. Кроме того, современные модели, например тот же DeepSeek может затянуть на 200 +млрд параметров и вообще запредельных мощностей, которые просто не организовать в домашних условиях.
И, если я правильно понял, то такие мощности требуются только для комфортной работы модели, а для ее переобучения нужно больше...
К чему я веду?
Нейронки (DeepSeek, chatGPT, etc) обучаются на огромных массивах данных, включая все языки, всю документацию, все примеры кода и т.д. Нет четкого фокуса - главное быть лучше и функциональнее конкурента. У разработчиков этих моделей нет задачи сделать их мастерами в React, Solidity или Python. Отсюда у нас идет хороший, но порой "не тот" код.
А дообучить\переобучить нейронку для определенного языка - у обычных пользователей нет ресурсов.
Вот и получается, что сейчас возможен период, когда компании будут формировать свои ресурсы вокруг опенсорсных моделей, нишево дообучать их для определенной цели и продавать доступ по подписке.
В ближайшие лет 5 текущие нейронки выйдут на хороший уровень по коду, но появится много надстроек, которые будут продавать фокусные решения. И пользователи будут платить за модель, которая отлично пишет код Solidity с акцентом на безопасности, чем брать просто хорошие основные сети для "всего".
Вот такой пятничный поток мыслей. А вы что думаете по этому поводу?
#offtop
❤6🤔3👍2
Упрощение сети Эфириум
Месяц назад сохранил в закладки для себя статью от Виталика Бутерина и только сейчас дошел до нее. В целом, очень идеи и предположения. Может некоторые из них и будут внедрены в сеть...
О чем же сама статья?
Виталик предлагает радикально упростить протокол Ethereum, стремясь приблизить его по простоте к Bitcoin. Он утверждает, что чрезмерная сложность текущей архитектуры Ethereum затрудняет развитие, увеличивает риски и препятствует участию новых разработчиков. В отличие от этого, простота Bitcoin делает его более устойчивым и понятным даже для начинающих программистов.
Одним из ключевых предложений является внедрение модели консенсуса с трёхслотовой финализацией, которая заменит текущую сложную систему слотов, эпох и комитетов. Эта модель может быть реализована в около 200 строках кода и обеспечивает почти оптимальные свойства безопасности. Уменьшение числа активных валидаторов одновременно упрощает реализацию правил выбора форка и повышает надёжность сети.
В области исполнения Бутерин предлагает заменить Ethereum Virtual Machine (EVM) на виртуальную машину, основанную на архитектуре RISC-V. Это позволит значительно упростить протокол и улучшить производительность, особенно в контексте zero-knowledge доказательств. Для обеспечения обратной совместимости предлагается запускать существующие контракты EVM через интерпретатор на новой виртуальной машине.
Также предлагается стандартизация протокола, включая использование единых форматов сериализации и структуры данных, таких как SSZ и унифицированные Merkle-деревья. Это позволит улучшить инструментарий, системы доказательств и повторное использование кода, а также упростит разработку и поддержку протокола.
Бутерин подчёркивает, что простота протокола способствует его устойчивости, снижает вероятность критических ошибок и уменьшает социальную поверхность атаки. Он признаёт, что предыдущие решения, включая его собственные, способствовали излишней сложности и рискам безопасности, и призывает к переосмыслению архитектуры Ethereum с акцентом на простоту и прозрачность.
Предложенные изменения представляют собой долгосрочную стратегию, направленную на повышение устойчивости и масштабируемости Ethereum. Хотя реализация этих изменений потребует значительных усилий и может вызвать временные трудности, Бутерин уверен, что в долгосрочной перспективе они принесут значительные преимущества для всей экосистемы Ethereum.
#ethereum
Месяц назад сохранил в закладки для себя статью от Виталика Бутерина и только сейчас дошел до нее. В целом, очень идеи и предположения. Может некоторые из них и будут внедрены в сеть...
О чем же сама статья?
Виталик предлагает радикально упростить протокол Ethereum, стремясь приблизить его по простоте к Bitcoin. Он утверждает, что чрезмерная сложность текущей архитектуры Ethereum затрудняет развитие, увеличивает риски и препятствует участию новых разработчиков. В отличие от этого, простота Bitcoin делает его более устойчивым и понятным даже для начинающих программистов.
Одним из ключевых предложений является внедрение модели консенсуса с трёхслотовой финализацией, которая заменит текущую сложную систему слотов, эпох и комитетов. Эта модель может быть реализована в около 200 строках кода и обеспечивает почти оптимальные свойства безопасности. Уменьшение числа активных валидаторов одновременно упрощает реализацию правил выбора форка и повышает надёжность сети.
В области исполнения Бутерин предлагает заменить Ethereum Virtual Machine (EVM) на виртуальную машину, основанную на архитектуре RISC-V. Это позволит значительно упростить протокол и улучшить производительность, особенно в контексте zero-knowledge доказательств. Для обеспечения обратной совместимости предлагается запускать существующие контракты EVM через интерпретатор на новой виртуальной машине.
Также предлагается стандартизация протокола, включая использование единых форматов сериализации и структуры данных, таких как SSZ и унифицированные Merkle-деревья. Это позволит улучшить инструментарий, системы доказательств и повторное использование кода, а также упростит разработку и поддержку протокола.
Бутерин подчёркивает, что простота протокола способствует его устойчивости, снижает вероятность критических ошибок и уменьшает социальную поверхность атаки. Он признаёт, что предыдущие решения, включая его собственные, способствовали излишней сложности и рискам безопасности, и призывает к переосмыслению архитектуры Ethereum с акцентом на простоту и прозрачность.
Предложенные изменения представляют собой долгосрочную стратегию, направленную на повышение устойчивости и масштабируемости Ethereum. Хотя реализация этих изменений потребует значительных усилий и может вызвать временные трудности, Бутерин уверен, что в долгосрочной перспективе они принесут значительные преимущества для всей экосистемы Ethereum.
#ethereum
❤7👍6🤔3
Стандарт ERC-6909 Minimal Multi-Token Standard. Часть 1
Следующий цикл постов я хочу посвятить этому интересному стандарту.
ERC-6909 - это оптимизированная альтернатива ERC-1155. Он представляет интерфейс для нескольких токенов, который позволяет одному смарт контракту включать в себя fungible and non-fungible токены (т. е. ERC20 и ERC721).
ERC-1155 позволил решить несколько проблем, таких как снижение затрат на развертывание, минимизация избыточного байткода в блокчейне Ethereum и упрощение процедуры утверждения токенов для торговли несколькими токенами.
Однако он привел к некоторому раздуванию и газовой неэффективности из-за обязательных callbacks для каждого трансфера, принудительного включения batch transfer и отсутствия тонкого контроля разрешений одного оператора. ERC-6909 устраняет эти недостатки, а как - узнаем дальше.
ERC-6909 удаляет требование callbacks
Спецификация ERC-1155 требует, чтобы функции safeTransferFrom и safeBatchTransferFrom проверяли, является ли получатель контрактом. Если это так, то они ОБЯЗАТЕЛЬНО должны вызвать функции интерфейса ERC1155TokenReceiver (onERC1155Received, onERC1155BatchReceived) в контракте-получателе, чтобы проверить, принимает ли он переводы.
Эти callbacks полезны в некоторых случаях. Однако они становятся ненужными внешними вызовами для получателя, который хочет отказаться от такого поведения. Callbacks влияют на стоимость газа и размер кода контрактов-получателей, поскольку требуют реализации нескольких callback-функций (например, onERC1155Received, onERC1155BatchReceived) и возврата специальных 4-байтовых значений для получения токенов. В отличие от этого, разработчики, реализующие стандарт ERC-6909, могут самостоятельно выбирать архитектуру своих callback-функций.
ERC-6909 не включает логику пакетных переводов (batch transfer)
Пакетные переводы, несмотря на свою полезность в некоторых случаях, намеренно исключены из стандарта ERC-6909. Это позволяет разработчикам реализовывать логику таких переводов, адаптированную под конкретные среды исполнения. Разработчики могут реализовать переводы любым удобным для них способом и не обязаны добавлять дополнительную функцию переводов только ради соответствия стандарту.
Функция safeBatchTransferFrom , показанная ниже, отвечает за выполнение таких переводов в стандарте ERC-1155. Однако её обязательное присутствие увеличивает объём кода у приложений, которым такие функции не нужны:
Ниже представлена функция ERC-6909 transferFrom. Видно, что функция batch и параметр _data были удалены.
ERC-6909 поддерживает как глобальные разрешения, так и детализированные лимиты
Функция setApprovalForAll , показанная выше, реализует модель глобального оператора из стандарта ERC-1155. Она позволяет одному аккаунту авторизовать другой аккаунт для управления (в качестве оператора) всеми идентификаторами токенов от его имени. После авторизации оператор получает неограниченный доступ к переводу любых количеств любых токенов, принадлежащих авторизующему аккаунту.
Хотя этот подход упрощает делегирование прав, он не предоставляет возможности точного контроля:
Следующий цикл постов я хочу посвятить этому интересному стандарту.
ERC-6909 - это оптимизированная альтернатива ERC-1155. Он представляет интерфейс для нескольких токенов, который позволяет одному смарт контракту включать в себя fungible and non-fungible токены (т. е. ERC20 и ERC721).
ERC-1155 позволил решить несколько проблем, таких как снижение затрат на развертывание, минимизация избыточного байткода в блокчейне Ethereum и упрощение процедуры утверждения токенов для торговли несколькими токенами.
Однако он привел к некоторому раздуванию и газовой неэффективности из-за обязательных callbacks для каждого трансфера, принудительного включения batch transfer и отсутствия тонкого контроля разрешений одного оператора. ERC-6909 устраняет эти недостатки, а как - узнаем дальше.
ERC-6909 удаляет требование callbacks
Спецификация ERC-1155 требует, чтобы функции safeTransferFrom и safeBatchTransferFrom проверяли, является ли получатель контрактом. Если это так, то они ОБЯЗАТЕЛЬНО должны вызвать функции интерфейса ERC1155TokenReceiver (onERC1155Received, onERC1155BatchReceived) в контракте-получателе, чтобы проверить, принимает ли он переводы.
Эти callbacks полезны в некоторых случаях. Однако они становятся ненужными внешними вызовами для получателя, который хочет отказаться от такого поведения. Callbacks влияют на стоимость газа и размер кода контрактов-получателей, поскольку требуют реализации нескольких callback-функций (например, onERC1155Received, onERC1155BatchReceived) и возврата специальных 4-байтовых значений для получения токенов. В отличие от этого, разработчики, реализующие стандарт ERC-6909, могут самостоятельно выбирать архитектуру своих callback-функций.
ERC-6909 не включает логику пакетных переводов (batch transfer)
Пакетные переводы, несмотря на свою полезность в некоторых случаях, намеренно исключены из стандарта ERC-6909. Это позволяет разработчикам реализовывать логику таких переводов, адаптированную под конкретные среды исполнения. Разработчики могут реализовать переводы любым удобным для них способом и не обязаны добавлять дополнительную функцию переводов только ради соответствия стандарту.
Функция safeBatchTransferFrom , показанная ниже, отвечает за выполнение таких переводов в стандарте ERC-1155. Однако её обязательное присутствие увеличивает объём кода у приложений, которым такие функции не нужны:
// ERC-1155
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external;
Ниже представлена функция ERC-6909 transferFrom. Видно, что функция batch и параметр _data были удалены.
// ERC-6909
function transferFrom(
address sender,
address receiver,
uint256 id,
uint256 amount
) public returns (bool) {
if (sender != msg.sender && !isOperator[sender][msg.sender]) {
uint256 senderAllowance = allowance[sender][msg.sender][id];
if (senderAllowance < amount) revert InsufficientPermission();
if (senderAllowance != type(uint256).max) {
allowance[sender][msg.sender][id] = senderAllowance - amount;
}
}
if (balanceOf[sender][id] < amount) revert InsufficientBalance();
balanceOf[sender][id] -= amount;
balanceOf[receiver][id] += amount;
emit Transfer(msg.sender, sender, receiver, id, amount);
return true;
}
ERC-6909 поддерживает как глобальные разрешения, так и детализированные лимиты
// in ERC-1155 →
function setApprovalForAll(
address _operator,
bool _approved
) external;
Функция setApprovalForAll , показанная выше, реализует модель глобального оператора из стандарта ERC-1155. Она позволяет одному аккаунту авторизовать другой аккаунт для управления (в качестве оператора) всеми идентификаторами токенов от его имени. После авторизации оператор получает неограниченный доступ к переводу любых количеств любых токенов, принадлежащих авторизующему аккаунту.
Хотя этот подход упрощает делегирование прав, он не предоставляет возможности точного контроля:
1❤2
- Нет способа выдать разрешение на перевод конкретных идентификаторов токенов или определённых количеств.
- Такой "всё или ничего" подход не подходит для сценариев, где требуется гибкое управление разрешениями.
Для реализации более тонкого контроля, в ERC-6909 используется гибридная схема разрешений, которая включает:
- модель оператора из ERC-1155,
- и модель лимитов (allowance), вдохновлённую стандартом ERC-20.
Далее продолжим разговор о нюансах данного стандарта.
#eip6909
- Такой "всё или ничего" подход не подходит для сценариев, где требуется гибкое управление разрешениями.
Для реализации более тонкого контроля, в ERC-6909 используется гибридная схема разрешений, которая включает:
- модель оператора из ERC-1155,
- и модель лимитов (allowance), вдохновлённую стандартом ERC-20.
Далее продолжим разговор о нюансах данного стандарта.
#eip6909
👍6
Стандарт ERC-6909 Minimal Multi-Token Standard. Часть 2
Продолжаем знакомится с данным стандартом.
Модель оператора в ERC-6909
В функции ERC-6909 setOperator, показанной ниже, переменная spender устанавливается в качестве оператора и получает глобальные разрешения на передачу всех идентификаторов токенов, принадлежащих счету, без ограничений по разрешению.
Модель разрешений в ERC-6909
Модель разрешений (allowance model) представляет собой систему управления по конкретным токенам и суммам, в которой учетная запись может установить ограниченное количество разрешений для конкретного ID токена.
Например, Алиса может разрешить Бобу перевести 100 единиц токена с ID 42, не предоставляя доступа к другим токенам или неограниченным суммам, используя функцию одобрения в ERC-6909, показанную далее.
Переменная spender в approve - это учетная запись, уполномоченная переводить определенные суммы определенного id токена от имени владельца.
Например, владелец может разрешить spender переводить <= 100 единиц определенного ID токена. Кроме того, он может дать бесконечное разрешение на перевод определенного id токена, установив разрешение на type(uint256).max.
В ERC-6909 не указано, должны ли вычитаться надбавки, установленные в type(uint256).max, или нет. Это поведение оставлено на усмотрение исполнителя, аналогично ERC-20.
Основные структуры данных
Реализации ERC-6909 используют три маппинга для обновления состояния остатков на счетах и разрешений.
1. balanceOf: Баланс владельца id
Маппинг balanceOf отслеживает баланс определенного ID токена, принадлежащего определенному адресу (владельцу). Структура owner => (id => amount) в связке указывает на то, что один владелец может владеть несколькими токенами и отслеживать их баланс по соответствующим ID.
2. allowance: Разрешение на передачу токена
Маппинг allowance определяет, какое количество конкретного токена (ID) может передать spender от имени владельца. Это облегчает тонкий контроль над расходованием токенов.
3. isOperator: Статус утверждения оператора
Этот маппинг отслеживает, был ли spender утвержден в качестве оператора для всех токенов, принадлежащих адресу. Например, isOperator[0x123...][0xABC...] возвращает true, если адресу 0xABC... разрешено тратить токены, принадлежащие адресу 0x123...; в противном случае возвращается false.
Далее разберем функции.
#eip6909
Продолжаем знакомится с данным стандартом.
Модель оператора в ERC-6909
В функции ERC-6909 setOperator, показанной ниже, переменная spender устанавливается в качестве оператора и получает глобальные разрешения на передачу всех идентификаторов токенов, принадлежащих счету, без ограничений по разрешению.
function setOperator(address spender, bool approved) public returns (bool) {
isOperator[msg.sender][spender] = approved;
emit OperatorSet(msg.sender, spender, approved);
return true;
}Модель разрешений в ERC-6909
Модель разрешений (allowance model) представляет собой систему управления по конкретным токенам и суммам, в которой учетная запись может установить ограниченное количество разрешений для конкретного ID токена.
Например, Алиса может разрешить Бобу перевести 100 единиц токена с ID 42, не предоставляя доступа к другим токенам или неограниченным суммам, используя функцию одобрения в ERC-6909, показанную далее.
function approve(address spender, uint256 id, uint256 amount) public returns (bool) {
allowance[msg.sender][spender][id] = amount;
emit Approval(msg.sender, spender, id, amount);
return true;
}Переменная spender в approve - это учетная запись, уполномоченная переводить определенные суммы определенного id токена от имени владельца.
Например, владелец может разрешить spender переводить <= 100 единиц определенного ID токена. Кроме того, он может дать бесконечное разрешение на перевод определенного id токена, установив разрешение на type(uint256).max.
В ERC-6909 не указано, должны ли вычитаться надбавки, установленные в type(uint256).max, или нет. Это поведение оставлено на усмотрение исполнителя, аналогично ERC-20.
Основные структуры данных
Реализации ERC-6909 используют три маппинга для обновления состояния остатков на счетах и разрешений.
1. balanceOf: Баланс владельца id
Маппинг balanceOf отслеживает баланс определенного ID токена, принадлежащего определенному адресу (владельцу). Структура owner => (id => amount) в связке указывает на то, что один владелец может владеть несколькими токенами и отслеживать их баланс по соответствующим ID.
mapping(address owner => mapping(uint256 id => uint256 amount)) public balanceOf;
2. allowance: Разрешение на передачу токена
Маппинг allowance определяет, какое количество конкретного токена (ID) может передать spender от имени владельца. Это облегчает тонкий контроль над расходованием токенов.
mapping(address owner => mapping(address spender => mapping(uint256 id => uint256 amount))) public allowance;
3. isOperator: Статус утверждения оператора
mapping(address owner => mapping(address operator => bool isOperator)) public isOperator;
Этот маппинг отслеживает, был ли spender утвержден в качестве оператора для всех токенов, принадлежащих адресу. Например, isOperator[0x123...][0xABC...] возвращает true, если адресу 0xABC... разрешено тратить токены, принадлежащие адресу 0x123...; в противном случае возвращается false.
Далее разберем функции.
#eip6909
👍5❤2
Стандарт ERC-6909 Minimal Multi-Token Standard. Часть 3
На этой неделе поговорим о функциях в стандарте и некоторых моментах его использования.
1. transfer():
Функция перевода ERC-6909 ведет себя так же, как и трансфер ERC-20, за исключением того, что она применяется к конкретному идентификатору токена. Функция принимает адрес получателя, id токена и сумму для перевода в качестве входных параметров и обновляет балансы с помощью связки balanceOf. Как и в функции перевода ERC-20, необходимо вернуть true, если транзакция выполнена успешно:
2. transferFrom():
Функция transferFrom в ERC-6909 отличается от функции ERC-20 тем, что требует идентификатор токена. Кроме того, она проверяет наличие одобрения оператора в дополнение к разрешению.
Сначала функция проверяет, если (sender != msg.sender && !isOperator[sender][msg.sender]), гарантируя, что вызывающая сторона (msg.sender) является либо:
- Владелецем (отправителем), либо
- Одобренным оператором (isOperator[sender][msg.sender] == true).
Если отправитель msg.sender не является таковыми, то функция проверяет, достаточно ли у вызывающего абонента средств для перевода. Если резерв существует, но не установлен в неограниченное значение (type(uint256).max), то переведенная сумма вычитается из резерва.
Кроме того, в стандарте указано, что функция НЕ ДОЛЖНА вычитать сумму из резерва вызывающего абонента по идентификатору токена, если вызывающий абонент является оператором или отправителем.
3. approve():
Функция approve позволяет вызывающей стороне (msg.sender) предоставить определенное разрешение к ID спендеру. При этом обновляется маппинг, чтобы отразить новое состояние, и порождается событие Approval:
4. setOperator():
Функция setOperator позволяет вызывающей стороне (msg.sender) предоставить или отозвать разрешения оператора для определенного адреса (spender) от своего имени, установив параметр approved в true или false. Функция соответствующим образом обновляет отображение isOperator и порождает событие OperatorSet, чтобы уведомить внешних слушателей об изменении.
5. Events:
В стандарте предусмотрены три события для порождения в ключевых функциях:
#eip6909
На этой неделе поговорим о функциях в стандарте и некоторых моментах его использования.
1. transfer():
Функция перевода ERC-6909 ведет себя так же, как и трансфер ERC-20, за исключением того, что она применяется к конкретному идентификатору токена. Функция принимает адрес получателя, id токена и сумму для перевода в качестве входных параметров и обновляет балансы с помощью связки balanceOf. Как и в функции перевода ERC-20, необходимо вернуть true, если транзакция выполнена успешно:
function transfer(address receiver, uint256 id, uint256 amount) public returns (bool) {
if (balanceOf[msg.sender][id] < amount) revert InsufficientBalance(msg.sender, id);
balanceOf[msg.sender][id] -= amount;
balanceOf[receiver][id] += amount;
emit Transfer(msg.sender, msg.sender, receiver, id, amount);
return true;
}2. transferFrom():
Функция transferFrom в ERC-6909 отличается от функции ERC-20 тем, что требует идентификатор токена. Кроме того, она проверяет наличие одобрения оператора в дополнение к разрешению.
Сначала функция проверяет, если (sender != msg.sender && !isOperator[sender][msg.sender]), гарантируя, что вызывающая сторона (msg.sender) является либо:
- Владелецем (отправителем), либо
- Одобренным оператором (isOperator[sender][msg.sender] == true).
Если отправитель msg.sender не является таковыми, то функция проверяет, достаточно ли у вызывающего абонента средств для перевода. Если резерв существует, но не установлен в неограниченное значение (type(uint256).max), то переведенная сумма вычитается из резерва.
Кроме того, в стандарте указано, что функция НЕ ДОЛЖНА вычитать сумму из резерва вызывающего абонента по идентификатору токена, если вызывающий абонент является оператором или отправителем.
function transferFrom(address sender, address receiver, uint256 id, uint256 amount) public returns (bool) {
if (sender != msg.sender && !isOperator[sender][msg.sender]) {
uint256 senderAllowance = allowance[sender][msg.sender][id];
if (senderAllowance < amount) revert InsufficientPermission();
if (senderAllowance != type(uint256).max) {
allowance[sender][msg.sender][id] = senderAllowance - amount;
}
}
if (balanceOf[sender][id] < amount) revert InsufficientBalance();
balanceOf[sender][id] -= amount;
balanceOf[receiver][id] += amount;
emit Transfer(msg.sender, sender, receiver, id, amount);
return true;
}3. approve():
Функция approve позволяет вызывающей стороне (msg.sender) предоставить определенное разрешение к ID спендеру. При этом обновляется маппинг, чтобы отразить новое состояние, и порождается событие Approval:
function approve(address spender, uint256 id, uint256 amount) public returns (bool) {
allowance[msg.sender][spender][id] = amount;
emit Approval(msg.sender, spender, id, amount);
return true;
}4. setOperator():
Функция setOperator позволяет вызывающей стороне (msg.sender) предоставить или отозвать разрешения оператора для определенного адреса (spender) от своего имени, установив параметр approved в true или false. Функция соответствующим образом обновляет отображение isOperator и порождает событие OperatorSet, чтобы уведомить внешних слушателей об изменении.
function setOperator(address spender, bool approved) public returns (bool) {
isOperator[msg.sender][spender] = approved;
emit OperatorSet(msg.sender, spender, approved);
return true;
}5. Events:
В стандарте предусмотрены три события для порождения в ключевых функциях:
event Transfer(address caller, address indexed sender, address indexed receiver, uint256 indexed id, uint256 amount);
event OperatorSet(address indexed owner, address indexed spender, bool approved);
event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount);
#eip6909
👍2
Стандарт ERC-6909 Minimal Multi-Token Standard. Часть 4
В последнем посте про этот стандарт поговорим о способах его применения.
Как Uniswap v4 PoolManager реализует ERC-6909?
В Uniswap третьей версии для каждой новой торговой пары создавался отдельный смарт-контракт через фабрику UniswapV3Factory. Это приводило к высоким комиссиям, поскольку развертывание нового контракта для каждого пула требовало дополнительных затрат газа.
Четвертая версия Uniswap кардинально изменила подход, внедрив единый управляющий контракт PoolManager.sol. Вместо создания отдельных контрактов для каждого пула, все операции теперь выполняются в рамках одного главного контракта, что существенно уменьшает затраты на создание новых торговых пар.
В предыдущих версиях сложные операции с участием нескольких пулов сопровождались множественными переводами токенов и дублирующими обновлениями данных. В Uniswap v4 применяется принципиально новая схема - токены хранятся в виде внутренних записей стандарта ERC-6909, что исключает необходимость физических переводов.
Пользователи по-прежнему могут выводить свои средства в виде стандартных ERC-20 токенов. Однако если активы остаются в протоколе, система использует их виртуальное представление по стандарту ERC-6909, что ускоряет операции и снижает комиссии. Такой подход позволяет совершать сделки без постоянного перемещения токенов между кошельками и контрактами.
При торговле между токенами A и B система просто изменяет соответствующие записи в рамках внутреннего учета, а не выполняет фактические переводы. Стоит отметить, что в Uniswap v4 стандарт ERC-6909 не применяется для токенов, представляющих долю в пуле ликвидности (LP-токены).
Метаданные ERC-6909 для синглтон-архитектур DeFi и NFT-коллекций
Интерфейс IERC6909Metadata определяет, как стандарт ERC-6909 связывает метаданные (name, symbols, decimals) с отдельными токенами.
Функции name, symbol и decimals могут изменяться в зависимости от id токена, позволяя разным токенам в рамках одного ERC-6909 контракта иметь уникальные параметры.
Для DeFi-протокола с несколькими LP-токенами может потребоваться стандартизация количества знаков после запятой (например, фиксированные 18 decimal), при этом названия и символы токенов должны отражать различные активы в пуле.
В случае с NFT (невзаимозаменяемыми токенами) значение decimals всегда должно быть равно 1, поскольку NFT неделимы.
В традиционных NFT-коллекциях (например, ERC-721) все токены используют одинаковые название и символ, представляющие коллекцию целиком (например, "CryptoPunks" с символом "PUNK"). Стандарт ERC-6909 позволяет сохранить подход ERC-721, где все NFT в коллекции разделяют общие метаданные.
Еще несколько интересных примеров с кодом вы можете посмотреть в оригинальной статье от RareSkills тут.
#eip6909
В последнем посте про этот стандарт поговорим о способах его применения.
Как Uniswap v4 PoolManager реализует ERC-6909?
В Uniswap третьей версии для каждой новой торговой пары создавался отдельный смарт-контракт через фабрику UniswapV3Factory. Это приводило к высоким комиссиям, поскольку развертывание нового контракта для каждого пула требовало дополнительных затрат газа.
Четвертая версия Uniswap кардинально изменила подход, внедрив единый управляющий контракт PoolManager.sol. Вместо создания отдельных контрактов для каждого пула, все операции теперь выполняются в рамках одного главного контракта, что существенно уменьшает затраты на создание новых торговых пар.
В предыдущих версиях сложные операции с участием нескольких пулов сопровождались множественными переводами токенов и дублирующими обновлениями данных. В Uniswap v4 применяется принципиально новая схема - токены хранятся в виде внутренних записей стандарта ERC-6909, что исключает необходимость физических переводов.
Пользователи по-прежнему могут выводить свои средства в виде стандартных ERC-20 токенов. Однако если активы остаются в протоколе, система использует их виртуальное представление по стандарту ERC-6909, что ускоряет операции и снижает комиссии. Такой подход позволяет совершать сделки без постоянного перемещения токенов между кошельками и контрактами.
При торговле между токенами A и B система просто изменяет соответствующие записи в рамках внутреннего учета, а не выполняет фактические переводы. Стоит отметить, что в Uniswap v4 стандарт ERC-6909 не применяется для токенов, представляющих долю в пуле ликвидности (LP-токены).
Метаданные ERC-6909 для синглтон-архитектур DeFi и NFT-коллекций
Интерфейс IERC6909Metadata определяет, как стандарт ERC-6909 связывает метаданные (name, symbols, decimals) с отдельными токенами.
Функции name, symbol и decimals могут изменяться в зависимости от id токена, позволяя разным токенам в рамках одного ERC-6909 контракта иметь уникальные параметры.
/// @notice Contains metadata about individual tokens.
interface IERC6909Metadata is IERC6909 {
/// @notice Name of a given token.
/// @param id The id of the token.
/// @return name The name of the token.
function name(uint256 id) external view returns (string memory);
/// @notice Symbol of a given token.
/// @param id The id of the token.
/// @return symbol The symbol of the token.
function symbol(uint256 id) external view returns (string memory);
/// @notice Decimals of a given token.
/// @param id The id of the token.
/// @return decimals The decimals of the token.
function decimals(uint256 id) external view returns (uint8);
}
Для DeFi-протокола с несколькими LP-токенами может потребоваться стандартизация количества знаков после запятой (например, фиксированные 18 decimal), при этом названия и символы токенов должны отражать различные активы в пуле.
В случае с NFT (невзаимозаменяемыми токенами) значение decimals всегда должно быть равно 1, поскольку NFT неделимы.
В традиционных NFT-коллекциях (например, ERC-721) все токены используют одинаковые название и символ, представляющие коллекцию целиком (например, "CryptoPunks" с символом "PUNK"). Стандарт ERC-6909 позволяет сохранить подход ERC-721, где все NFT в коллекции разделяют общие метаданные.
Еще несколько интересных примеров с кодом вы можете посмотреть в оригинальной статье от RareSkills тут.
#eip6909
👍3
Проект на виду. Часть 7. Обучение с нейронками
Вы, наверное, помните, что я уже пару-тройку месяцев интересуюсь языковыми моделями, автоматизированным программированием и всем, что с этим связано. Сегодня хочу обсудить, насколько эффективно можно учиться самостоятельно, используя только современные нейросети.
Я пробовал создавать небольшие проекты в Cursor на разных языках - Python, Rust, Java - с использованием соответствующих инструментов вроде Flask для Python. Поскольку я не знал этих языков, мне было интересно проверить, получится ли полноценно программировать, полагаясь только на нейросети. Результат оказался разочаровывающим - об этом я уже писал раньше.
После нескольких неудачных попыток разобраться в сгенерированном коде я решил попробовать другой подход: попросил нейросеть научить меня основам Python. Мой запрос был простым: "Ты преподаватель Python. У меня есть опыт в PHP и JavaScript, но о Python я не знаю ничего. Составь пять первых уроков для новичка с примерами кода и заданиями".
Нейросеть выдала уроки, которые на первый взгляд выглядели неплохо. Но тут я столкнулся с неожиданной проблемой: как понять, что программа обучения составлена правильно и ничего важного не упущено? Когда я спросил, какие ключевые моменты могли быть пропущены, нейросеть добавила несколько пунктов - например, про отсутствие точек с запятой и важность отступов в Python.
Однако чем больше я задавал уточняющих вопросов, тем больше запутывался. В конечном счете мне пришлось искать обычные учебные программы и видеоуроки, потому что нейросеть не смогла предоставить систематизированный подход к обучению.
Это подводит меня к важному выводу: когда вы не знаете предмета и не имеете четкого плана обучения, очень сложно чему-то научиться. Даже современные нейросети не могут заменить полноценного учебного курса.
Возникает вопрос: зачем вообще учить языки программирования, если нейросети могут писать код? Ответ прост: чтобы понимать, какой код перед вами - качественный или наполненный ненужными элементами вроде избыточного логирования, временных тестов или одноразовых библиотек.
То же самое касается и Solidity. Нейросеть может дать сжатый курс, где в первую же неделю будут и типы данных, и функции, и контракты. Но в web3-разработке важны нюансы - недостаточно просто знать о существовании тех или иных возможностей, нужно уметь их правильно применять.
В итоге получается, что языковые модели, при всей их эрудированности, пока не способны заменить полноценного преподавателя и хорошо структурированную учебную программу. Лучший способ их использовать - сначала изучать основы по проверенным источникам, а затем обращаться к нейросетям за разъяснением конкретных вопросов и дополнительными деталями.
Надеюсь, что скоро расскажу вам, чем я там таким интересным занимаюсь помимо аудитов смарт контрактов!
#offtop
Вы, наверное, помните, что я уже пару-тройку месяцев интересуюсь языковыми моделями, автоматизированным программированием и всем, что с этим связано. Сегодня хочу обсудить, насколько эффективно можно учиться самостоятельно, используя только современные нейросети.
Я пробовал создавать небольшие проекты в Cursor на разных языках - Python, Rust, Java - с использованием соответствующих инструментов вроде Flask для Python. Поскольку я не знал этих языков, мне было интересно проверить, получится ли полноценно программировать, полагаясь только на нейросети. Результат оказался разочаровывающим - об этом я уже писал раньше.
После нескольких неудачных попыток разобраться в сгенерированном коде я решил попробовать другой подход: попросил нейросеть научить меня основам Python. Мой запрос был простым: "Ты преподаватель Python. У меня есть опыт в PHP и JavaScript, но о Python я не знаю ничего. Составь пять первых уроков для новичка с примерами кода и заданиями".
Нейросеть выдала уроки, которые на первый взгляд выглядели неплохо. Но тут я столкнулся с неожиданной проблемой: как понять, что программа обучения составлена правильно и ничего важного не упущено? Когда я спросил, какие ключевые моменты могли быть пропущены, нейросеть добавила несколько пунктов - например, про отсутствие точек с запятой и важность отступов в Python.
Однако чем больше я задавал уточняющих вопросов, тем больше запутывался. В конечном счете мне пришлось искать обычные учебные программы и видеоуроки, потому что нейросеть не смогла предоставить систематизированный подход к обучению.
Это подводит меня к важному выводу: когда вы не знаете предмета и не имеете четкого плана обучения, очень сложно чему-то научиться. Даже современные нейросети не могут заменить полноценного учебного курса.
Возникает вопрос: зачем вообще учить языки программирования, если нейросети могут писать код? Ответ прост: чтобы понимать, какой код перед вами - качественный или наполненный ненужными элементами вроде избыточного логирования, временных тестов или одноразовых библиотек.
То же самое касается и Solidity. Нейросеть может дать сжатый курс, где в первую же неделю будут и типы данных, и функции, и контракты. Но в web3-разработке важны нюансы - недостаточно просто знать о существовании тех или иных возможностей, нужно уметь их правильно применять.
В итоге получается, что языковые модели, при всей их эрудированности, пока не способны заменить полноценного преподавателя и хорошо структурированную учебную программу. Лучший способ их использовать - сначала изучать основы по проверенным источникам, а затем обращаться к нейросетям за разъяснением конкретных вопросов и дополнительными деталями.
Надеюсь, что скоро расскажу вам, чем я там таким интересным занимаюсь помимо аудитов смарт контрактов!
#offtop
👍10❤1
Что-то кончается, что-то начинается
На прошлой неделе закончился 1 модуль курса. Он был существенно дополнен новыми уроками по EVM, кучей вопросов для самопроверки, а также небольшой социальной частью.
В самом начале модуля я рассказал участникам, что сейчас лучше всего искать работу через web3 сообщество, а именно в социальной сети Твиттер.
Вся жизнь web3 происходит именно там: свежие новости о хакерских атаках, полезные советы по Solidity, программы для начинающих разработчиков и, конечно же, вакансии. Гораздо проще получить первую работу, если вы активно ведёте аккаунт и делитесь полезным контентом (не говоря уже об аудиторах, которые благодаря участию в конкурсах получают огромный рост аудитории и стабильный доход).
Да и работодателям проще понять, подходите ли вы им, по вашим постам и активности, чем по сухому резюме.
Именно поэтому на модуле бонусом были посты про то, как вести свой аккаунт, а также некоторые личные рекомендации пользователей и компаний, за которыми интересно следить.
Вести блог или соцсети одновременно и легко, и сложно. Но именно это помогает вас заметить. Если вы меняете профессию — это отличный повод документировать свой путь. Так, например, появился и этот канал — мой личный опыт в web3 и Solidity.
Раскрутка аккаунта может занять больше года, и важно работать над этим ежедневно. Поэтому лучше начинать уже во время обучения, а не в конце, когда знания есть, а времени на развитие личного бренда уже нет.
Помните: ваш аккаунт — это ваша визитная карточка. Даже если сейчас у вас мало подписчиков, каждый пост — это вклад в вашу репутацию. Комментируйте новости, делитесь своими успехами и ошибками, задавайте вопросы экспертам. Так вы не только учитесь быстрее, но и обрастаете полезными связями.
Не ждите идеального момента — его не будет. Начните сегодня: напишите пост о том, что нового узнали, сделайте разбор интересного кейса или просто расскажите о своих целях. Со временем это превратится в мощный ресурс, который откроет вам двери в лучшие проекты.
Это было необычным бонусом на этом модуле, а на следующем - будет что-то новое!
P.S. Отдельный респект всем, кто узнал отсылку в заголовке поста!
#курс
На прошлой неделе закончился 1 модуль курса. Он был существенно дополнен новыми уроками по EVM, кучей вопросов для самопроверки, а также небольшой социальной частью.
В самом начале модуля я рассказал участникам, что сейчас лучше всего искать работу через web3 сообщество, а именно в социальной сети Твиттер.
Вся жизнь web3 происходит именно там: свежие новости о хакерских атаках, полезные советы по Solidity, программы для начинающих разработчиков и, конечно же, вакансии. Гораздо проще получить первую работу, если вы активно ведёте аккаунт и делитесь полезным контентом (не говоря уже об аудиторах, которые благодаря участию в конкурсах получают огромный рост аудитории и стабильный доход).
Да и работодателям проще понять, подходите ли вы им, по вашим постам и активности, чем по сухому резюме.
Именно поэтому на модуле бонусом были посты про то, как вести свой аккаунт, а также некоторые личные рекомендации пользователей и компаний, за которыми интересно следить.
Вести блог или соцсети одновременно и легко, и сложно. Но именно это помогает вас заметить. Если вы меняете профессию — это отличный повод документировать свой путь. Так, например, появился и этот канал — мой личный опыт в web3 и Solidity.
Раскрутка аккаунта может занять больше года, и важно работать над этим ежедневно. Поэтому лучше начинать уже во время обучения, а не в конце, когда знания есть, а времени на развитие личного бренда уже нет.
Помните: ваш аккаунт — это ваша визитная карточка. Даже если сейчас у вас мало подписчиков, каждый пост — это вклад в вашу репутацию. Комментируйте новости, делитесь своими успехами и ошибками, задавайте вопросы экспертам. Так вы не только учитесь быстрее, но и обрастаете полезными связями.
Не ждите идеального момента — его не будет. Начните сегодня: напишите пост о том, что нового узнали, сделайте разбор интересного кейса или просто расскажите о своих целях. Со временем это превратится в мощный ресурс, который откроет вам двери в лучшие проекты.
Это было необычным бонусом на этом модуле, а на следующем - будет что-то новое!
P.S. Отдельный респект всем, кто узнал отсылку в заголовке поста!
#курс
🔥15❤1