В предыдущих постах мы разбирали базовые понятия Account Abstraction, полностью скопировали функциональность EOA и улучшили его, позволив пользователям выбирать собственную логику проверки операции. Но пока что кошельку все еще нужно оплачивать газ, а это значит, что владельцу кошелька нужно найти способ получить немного Эфира, прежде чем он сможет выполнять какие-либо действия.
А что если бы, газ мог заплатить не владелец кошелька, а кто-то другой? И мы переходим ко второй статье от Alchemy: Account Abstraction Part 2: Sponsoring Transactions Using Paymasters.
Есть несколько веских причин, чтобы разрешить другому пользователю оплачивать газ:
1. Если владелец кошелька - новичок в блокчейне, то необходимость приобретения ETH перед выполнением действий на цепочке станет огромным камнем преткновения;
2. Dapp может быть готов оплачивать бензин для своих методов, чтобы плата за газ не отпугивала потенциальных пользователей;
3. Спонсор может позволить кошельку оплачивать газ в каком-либо токене, отличном от ETH, например, в USDC;
4. Для обеспечения конфиденциальности пользователь может захотеть вывести активы из миксера на свежий адрес и списать плату за газ на счет, не связанный с ним;
Представляем paymasters
Допустим, я создаю dapp, который хочет платить за газ других людей. Предположительно, я не хочу платить за газ всех и каждого, поэтому мне нужно внедрить в цепочку кстомную логику, которая может посмотреть на операции пользователя и решить, хочет ли она оплатить эти операции или нет.
Чтобы внедрить кастомную логику в цепочку, нужно развернуть контракт, который мы назовем paymaster.
У него будет один метод, который смотрит на пользовательскую операцию и решает, хочет ли он заплатить за эту операцию или нет:
contract Paymaster {
function validatePaymasterOp(UserOperation op);
}Затем, когда кошелек отправляет операцию, ему нужно будет указать, какой paymaster (если таковой имеется) будет оплачивать его газ.
Мы добавим новое поле в UserOperation, чтобы обозначить это.
Мы также добавим в пользовательскую операцию поле, которое кошелек сможет использовать для передачи произвольных данных в paymaster, чтобы помочь ему убедить paymaster оплатить свои расходы.
Например, это может быть что-то, что было подписано владельцем кошелька вне цепи.
struct UserOperation {
// ...
address paymaster;
bytes paymasterData;
}Далее мы изменим handleOps, чтобы использовать новые paymasters.
Теперь ее поведение будет таким для каждой операции:
1. Вызываем validateOp на кошельке, указанном отправителем операции;
2. Если у операции есть адрес paymaster, то вызовается validatePaymasterOp для этого paymaster;
3. Все операции, которые не прошли проверку, отбрасываются;
4. Для каждой операции вызываем executeOp на кошельке отправителя операции, отслеживая, сколько газа мы использовали, затем переводим ETH исполнителю, чтобы оплатить этот газ. Если у операции есть поле paymaster, то этот ETH поступает от paymaster. В противном случае он поступает из кошелька, как и раньше.
Как и кошельки, paymaster'ы депонируют свои ETH через метод депозита, прежде чем они могут быть использованы для оплаты операций.
На самом деле это довольно просто, верно?
Мы просто попросим бандлер обновить свои симуляции и...
#accountabstraction
