区块链中文技术社区

BTTC跨链分享

一、原理

BTTC跨链

跨链桥

跨链桥提供了一条在 侧链 和 主链 之间的可信双向交易通道。

当代币通过跨链桥传递时,它的总流通量不会被影响

架构

BTTC是三层架构:

Bridge:负责监听各链路事件,发送事件消息等。

Core:共识模块,包括Checkpoint(BitTorrent-Chain链的状态快照)的验证,Statesync事件&Staking事件的共识。

REST-Server:提供相关API服务。

实现:Delivery

Root Contracts

目前支持与BTTC跨链的根链有 TRON, Ethereum, BSC。BTTC设计的框架支持后续增加其它的公共区块链,仅需要在该公链上部署以下3类合约即可:

部署的合约列表查看

Child Contracts

BTTC子链上为支持跨链所部署的合约有:

代币映射

使用 BTTC 跨链桥需要先将 Root Token、Child Token 进行映射。

操作步骤:

  1. 实现子代币合约

    1. 标准子代币(20,721):继承项目代码中 的 ChildERC20,确保有deposit以及withdrawTo方法
    2. 自定义子代币:实现自己的子代币合约
  2. 将子代币合约部署到 BTTC 网上

    1. 参考 deploy_child_chain_contracts.js进行部署;
    2. 部署时需要 BTTC 上的 ChildChainManager 合约地址;
  3. 提交映射请求

    1. 这里提交映射请求,其中 The Token Contract Address on Ethereum/BSC/TRON 是根链上的根代币合约地址,The Token Contract Address on BTTC 是部署在BTTC上的子代币合约地址。
    2. 审核时间是3~5个工作日

根链权限

deposit 需要根链锁币,withdraw 需要解锁相关资产。

代币映射时,会指定代币类型,每种类型有对应的 Predicate 合约。

锁币:交易发起者 Approve 对应的 Predicate 合约,批准合约Predicate消费代币,将 token 从发起者账户转给 Predicate 地址;

解锁:Predicate 地址给接收者账户转 token。

Token TypePredicate
ERC20ERC20Predicate
ERC721ERC721Predicate
MintableERC20MintableERC20Predicate
MintableERC721MintableERC721Predicate

二、跨链流程

前提

进行充提币操作之前,需要先下载插件钱包并连接钱包中的账户地址。

目前BTTC网页支持2种钱包插件,分别为 TronLinkMetaMask

2.1 根链 <-> BTTC

deposit

状态转移数据格式:

/* StateSynced event内数据格式如下
{
  id: counter++,
  receiver: childChainManagerAddress,
  calldata: abi.encode(
    DEPOSIT,
    abi.encode(user, rootToken, CHAIN_ID, depositeData)
  )
}
*/

type MsgEventRecord struct {
   From            // 提交tx的Delivery节点地址
   TxHash          // deposit tx 的 tx hash
   LogIndex        // 日志的index
   BlockNumber     // 日志所在的block number
   ContractAddress // StateSynced 事件的 receiver,即 ChildChainManagerAddress
   Data            // StateSynced 事件的 data
   ID              // StateSynced 事件的 id, StateSender 合约维护一个counter,每次发出 StateSynced事件则加1
   ChainID         // 子链 ID
   RootChainType   // 根链类型,TRON? ETH? BSC?
}

checkpoint

Delivery层将BTTC层生产的区块聚合成一棵Merkle树,并定期将Merkle根发布到根链,这种定期发布称为检查点

Checkpoint很重要:

checkpoint 同步流程

  1. Delivery bridge 同步到最新的BTTC new header,验证header后发现该提交checkpoint,则 当前的 proposer 为每条根链创建对应的 checkpoint tx,并发送给 BTTC 节点。该 tx.Msg 数据格式如下:
type MsgCheckpoint struct {
  Proposer        // checkpoint 的提议者
  StartBlock      // checkpoint 开始的区块number
  EndBlock        // checkpoint 结束的区块number
  RootHash        // Merkle root
  AccountRootHash 
  BorChainID      // 子链 ID
  Epoch           
  RootChainType   // 根链类型,TRON? ETH? BSC?
}

StartBlock:访问根链RootChain合约的CurrentHeaderBlock及GetHeaderInfo方法可以获取根链记录的最新checkpoint,该checkpoint.end+1即为下一个checkpoint的start;

假设正常的checkpoint [StartBlock, EndBlock] 如下:[1,128], [129, 256],...若第一个checkpoint([1, 128]),由于各种原因导致根链没有接收并更新合约内存储的内容,则要发送给该根链的 checkpoint 是 [1, 256]

  1. 这些checkpoint tx被打包进block,执行后将生成 EventTypeCheckpoint 事件的日志;validator会对执行结果进行 Precommit 投票,收集到超过2/3的 Precommit 投票才有效。
// Emit event for checkpoint
ctx.EventManager().EmitEvents(sdk.Events{
   sdk.NewEvent(
      types.EventTypeCheckpoint,
      sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
      sdk.NewAttribute(types.AttributeKeyProposer, msg.Proposer.String()),
      sdk.NewAttribute(types.AttributeKeyStartBlock, strconv.FormatUint(msg.StartBlock, 10)),
      sdk.NewAttribute(types.AttributeKeyEndBlock, strconv.FormatUint(msg.EndBlock, 10)),
      sdk.NewAttribute(types.AttributeKeyRootHash, msg.RootHash.String()),
      sdk.NewAttribute(types.AttributeKeyAccountHash, msg.AccountRootHash.String()),
   ),
})
  1. bridge 监听到该事件,proposer 将创建和广播 checkpoint tx 给对应的根链。
  2. 给 ETH、BSC 发送 checkpoint tx:获取之前提交的、针对对应根链的 checkpoint tx,将其转换成 stdTx,再封装成 tx 的 SideTxMsg,提交一个新的tx,该tx调用 RootChain 合约的 submitCheckpoint 方法,其中 SideTxMsg 以及 checkpoint tx 的投票作为参数传递。

    1. 调用 StakeManager.sol 的 checkSignatures 方法对投票进行验签
    2. 根链的 RootChainStorage 合约保存 checkpoint;
// RootChainStorage.sol
mapping(uint256 => HeaderBlock) public headerBlocks

// RootChain.sol submitCheckpoint() 
function _buildHeaderBlock(
        address proposer,
        uint256 start,
        uint256 end,
        bytes32 rootHash
    ) private returns (bool) {
  ...
  HeaderBlock memory headerBlock = HeaderBlock({
     root: rootHash,
     start: nextChildBlock,
     end: end,
     createdAt: now,
     proposer: proposer
  });

  headerBlocks[_nextHeaderBlock] = headerBlock;
  ...
}

// RootChain.sol
function getLastChildBlock() external view returns (uint256) {
   return headerBlocks[currentHeaderBlock()].end;
}
  1. ETH、BSC 执行该 tx 后,会 emit NewHeaderBlock 事件
  2. TRON 处理流程相同
  3. bridge 监听到来自根链的 NewHeaderBlock 事件后,proposer 给 BTTC 发布 checkpoint ack tx。

exit withdraw

调用RootChainManager合约的exit方法来解锁并从ERC20Predicate合约接收代币。这个方法接收一个参数:代币的销毁证明。

调用这个方法之前必须要等待包含销毁交易的checkpoint提交成功。销毁证明由RLP编码生成如下字段:

销毁证明可以自己生成,也可以调用 BTTC SDK 生成

2.2 根链 <-> 根链

TRON、Ethereum、BSC网络之间的跨链

以 WIN 为例:原始代币 WIN 部署在 TRON 链上,其对应的子代币合约为 WIN_t ,Ethereum 链代币对应的子代币合约为 WIN_e,BSC链代币对应的子代币合约为 WIN_b。

子代币合约

WIN_e、WIN_b 两个合约与 WIN_t 所映射的子代币合约略有不同:

根链代币合约

原始代币:部署在 TRON 上

其它根链代币:非标准代币,继承自 IMintableERC20,部署时需要指定主链上的 MintableAssetPredicate(例如:MintableERC20Predicate。Asset表示资产类型,下同) 合约为铸币者

MintableERC20Predicate 与 ERC20Predicate 的 exit() 方法实现不同:

TRON给其它根链转账

操作:TRON 的账户 Addr_t 签名发起交易,转 100 WIN 给 BSC 的账户 Addr_b;

步骤TRON Addr_tBTTC Addr_bBTTC Addr(WIN_b)BSC Addr_b
充值-100 WIN+100 WIN_t (mint)
提币1: swapIn -100 WIN_t, +100 WIN_b (mint)+100 WIN_t
提币2: withdrawTo -100 WIN_b (burn)
收币 +100 WIN

其它根链给TRON转账

操作:从 BSC 的账户 Addr_b 转100 WIN给 TRON 的账户 Addr_t;

步骤BSC Addr_bBTTC Addr_bBTTC Addr(WIN_b)TRON Addr_t
充值-100 WIN+100 WIN_b (mint)
提币1: swapOut -100 WIN_b (burn), +100 WIN_t-100 WIN_t
提币2: withdrawTo -100 WIN_t (burn)
收币 +100 WIN

BSC给Ethereum转账

操作:从 BSC 的账户 Addr_b 转100 WIN给 Ethereum 的账户 Addr_e;

步骤BSC Addr_bBTTC Addr_bBTTC Addr(WIN_b)BTTC Addr(WIN_e)Ethereum Addr_e
充值-100 WIN+100 WIN_b (mint)
提币1: swapOut -100 WIN_b (burn), +100 WIN_t-100 WIN_t
提币2: swapIn -100 WIN_t (burn), +100 WIN_e +100 WIN_t
提币3: withdrawTo -100 WIN_e (burn)
收币 +100 WIN

Ethereum给BSC转账

操作:从 Ethereum 的账户 Addr_e 转100 WIN给 BSC 的账户 Addr_b;

步骤Ethereum Addr_eBTTC Addr_eBTTC Addr(WIN_b)BTTC Addr(WIN_e)BSC Addr_b
充值-100 WIN+100 WIN_e (mint)
提币1: swapOut -100 WIN_e (burn), +100 WIN_t+100 WIN_t
提币2: swapIn -100 WIN_t (burn), +100 WIN_b -100 WIN_t
提币3: withdrawTo -100 WIN_b (burn)
收币 +100 WIN

2.3 关于 BTT

BTT在各条链上的代币合约:

TRON:

genesis-contracts/bttc-contracts/contracts/child/MRC20.sol

Ethereum & BSC:

三、总结

3.1 安全

使用侧链进行跨链的风险:

每个侧链交易都会收集Precommit投票,只有超过2/3的节点进行了投票,交易结果才有效;

根链同步BTTC的staking情况,能验证针对侧链状态的Precommit投票。

3.2 vs Polygon

3.3 侧链 vs 中继

侧链中继
从属关系从属于主链没有
作用区块链的可扩展性跨链数据的传输
实现将主链上的资产转移到侧链上来处理从各主链抽象分离出来的一个跨链操作层
代表Polygon,BTTCCosmos,Polkadot

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »