网络信息
| 类型 | 网址 |
|---|---|
| 区块浏览器 | https://www.qeasyweb3.com/ |
| 测试水龙头 | http://faucet.qeasyweb3.com/ |
| ChainList | https://chainlist.org/chain/9528/ |
| 节点抵押 | http://scan.qeasyweb3.com/ |
注意
以上为测试链,代币无任何价值
当前为技术预览阶段,链数据可能重置
探索商业公链解决方案服务https://ethdpos.com/
| 类型 | 网址 |
|---|---|
| 区块浏览器 | https://www.qeasyweb3.com/ |
| 测试水龙头 | http://faucet.qeasyweb3.com/ |
| ChainList | https://chainlist.org/chain/9528/ |
| 节点抵押 | http://scan.qeasyweb3.com/ |
以上为测试链,代币无任何价值
当前为技术预览阶段,链数据可能重置
探索商业公链解决方案服务https://ethdpos.com/
对于Windows WSL的安装和对应镜像安装此片不做具体介绍,本篇文章只介绍Goland配置
首先Goland 打开相应代码项目后
通过菜单 File->Settings
打开Settings设置
打开Run Targets配置

然后添加 WSL

选择自己本地对应的WSL

根据自己WSL镜像中的go配置,选择对应的目录

然后修改编辑当前编译项目配置,选择前面设置的Targets

最后保存即可在WSL编译项目了
BTTC跨链

跨链桥提供了一条在 侧链 和 主链 之间的可信双向交易通道。
当代币通过跨链桥传递时,它的总流通量不会被影响
BTTC是三层架构:

Bridge:负责监听各链路事件,发送事件消息等。
Core:共识模块,包括Checkpoint(BitTorrent-Chain链的状态快照)的验证,Statesync事件&Staking事件的共识。
REST-Server:提供相关API服务。
实现:Delivery
目前支持与BTTC跨链的根链有 TRON, Ethereum, BSC。BTTC设计的框架支持后续增加其它的公共区块链,仅需要在该公链上部署以下3类合约即可:
BTTC子链上为支持跨链所部署的合约有:
使用 BTTC 跨链桥需要先将 Root Token、Child Token 进行映射。
操作步骤:
deposit 需要根链锁币,withdraw 需要解锁相关资产。
代币映射时,会指定代币类型,每种类型有对应的 Predicate 合约。
锁币:交易发起者 Approve 对应的 Predicate 合约,批准合约Predicate消费代币,将 token 从发起者账户转给 Predicate 地址;
解锁:Predicate 地址给接收者账户转 token。
| Token Type | Predicate |
|---|---|
| ERC20 | ERC20Predicate |
| ERC721 | ERC721Predicate |
| MintableERC20 | MintableERC20Predicate |
| MintableERC721 | MintableERC721Predicate |
前提
进行充提币操作之前,需要先下载插件钱包并连接钱包中的账户地址。
目前BTTC网页支持2种钱包插件,分别为 TronLink与 MetaMask。

状态转移数据格式:
/* 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?
}
Delivery层将BTTC层生产的区块聚合成一棵Merkle树,并定期将Merkle根发布到根链,这种定期发布称为检查点。
Checkpoint很重要:
checkpoint 同步流程
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]
// 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()),
),
})
// 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;
}
调用RootChainManager合约的exit方法来解锁并从ERC20Predicate合约接收代币。这个方法接收一个参数:代币的销毁证明。
调用这个方法之前必须要等待包含销毁交易的checkpoint提交成功。销毁证明由RLP编码生成如下字段:
销毁证明可以自己生成,也可以调用 BTTC SDK 生成
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 的账户 Addr_t 签名发起交易,转 100 WIN 给 BSC 的账户 Addr_b;
| 步骤 | TRON Addr_t | BTTC Addr_b | BTTC 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 |
操作:从 BSC 的账户 Addr_b 转100 WIN给 TRON 的账户 Addr_t;
| 步骤 | BSC Addr_b | BTTC Addr_b | BTTC 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 的账户 Addr_b 转100 WIN给 Ethereum 的账户 Addr_e;
| 步骤 | BSC Addr_b | BTTC Addr_b | BTTC 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 的账户 Addr_e 转100 WIN给 BSC 的账户 Addr_b;
| 步骤 | Ethereum Addr_e | BTTC Addr_e | BTTC 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 |
BTT在各条链上的代币合约:
TRON:
genesis-contracts/bttc-contracts/contracts/child/MRC20.sol
Ethereum & BSC:
使用侧链进行跨链的风险:
每个侧链交易都会收集Precommit投票,只有超过2/3的节点进行了投票,交易结果才有效;
根链同步BTTC的staking情况,能验证针对侧链状态的Precommit投票。
| 侧链 | 中继 | |
|---|---|---|
| 从属关系 | 从属于主链 | 没有 |
| 作用 | 区块链的可扩展性 | 跨链数据的传输 |
| 实现 | 将主链上的资产转移到侧链上来处理 | 从各主链抽象分离出来的一个跨链操作层 |
| 代表 | Polygon,BTTC | Cosmos,Polkadot |
有人把Tendermint当成一个共识,有人把它当成一个通信组件。这都是可以理解的。Tendermint融合了共识和网络通信部分。它类似于一个软件包,通过使用Tendermint可以很容易的开发一个和Cosmos相兼容的区块链(当然,如果使用Cosmos-sdk会更简单,但是会屏蔽更多的细节)。可以把它理解成Cosmos的一个底层架构,提供类似于基础服务的一个平台。Tendermint可以提供一个Cosmos标准的跨链的基础应用。

通过上面这个图可以看出Tendermint在整个Cosmos生态中的位置。Tendermint Core是所有Cosmos生态中区块链的核心(上图中的淡绿色部分),提供了DPOS+BFT的共识机制。Cosmos Hub提供了不同区块链的之间的交互和价值转移。各个区块链应用之间通过IBC接口进行通信。
Tendermint使用的共识算法是拜占庭容错共识协议,它是来源于DLS共识算法。使用这种算法的目的是可以简单方便的解决区块链的分叉机制。这种BFT的机制要求有固定的一组验证人,然后他们会尝试在某个区块上达成共识。每个区块的共识轮流进行,每一轮都有一个提议者来发起区块,之后由验证人来决定是否接受区块或者进入下一轮投票。
Tendermint采用由绝对多数的选票(三分之二)待定的最优拜占庭算法。因此它可以确定的做到:
如果想做恶,必须要有三分之一以上的选票出现问题,并且提交了两个值。
如果任何验证组引起安全问题,就会被发现并对冲突进行投票,同时广播有问题的那些选票。
因为使用了BFT,所以其共识的速度在所有的共识中最相当快速的,很容易达到并维持每秒千笔交易的速度。
Tendermint中的网络底层通信,使用的是一种普通的反应器,它通过参数来查找需要连接的P2P节点,在Tendermint的节点连接中,维护着两组映射来管理连接自己和自己连接的对象,分别称做inbound,outbound.
outbound中,有两种连接,一种是连接时指定的seed,一种是在初始化时检测出来的节点。一般情况下,outbound的数量少于10个。而inbound控制在50个左右的连接。
既然是基于反应器的,那么编程的复杂性就大大降低了。只需要服务监听就可以了。这里不再细节赘述网络通信部分。
网络在启动时,会启动一个协程,定时轮询outbound的数量,来控制连接的稳定性。
Tendermint的设计目的是为了创建一个统一的区块链开发的基础组件。通过将区块链中主要的P2P和共识抽象出来,实现区块链开发过程中的组件式管理。这样做的优势有以下几点:
一个是代码重用。对通用的网络通信和共识就不必再重复的造轮子。
二是解放了区块链编程的语言。比如以太坊用go,c++,但是通过Tendermint的抽象后,可以使用任何语言(觉得和当初JAVA才提出时一次编译的想法有些相似啊)。特别是对于智能合约,这个优点就更显得明显了。
Tendermint共识机制中通过作验证人(Validators)来对区块达成共识,这个在前面已经介绍过,一组验证人负责对每一轮的新区块进行提议和投票。整个共识达成的过程如下图所示。

每一轮的开始(New Round),节点对新一轮的区块进行提议。之后,合格的提议区块首先经过一轮预投票(Prevote)。在提议区块获得2/3以上的投票后,进入下一轮的预认可(Precommit),同样是待获得2/3以上的验证人预认可后,被提议区块就正式获得了认可(Commit)。而得到认可的这个区块就被添加的到区块链中。
下面为详细的过程:

在Tendermint算法中,如果遇到对同一特定区块的同意及否决信息同时超过2/3的情况,需要启用外部的维护机制去核查是否存在超过1/3的验证节点伪造签名或者投出双重选票。
当一个Tx进来时, Tmcore的mempool(MP)会通过mempool connection(一个socket连接,由abci-server提供)调用Application Logic(AL:也就是abci-app,我们自己用任何语言编写的APP逻辑)里的checkTx方法,AL向MP返回验证结果。MP根据验证结果通过或者拒绝该Tx。
Tendermint(TM)把tx暂存在内存池(mempool)里,并把这条Tx通过P2P网络复制给其它TM节点。TM发起了对这条Tx的拜占庭共识投票,所有Tendermint节点都参与了。投票过程分三轮,第一轮预投票(PreVote),超过2/3认可后进入第二轮预提交(PreCommit),超过2/3认可后进入最后一轮正式提交(Commit)
TM提交Tx时依次通过Consensus Connection(一个socket连接,由abci-server提供)向ABCI-APP发送指令BeginBlock-->多次DeliverTx-->EndBlock-->Commit,提交成功后会将StateRoot(application Merkle root hash)返回给TM,TM New出一个区块。
如下图所示的交易流程图:

通过上面的分析可以看到,其实Tendermint的重点在于共识和P2P,将二者抽象出来的有利之处在于,可以让开发者忽略对网络通信和共识的复杂性。直接进行业务层面的开发,而SDK的封装,进一步减少了业务上对非相关的逻辑的考虑,大大减少了开发者生产一条区块链的复杂度,而这也恰恰是Tendermint和cosmos-sdk所想达到的目的。