На этой неделе мы заканчиваем с переводом и разбором статей Alchemy, посвященные Account Abstraction. И сегодня продолжим говорить о создании Кошельков.
Первая попытка: Развертывание произвольных контрактов
Теперь, когда мы знаем о CREATE2, наш изначальный план прост. Мы позволим пользователям передавать код инициации (init code), а точка входа будет разворачивать его. Для начала мы добавим еще одно поле в пользовательские операции:
struct UserOperation {
// ...
bytes initCode;
}Затем мы обновим часть валидации в handleOps, чтобы сделать следующее:
В рамках проверки пользовательской операции, если операция имеет непустой initCode, то будет использоваться CREATE2 для развертывания контракта с этим init-кодом.
Затем выполняем остальную часть проверки:
1. Вызываем метод validateOp только что созданного кошелька;
2. Затем, если у операции есть paymaster, вызываем метод validatePaymasterOp в paymaster;
Так мы сможем выполнить наши изначальные задачи: пользователи смогут развернуть произвольные контракты и заранее знать их адреса, а само развертывание может спонсироваться или paymaster, или пользователем.
Тем не менее, есть несколько проблем, которые связаны с тем, что мы просим пользователя отправить, а контракт подтвердить произвольный блок байткода:
1. Когда paymaster просматривает пользовательские операции, он не может проанализировать байткод, чтобы решить, хочет ли он платить за него или нет;
2. Когда пользователь отправляет байткод для развертывания контракта, он не может легко проверить, что отправленный им байткод выполняет то, что он хочет. Если пользователь использует инструмент для развертывания контракта, то, если инструмент вредоносный или взломанный, он может предоставить код init, который установит бэкдор в развернутый контракт, и этот баг будет сложно обнаружить;
3. Вспомните из первой части, что bundler хочет имитировать проверку каждой операции, которую он включает в пакет, чтобы в итоге не включать операции, не прошедшие проверку, за которые ему потом придется платить газом из собственных средств. Но поскольку init code - это произвольный код, он может легко сработать во время симуляции, но провалиться во время выполнения.
Нам нужен способ, чтобы пользователи могли развертывать контракты, не предоставляя произвольный байткод, а другие участники могли иметь некоторые гарантии относительно поведения развертывания.
Как обычно, когда мы хотим получить больше гарантий исполнения коды, приходит время ввести новый смарт-контракт...
#accountabstraction