Как развернуть смарт-контракт на один и тот же адрес в разных блокчейнах?
Вы когда-нибудь развертывали смарт-контракт и замечали развернутый адрес? Кажется, что это набор случайных символов, и хотя это так, этот адрес является детерминированным.
Краткий обзор учетной записи и адреса в Ethereum:
В Ethereum существует два типа учетных записей: внешняя учетная запись (EOA) и контрактная учетная запись. Оба типа учетных записей имеют связанный с ними адрес. Адрес в Ethereum — это 42-символьный шестнадцатеричный адрес.
Например, адрес смарт-контракта UniswapV3Factory Uniswap — 0x1F98431c8aD98523631AE4a59f267346ea31F984 , и он одинаков в основной сети Ethereum, Polygon, Optimism, Arbitrum и Avalanche. То же самое относится ко всем смарт-контрактам Uniswap.
Как генерируется адрес смарт-контракта?
Адрес смарт-контракта получается из двух значений: адреса пользователя EOA и количества транзакций, отправленных пользователем. Это адрес кошелька пользователя и одноразовый номер.
Учебник по Nonce. Проще говоря, Nonce — это количество транзакций, которые пользователь совершил в данной цепочке блоков. Каждый раз, когда у пользователя есть исходящая транзакция, одноразовый номер увеличивается на единицу. Одноразовый номер уникален для каждого блокчейна, а это означает, что отправка транзакции в Ethereum увеличит одноразовый номер учетной записи в Ethereum, но не в Polygon.
Обратите внимание, что мы имеем в виду одноразовый номер учетной записи, относящийся к пользователю, а не одноразовый номер блока.
Как я упоминал в начале статьи, адрес смарт-контракта является детерминированным. Мы можем определить адрес до фактического развертывания смарт-контракта, используя адрес кошелька, с которого пользователь будет развертывать контракт, и их самый последний одноразовый номер + 1.
Ниже приведен пример кода, использующего ether.js для вычисления адреса перед развертыванием. Проверьте вывод
const walletAddress = "0xBf7504799c6ED34dbC7D3077e3198f1F5D2B1306"; const nonce = 0; let deployedAddress = ethers.utils.getAddress(ethers.utils.getContractAddress({from: walletAddress, nonce})); console.log(deployedAddress); //Console will print 0x488f7dab2688771f8d8308b2e65a0977d1b06e51 //verify via Polyscan https://mumbai.polygonscan.com/tx/0x84760a4617c32d2acd90c2c9baf465abbb72a64e26420585a0eca299eea9efef
Наконец, чтобы ответить на вопрос: «Как развернуть смарт-контракт на один и тот же адрес в разных блокчейнах?» ——>——>——>
В нашем кошельке я использую Metamask, мы должны сохранить учетную запись, назовем ее учетной записью развертывания, только для развертывания смарт-контрактов. Мы не должны совершать в нем никаких транзакций, кроме создания смарт-контракта. Отправка транзакций создания смарт-контрактов во всех блокчейнах с одним и тем же одноразовым номером приведет к тому, что везде будет использоваться один и тот же адрес смарт-контракта.
Тот же адрес делает смарт-контракт более удобным для разработчиков. Это уменьшает трение при поддержании адресов для разных окружений (основная сеть и тестовая сеть) и блокчейнов (Эфириум, Полигон и т. д.). Это также упрощает социализацию запуска.