Мост ChainBridge между Ethereum и Moonbeam

Moonbeam in Russian
11 min readApr 16, 2021

--

Введение

Мост позволяет двум экономически независимым и технологически различным цепям взаимодействовать друг с другом. Мосты могут варьироваться от централизованных и надежных до децентрализованных и с минимальным доверием. Одним из доступных решений на данный момент является ChainBridge, модульный разно-направленный мост на blockchain, разработанный командой ChainSafe. Интеграция ChainBridge теперь доступна и на Moonbeam. Данная интеграция соединяет нашу альфа тестовую сеть Moonbeam — Moonbase и Rinkeby/Kovan тестовые сети эфира.

Это руководство разбито на два основных раздела. В первой части мы объясним общий рабочий процесс моста. Во второй части рассмотрим несколько примеров использования моста для передачи ресурсов ERC-20 и ERC-721 между Moonbase Alpha и Rinkeby / Kovan.

Как работает мост

ChainBridge по своей сути является протоколом передачи сообщений. События в исходном чейне используются для отправки сообщения, которое направляется в цепочку назначения. В данном процессе есть 3 основные роли:

  • Слушатель: извлекает события из первоначального чейна и создает сообщение.
  • Роутер: передает сообщение от слушателя до писателя.
  • Писатель: интерпретирует сообщения и отправляет транзакцию на чейн-получатель.

В настоящее время ChainBridge полагается на доверенные ретрансляторы для выполнения этих ролей. Тем не менее, он имеет механизм, который предотвращает злоупотреблением полномочиями и ненадлежащее использование средств любым ретранслятором. На высоком уровне ретрансляторы создают предложения в целевой цепочке, которые отправляются на утверждение другим ретрансляторам. Утверждающее голосование также происходит в целевой цепочке, и каждое предложение выполняется только после того, как оно достигает определенного порога голосования.

По обе стороны моста есть набор смарт-контрактов, каждый из которых выполняет определенную функцию:

  • Контракт Моста — пользователи и ретрансляторы взаимодействуют с этим контрактом. Он делегирует вызовы контрактам обработчика для депозитов, запускает транзакцию в исходной цепочке и для выполнения предложений в целевой цепочке.
  • Контракты обработчика — проверяет параметры, предоставленные пользователем, создавая запись депозита / исполнения.
  • Целевой контракт — как следует из названия, это контракт, с которым мы собираемся взаимодействовать с каждой стороны моста.

Общий рабочий процесс

Общий рабочий процесс следующий (от чейн A к чейн B):

  • Пользователь инициирует транзакцию с помощью функции deposit () в мостовом контракте чейна A. Здесь пользователю необходимо ввести целевчй чейн, идентификатор ресурса и calldata (определения после диаграммы). После нескольких проверок вызывается функция deposit () контракта-обработчика, которая выполняет соответствующий вызов целевого контракта.
  • После того, как функция целевого контракта в чейне A выполнена, мостовым контрактом генерируется событие депозита, которое содержит необходимые данные для выполнения в чейне B. Это называется предложением. Каждое предложение может иметь пять статусов (неактивно, активно, прошло, выполнено и отменено).
  • Ретрансляторы всегда слушают с обеих сторон чейна. Как только ретранслятор принимает событие, он инициирует голосование по предложению, которое происходит в мостовом контракте в чейне B. Это устанавливает состояние предложения с неактивного на активное.
  • Ретрансляторы должны проголосовать за предложение. Каждый раз, когда ретранслятор голосует, мостовой контракт генерирует событие, которое обновляет его статус. После достижения порога статус меняется с активного на пройденный. Затем ретранслятор выполняет предложение в чейне B через мостовой контракт.
  • После нескольких проверок мост выполняет предложение в целевом контракте через контракт обработчика в чейне B. Запускается другое событие, которое обновляет статус предложения с «передано» на «выполнено».

Этот рабочий процесс представлен на следующей диаграмме:

Два целевых контракта на каждой стороне моста связаны путем выполнения серии регистраций в соответствующем контракте обработчика через мостовой контракт. Эти регистрации в настоящее время могут быть выполнены только администратором мостового контракта.

Общие определения

Здесь мы собрали список концепций, применимых к реализации ChainBridge (от цепочки A до цепочки B):

  • ChainBridge Chain ID — не путать с идентификатором чейна сети. Это уникальный сетевой идентификатор, используемый протоколом для каждого чейна. Он может отличаться от фактического идентификатора чейна самой сети. Например, для Moonbase Alpha и Rinkeby мы установили идентификатор чейна ChainBridge на 43 и 4 соответственно (Кован был установлен на 42).
  • Идентификатор ресурса — это 32-байтовое слово, предназначенное для однозначной идентификации актива в кросс-чейн среде. Обратите внимание, что младший байт зарезервирован для chainId, поэтому у нас будет 31 байт всего для представления актива чейна в нашем мосте. Например, это может быть выражение tokenX в чейне A эквивалентно tokenY в чейне B
  • Calldata — это параметр, необходимый для обработчика, который включает информацию, необходимую для выполнения предложения в чейне B. Точная сериализация определяется для каждого обработчика. Вы можете найти больше информации здесь.

Протестируйте на Moonbase Alpha

Мы настроили ретранслятор с реализацией ChainBridge, который подключен к нашей тестовой сети Moonbase Alpha TestNet, а также к Rinkeby и Kovan TestNets Ethereum.

ChainSafe имеет предварительно запрограммированные обработчики, специфичные для интерфейсов ERC-20 и ERC-721, и эти обработчики используются для передачи токенов ERC-20 и ERC-721 между чейнами. Более подробную информацию можно найти здесь. В общих чертах, это просто сужение общей схемы, которую мы описали ранее, поэтому обработчик работает только с конкретными функциями токена, такими как блокировка / запись и чеканка / разблокировка.

В этом разделе будут рассмотрены два различных примера использования моста для перемещения токенов ERC-20 и ERC-721 между цепочками. Для взаимодействия с Moonbase Alpha и Rinkeby/Kovan вам понадобится следующая информация:

Передача токенов ERC-20

Токены ERC-20, которые нужно переместить через мост, должны быть зарегистрированы ретрансляторами в контрактах обработчиков. Поэтому для тестирования моста мы развернули токен ERC-20 (ERC20S), где любой пользователь может чеканить 5 токенов:

Аналогичным образом, прямое взаимодействие с контрактом Bridge и вызов функции deposit () с правильными параметрами может быть пугающим. Чтобы упростить процесс использования моста, мы создали модифицированный контракт моста, который создает необходимые входные данные для функции deposit ():

Проще говоря, в модифицированном контракте, используемом для инициирования передачи, для этого примера заранее определены chainID и resourceID. Следовательно, он создает объект calldata из ввода пользователя, который является только адресом получателя и значением, которое нужно отправить.

Общий рабочий процесс для этого примера можно увидеть на этой диаграмме:

Чтобы попробовать мост с этим образцом токена ERC-20, мы должны выполнить следующие шаги (независимо от направления передачи):

  • Токены в исходном чейне (это подтверждает контракт обработчика источника в качестве спонсора на указанную сумму Токенов)
  • Используйте модифицированный мостовой контракт в исходном чейне для отправки токенов
  • Подождите, пока процесс завершится
  • Утвердите контракт обработчика целевого чейна в качестве спонсора для отправки токенов обратно
  • Используйте модифицированный мостовой контракт в целевом чейне для отправки токенов

Примечание:

Помните, что токены будут переданы только в том случае, если в контракте обработчика будет достаточно разрешений на использование токенов от имени владельца. Если процесс не удался, проверьте разрешение.

Давайте отправим Kovan несколько токенов ERC20S с Moonbase Alpha. Для этого воспользуемся Remix. Во-первых, мы можем использовать следующий интерфейс для взаимодействия с этим контрактом и создания токенов:

pragma solidity ^0.6.4;

/**
Interface for the Custom ERC20 Token contract for ChainBridge implementation
Rinkeby/Moonbase Alpha ERC-20 Address :
0xDb148a131d775615E8707eE11708B88e601b4397
Kovan/Moonbase Alpha ERC-20 Address:
0xF1346880D471D4345D740401A9B082265bDcc76a
*/

interface ICustomERC20 {

// Mint 5 ERC20S Tokens
function mintTokens() external;

// Get Token Name
function name() external view returns (string memory);

/**
Increase allowance to Handler
Rinkeby/Moonbase Alpha ERC-20 Handler:
0xddaDdc5148C47f9E1926520d7AD2175dD5Aad4d5
Kovan/Moonbase Alpha ERC-20 Handler:
0xC290939834364f08C8177b2A787eb3E032Fab27e
*/
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);

// Get allowance
function allowance(address owner, address spender) external view returns (uint256);
}

Обратите внимание, что функция контракта токена ERC-20 также была изменена для утверждения соответствующего контракта обработчика в качестве спонсора при выпуске токенов.

В Remix загрузите интерфейсный контракт по адресу токена ERC-20 (убедитесь, что Вы используете внедренный провайдер Web3 MetaMask). Затем вызовите функцию mintTokens() и подпишите транзакцию. После подтверждения транзакции Вы должны получить 5 токенов ERC20S. Вы можете проверить свой баланс, добавив токен в MetaMask.

Когда у нас есть токены, мы можем приступить к их отправке через мост в целевой чейн. В этом случае помните, что мы делаем это от Moonbase Alpha до Кована. Следующий интерфейс позволяет использовать функцию sendERC20SToken() для инициации передачи.

pragma solidity 0.6.4;

/**
Simple Interface to interact with bridge to transfer the ERC20S token
Rinkeby/Moonbase Alpha Bridge Address:
0xB8254105AC9EBAe528728bbdCDd1E060d8d24D08
Kovan/Moonbase Alpha Bridge Address:
0x89863493571c063171bE47e00c9404063eF1947A
*/

interface IPSBridgeERC20 {

/**
* @notice Creates a deposit in the Bridge Contract for an ERC-20 Transfer,
* @param _recipient Address recipient of the tokens in the other chain
* @param _value Amount of tokens to be sent
*/
function sendERC20SToken(address _recipient, uint _value) external;

}

Итак, еще раз в Remix загрузите интерфейсный контракт по адресу моста. Затем вызовите функцию sendERC20SToken(), указав адрес получателя на другой стороне моста и сумму для перевода в WEI. MetaMask должен появиться и попросить Вас подписать транзакцию. После подтверждения транзакции процесс может занять около 3 минут, после чего Вы должны получить токены в Kovan!

Вы можете проверить свой баланс, добавив токен в MetaMask и подключив его к целевой сети — в нашем случае Kovan.

Помните, что Вы также можете выпускать токены ERC20S в Коване и отправить их в Moonbase Alpha. Чтобы утвердить спонсора или увеличить его размер, Вы можете использовать функцию increaseAllowance() предоставленного интерфейса. Чтобы проверить допустимость контракта обработчика в контракте токена ERC20, вы можете использовать функцию интерфейса allowance() .

Примечание:

Токены будут переданы только в том случае, если в контракте с обработчиком будет достаточно разрешений для траты токенов от имени владельца. Если процесс не удался, проверьте припуск.

Трансфер токена ERC-721

Как и в нашем предыдущем примере, контракты токенов ERC-721 должны быть зарегистрированы ретрансляторами, чтобы обеспечить передачу через мост. Поэтому мы настроили контракт токена ERC-721, чтобы любой пользователь мог создать токен для тестирования моста. Однако, поскольку каждый токен не является взаимозаменяемым и, следовательно, уникальным, функция доступна только в контракте токенов исходной цепочки, но не в целевом контракте. Как следствие, вам понадобится пара адресов контрактов ERC-721 для токенов в Rinkeby / Kovan и передачи их в Moonbase Alpha и еще одну пару для противоположного действия. Следующая диаграмма объясняет рабочий процесс для этого примера, где важно подчеркнуть, что идентификатор токена и метаданные сохраняются.

Чтобы произвести токены в Moonbase Alpha (названные ERC721Moon с символом ERC721M) и отправлять их туда и обратно Rinkeby/Kovan, Вам понадобится следующий адрес:

Чтобы произвести токены в Rinkeby / Kovan (ERC721E) и отправлять их туда и обратно на Moonbase Alpha, Вам понадобится следующий адрес:

Вместо взаимодействия с контрактом моста и вызова функции deposit() мы изменили контракт моста, чтобы упростить процесс использования самого моста (тот же адрес, что и в предыдущем примере):

Проще говоря, в модифицированном мостовом контракте, используемом для инициирования передачи, для этого примера заранее определены chainID и resourceID. Следовательно, он создает объект calldata из ввода пользователя, который является только адресом получателя и идентификатором отправляемого токена.

Давайте отправим токен ERC720E от Kovan на Moonbase Alpha. Для этого воспользуемся Remix. Следующий интерфейс можно использовать для взаимодействия с исходными контрактами ERC721 и произведением токенов. Функцию tokenOfOwnerByIndex()также можно использовать для проверки идентификаторов токенов, принадлежащих определенному адресу, передавая адрес и индекс для запроса (каждый идентификатор токена сохраняется как элемент массива, связанный с адресом):

pragma solidity ^0.6.4;

/**
Interface for the Custom ERC721 Token contract for ChainBridge implementation:
Rinkeby/Moonbase Alpha:
ERC721Moon: 0x23A5AdE9E1e5DB3F0Db2027d91041fe3d78b2358
ERC721Eth: 0x5A142d1658DCE58e180b0329d83569C4c0B6e424
Kovan/Moonbase Alpha:
ERC721Moon: 0xD1017C476f05DFc456c02C35Fb94D8aBf79766A0
ERC721Eth: 0xf0fC240f029c9E953D85350B35439ECA24BECbe2

interface ICustomERC721 {

// Mint 1 ERC-721 Token
function mintToken() external returns (uint256);

// Query tokens owned by Owner
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);

// Get Token Name
function name() external view returns (string memory);

// Get Token URI
function tokenURI(uint256 tokenId) external view returns (string memory);

**/
Set Approval for Handler
Rinkeby/Moonbase Alpha ERC-721 Handler:
0xc6B836d5C269AbB5a7a81F35597b8d9c32ea8933
Kovan/Moonbase Alpha ERC-721 Handler:
0xfB736169b682027AF57D282B83952d2a82f41d55
*/
function approve(address to, uint256 tokenId) external;

// Check the address approved for a specific token ID
function getApproved(uint256 tokenId) external view returns (address);
}

Обратите внимание, что функция контракта токена ERC-721 также была изменена для утверждения соответствующего контракта обработчика в качестве спонсора при произведении токенов.

В Remix загрузите интерфейсный контракт по адресу исходного токена ERC721E (убедитесь, что Вы используете внедренный поставщик Web3 MetaMask). Затем вызовите функцию mintTokens() и подпишите транзакцию. После подтверждения транзакции Вы должны получить токен ERC721E. Вы можете проверить свой баланс, добавив токен в MetaMask.

Получив токен, мы можем приступить к его отправке через мост в исходную цепочку. В этом случае помните, что мы сделаем это от Kovana до Moonbase Alpha. Следующий интерфейс позволяет использовать функцию sendERC721EthToken()для инициирования передачи токенов, изначально созданного в Kovan (ERC721E). Также, вы можете использовать функцию sendERC721MoonToken(), чтобы инициировать передачу токенов, изначально созданных в Moonbase Alpha (ERC721M).

pragma solidity 0.6.4;

/**
Simple Interface to interact with bridge to transfer the ERC721 tokens
Rinkeby/Moonbase Alpha Bridge Address:
0xB8254105AC9EBAe528728bbdCDd1E060d8d24D08
Kovan/Moonbase Alpha Bridge Address:
0x89863493571c063171bE47e00c9404063eF1947A
*/

interface IPSBridgeERC721 {

/**
* @notice Creates a deposit in the Bridge Contract for an ERC-721 Transfer,
* @param _recipient Address recipient of the tokens in the other chain
* @param _tokenID Token ID of the token to be sent
*/
// For tokens minted in Rinkeby/Kovan (ECR721E)
function sendERC721EthToken(address _recipient, uint _tokenID) external;

// For tokens minted in Moonbase Alpha (ECR721M)
function sendERC721MoonToken(address _recipient, uint _tokenID) external;
}

Итак, еще раз, в Remix загрузите контракт интерфейса по адресу моста. Затем вызовите функцию sendERC721EthToken(), указав адрес получателя на другой стороне моста и идентификатор токена для передачи. MetaMask должен показать окно с просьбой подписать транзакцию. После подтверждения транзакции процесс может занять около 3-х минут, после чего вы должны получить тот же идентификатор токена в Moonbase Alpha!

Вы можете проверить свой баланс, добавив токен в MetaMask и подключив его к исходной сети, в нашем случае Moonbase Alpha.

Помните, что Вы также можете создать токены ERC721M в Moonbase Alpha и отправить их в Kovana. Важно всегда проверять допуск, предоставленный контракту обработчика в соответствующем контракте токена ERC721. Вы можете утвердить контракт обработчика для отправки токенов от Вашего имени, используя функцию approve(), предусмотренную в интерфейсе. Вы можете проверить одобрение каждого из ваших идентификаторов токенов с помощью функции getApproved().

Примечание:

Токены будут переданы только в том случае, если контракт обработчика утвержден на передачу токенов от имени владельца. Если процесс не удался, проверьте утверждение.

Универсальный обработчик

Универсальный обработчик предлагает возможность выполнения функции в цепочке A и создания предложения для выполнения другой функции в цепочке B (аналогично общей диаграмме рабочего процесса). Это обеспечивает удобный способ соединения двух независимых блоков цепочек.

Если вы заинтересованы в реализации этой функции, вы можете связаться с нами напрямую через наш сервер Discord. Будем рады обсудить эту реализацию.

Мы хотим услышать Ваше мнение!

Если у Вас есть какие-либо отзывы относительно исследования блоков или любой другой темы, связанной с Moonbeam, не стесняйтесь связаться с нами используя официальный канал разработки в Discord .

Подготовлено при участии: Denis Bradulin, Anpol, AntonM, Lyn.

--

--

Moonbeam in Russian
Moonbeam in Russian

Written by Moonbeam in Russian

Moonbeam — это совместимая с Ethereum платформа смарт-контрактов на Polkadot

No responses yet