В данном проекте разработан смарт контракт, дублирующий некоторую логику EO аккаунтов (Externally Owned Accounts):
- Получение токенов
- Отправка токенов
- Подпись транзакций
Дополнительно в контракте реализован функционал восстановления (смены владельца) с использованием доверенных лиц.
Подразумеваются, что токены соответствуют интерфейсу IERC20 стандарта ERC20.
Подробности концепции account abstraction можно изучить в следующих источниках:
Part I: WTF is Account Abstraction
Part II: WTF is Account Abstraction
Why EOA Wallets are a Threat to the Future of Blockchain
Implementing account abstraction as part of eth1.x
Смарт контракт был реализованный на языке Solidity последней (на момент 08.11.22) версии 0.8.17.
Использовались верифицированные контракты OpenZeppelin:
- access/Ownable.sol
- token/ERC20/ERC20.sol
Помимо этого была использована некоторая видоизмененная часть access/AccessControl.sol (см. в contracts/AccessControl.sol)
Комментарии к коду были добавлены в соответствии со стандартом NatSpec.
Стиль оформления контракта был во многом осуществлен под влиянием следующих статей:
Solidity Style Guide (Part II)
Описание API контракта можно посмотреть в документации, расположенной папке docs.
Данный функционал был реализован с использованием определенных модификаторов (см. onlyOwner и onlyRole).
Для аккаунтов введены две роли:
- администратор
- доверенное лицо
В любой момент времени и при любых ситуациях владелец кошелька является администратором, и наоборот.
Доверенное лицо добавляется администратором посредством выполнения следующей функции:
grantTrustedRole(accountAddress)
Администратор также может убрать аккаунт из списка доверенных при помощи следующего запроса:
revokeTrustedRole(accountAddress)
Сама смена владельца реализована в два этапа (см. ниже).
Первым делом подразумевается инициализация восстановления, посредством выполнения любым из доверенных лиц следующей функции:
initRecovery(newAccountAddress)
Далее каждое доверенное лицо должно выполнить следующий запрос:
approveRecovery(newAccountAddress)
В результате всего этого, владельцом (и администратором) становится новый аккаунт с адресом newAccountAddress.
Данная логика имеет некоторые риски, т.к. доверенные лица могут сговориться и сменить владельца без его ведома. Поэтому для повышения вероятности обнаружения данной ситуации текущим владельцем был введен механизм timelock.
Последнее одобрение доверенным лицом может выполнится лишь через некоторый промежуток времени (TIME_LOCK_PERIOD = 1 days) после предпоследнего.
Различные другие кейсы можно посмотреть в соответствующих тестах.
В папке test расположены тесты, покрывающие большое количество позитивных и негативных сценариев (порядка 50 штук). При их разработке использовались инструменты hardhat, waffle, ethers, mocha, solidity-coverage.
Для эмуляции взаимодействия с токенами IERC20 был использован соответствующий Mock контракт.
Таблица покрытия тестов выглядит следующим образом: