开发者文档

I. 概述

1. SUN Network 计划

SUN Network 计划是波场主网的扩容计划, 包含智能合约应用侧链(DAppChain), 跨链通讯等一些列扩容项目。其中 DAppChain 为波场的侧链项目,着重为波场主网提供无限扩容能力,同时帮助 DApp 以更低的 Energy 消耗,安全高效地在波场上运行。

2. DAppChain 特性

DAppChain 是 SUN Network 计划的第一个产品。它在支持智能合约交易,兼容主网功能的同时,重点突出低消耗、高安全、强效率的特征,其完整特性如下。

2.1 完全兼容 TRON 主网

侧链使用和主网相同的 DPoS 共识机制, 支持主网的几乎所有功能。TRON 主网用户可以非常方便的切换到侧链上,开发者在侧链上也可以快速的移植或开发新的 DApp。

2.2 侧链高定制化

DAppChain 致力于为所有生态参与者提供一个高度灵活、配置参数丰富、高可定制化的多侧链体系。高可定制化也是 DAppChain 中每条侧链区别于主网的特性之一。

2.3 整个生态更高的 TPS

TRON 主网可以接入多条侧链,每加入一条侧链,意味着 TRON 生态上 TPS 的增加。按照主网 TPS 峰值 2000 计算,多条侧链组成的 TRON 生态的 TPS 可以有 2000 * SideChainNum 的无限扩容能力。

2.4 很低的资源费用

同等情况下的交易,在侧链上的资源费用仅是主网的若干分之一。这可以帮助 DApp 开发者降低开发运营成本,也有助于吸引更多的小开发者团队参与生态建设。

2.5 保障用户资产安全

第一阶段的 DAppChain 采用侧链的 DPoS 共识机制,同时通过主网及侧链的智能合约以及 Oracle 中继,来保证侧链的交易有效和资产安全,以及主侧链链间交互的安全。

2.6 优秀丰富的 API 以及配套的工具集

我们在兼容波场主网接口的同时,提供了更丰富的跨主侧链 API,来降低用户的学习成本,方便 开发者快速接入。我们提供了 Java 和 JavaScript 的开发包,开发者可以基于这些开发包快速和侧链互操作。

II. DAppChain

1. DAppChain 架构及各部分功能

本节解释 DAppChain 的架构。

dappchain.png

如上图所述,DAppChain 的组成分别是:

  • MainChain Gateway 合约,负责主网 token 的映射(Mapping),主网用户的资产转入(Deposit)和资产转出(Withdraw)等。

  • 多 Oracle 中继节点,负责共同完成主网和侧链的链间交互,认证和转发主网的 deposit、mapping 交易到侧链,侧链的 withdraw 交易转发到主网。

  • SideChain Gateway 合约,负责在侧链上, 进出侧链资产的管理。

  • SideChain,基于 DPos 机制,借鉴主网但是做了深度定制化。

2. 侧链

2.1 概要

侧链作为主链扩容计划的核心,每 3 秒产一个块,采用 DPoS 共识机制。和多 oracle 中继节点共同实现侧链交易以及跨主侧链交易的共识。

2.2 共识机制

和主链相同,侧链采用 DPoS 共识,由多个 witness 构成。witness 扮演者侧链验证者的角色,根据票数的多少轮流验证侧链交易并产块,2/3 的 Wintess 确认交易,即对该交易达成共识。

2.3 现有侧链提案

提案号 描述 备注
1,000,000 交易计费开关,当提案设置为 1 时,正常收取交易费 初始为 0, 侧链所有交易消耗的能量和带宽不计费
1,000,001 设置侧链 gateway 合约地址
1,000,003 设置提案过期时间 默认值为 1 天
1,000,004 开启给 Witness 投票 开启后, 侧链支持投票功能
1,000,007 侧链激励池地址, 默认为全零地址 T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb
1,000,008 侧链 witness 激励开关,默认关闭 关闭时, 侧链出块无出块激励
1,000,009 侧链激励池分发系数
1,000,010 侧链收益累积到激励池的比例

侧链特有特性: Fund: 当前侧链激励池。通过激励, 促进社区参与侧链的治理。侧链收益的一部分将进入该激励池,最终实现侧链收益和验证者节点激励的自平衡; FundInject:侧链系统接口,用于向激励池注资。任何人都可以向激励池注资,但只有被共识的地址才可得到侧链的收益分成,侧链收益的剩余部分将进入激励池; mine 函数:precompile 新增函数,用于在侧链上生成从主链 deposit 过来的 TRX,类似 coinbase 交易; mineToken 函数:precompile 新增函数,用于在侧链上生成从主链 deposit 过来的 TRC10 资产,和 mine 类似;

3. 合约

3.1 合约分类

合约由三部分构成:

主链 gateway 合约

侧链 gateway 合约

标准 trc20/trc721 合约

由于侧链上生成的合约是通过系统自动生成的,所以合约中并没有关于abi的描述。因此当需要调用查询类的方法时,需要调用者调用提供的triggerconstantcontract方法以避免生成真正的交易造成扣费。

3.2 主链 gateway 合约与侧链 gateway 合约

3.2.1 trc20/trc721 合约映射操作:
//mappingTRC20 为例
//主链 gateway 合约方法
function mappingTRC20(bytes txId) public onlyNotStop onlyNotPause goDelegateCall payable returns (uint256) {
require(msg.value >= mappingFee, "trc20MappingFee not enough");
if (msg.value > 0) {
bonus += msg.value;
}
address trc20Address = calcContractAddress(txId, msg.sender);
require(trc20Address != sunTokenAddress, "mainChainAddress == sunTokenAddress");
require(mainToSideContractMap[trc20Address] != 1, "trc20Address mapped");
uint256 size;
assembly {size := extcodesize(trc20Address)}
require(size > 0);
userMappingList.push(MappingMsg(trc20Address, DataModel.TokenKind.TRC20, DataModel.Status.SUCCESS));
mainToSideContractMap[trc20Address] = 1;
emit TRC20Mapping(trc20Address, userMappingList.length - 1);
return userMappingList.length - 1;
}

//侧链 gateway 合约方法
function deployDAppTRC20AndMapping(address mainChainAddress, string name, string symbol, uint8 decimals) internal returns (address r) {
address sideChainAddress = new DAppTRC20(address(this), name, symbol, decimals);
mainToSideContractMap[mainChainAddress] = sideChainAddress;
sideToMainContractMap[sideChainAddress] = mainChainAddress;
emit DeployDAppTRC20AndMapping(mainChainAddress, sideChainAddress);
r = sideChainAddress;
}

在主链上,由主链 trc20/trc721 合约的部署者,将部署该合约时的交易 id,传入合约,合约验证该交易 id 是否真实部署合约。在侧链上,接收由多个 Oracle 确认的主网合约映射操作,为主链对应的 trc20/trc721 合约,在侧链部署相应的标准 trc20/trc721 合约。

3.2.2 资产转入操作:
//depositTRX 为例
//主链 gateway 合约方法
function depositTRX() payable public onlyNotStop onlyNotPause goDelegateCall returns (uint256) {
require(msg.value > 0, "value must be > 0");
require(msg.value >= depositMinTrx, "value must be >= depositMinTrx");
require(msg.value <= uint64Max, "msg.value must <= uint64Max");
userDepositList.push(DepositMsg(msg.sender, uint64(msg.value), 0, address(0), 0, 0, 0));
emit TRXReceived(msg.sender, uint64(msg.value), userDepositList.length - 1);
return userDepositList.length - 1;
}

//侧链 gateway 合约方法
function depositTRX(address to, uint256 value) internal {
mintTRXContract.call(value);
to.transfer(value);
emit DepositTRX(to, value);
}

在主链上,调用合约接收 TRX 和 TRC10 或者已经由开发者进行映射过的 TRC20 与 TRC721 资产,用户将想要转入的主链上的资产冻结在主链 gateway 合约里。在侧链上,与 trc20/trc721 合约映射操作类似,接收由多个 Oracle 确认的主网合约映射操作,侧链 gateway 合约会将对应的资产发给用户对应的侧链账号上。

3.2.3 资产转出操作:
//withdrawTRX 为例
//侧链 gateway 合约方法
function withdrawTRX() payable public onlyNotPause onlyNotStop goDelegateCall returns (uint256 r) {
require(msg.value >= withdrawMinTrx + withdrawFee, "value must be >= withdrawMinTrx+withdrawFee");
if (msg.value > 0) {
bonus += withdrawFee;
}
uint256 withdrawValue = msg.value - withdrawFee;
require(withdrawValue > 0, "withdrawValue must be > 0");
userWithdrawList.push(WithdrawMsg(msg.sender, address(0), 0, withdrawValue, DataModel.TokenKind.TRX, DataModel.Status.SUCCESS));
// burn
address(0).transfer(withdrawValue);
emit WithdrawTRX(msg.sender, withdrawValue, userWithdrawList.length - 1);
r = userWithdrawList.length - 1;
}

//主链 gateway 合约方法
function withdrawTRX(address \_to, uint256 value, uint256 nonce, bytes[] oracleSigns)
public onlyNotStop onlyOracle goDelegateCall {
require(oracleSigns.length <= numOracles, "withdraw TRX signs num > oracles num");
bytes32 dataHash = keccak256(abi.encodePacked(\_to, value, nonce));
bool needWithdraw = checkOracles(dataHash, nonce, oracleSigns);
if (needWithdraw) {
\_to.transfer(value);
// ensure it's not reentrant
emit TRXWithdraw(\_to, value, nonce);
}
}

资产转出操作与合约映射操作和资产转入操作不同的是资产转出操作首先发生在在侧链上,与资产转入操作类似,由用户调用合约接收 TRX 和 TRC10 或者已经由开发者进行映射过的 TRC20 与 TRC721 资产,用户将想要转出的侧链上的资产通过侧链 gateway 合约销毁。

3.3 侧链标准

trc20/trc721 合约,仅实现官方标准 trc20/trc721 基本接口,增加只能由侧链 gateway 合约地址调用的在转入资产用到的增发功能资产的方法,和在转出时将资产转至 gateway 合约的方法。

//标准 TRC20 中增加方法
function mint(address to, uint256 value) external onlyGateway {
require(to != address(0));

​ \_totalSupply = \_totalSupply.add(value);
​ \_balances[to] = \_balances[to].add(value);
​ emit Transfer(address(0), to, value);
​ }

​ function withdrawal(uint256 value) payable external returns (uint256 r) {
​ transfer(gateway, value);
​ r = ITRC20Receiver(gateway).onTRC20Received.value(msg.value)(msg.sender, value);
​ }
//标准 TRC721 中增加方法
function mint(address to, uint256 tokenId) external onlyGateway {
​ require(to != address(0));
​ require(!\_exists(tokenId));

​ \_tokenOwner[tokenId] = to;
​ \_ownedTokensCount[to] = \_ownedTokensCount[to].add(1);

​ emit Transfer(address(0), to, tokenId);
​ }

​ function withdrawal(uint256 tokenId) payable external returns (uint256 r) {
​ transfer(gateway, tokenId);
​ r = ITRC721Receiver(gateway).onTRC721Received.value(msg.value)(msg.sender, tokenId);
​ }

4. 主侧链交互所涉及详细步骤

4.1 概述

为了实现主链与侧链之间的交互通信, DAppchain 实现了三个模块:主链的网关合约、Oracle 服务、侧链的网关合约。

其中 Oracle 通过 Kafka 监听来自主链网关合约、侧链网关合约的消息,实现主侧链之间的交互通信。只有当主链与侧链之间的交互被超过 2/3 的 Oracle 共识,才能够被认为有效的交易。

主侧链之间交互动作主要分为三类:TRC20/TRC721 合约映射、转入功能、转出功能。

crosschain

4.2 TRC20/TRC721 合约映射(Mapping)

当用户使用 TRC20/TRC721 合约时,通过在主链触发 TRC20/TRC721 合约映射,将在主链部署的 TRC20/TRC721 合约映射到侧链的对应的合约,即用户无需在侧链手动部署 TRC20/TRC721 合约。

mapping.png

具体流程为:

  1. Deployer 先在主链部署 TRC20/TRC721 合约
  2. 资产所有者调用 gateway 中的部署映射合约方法去创建相应的 TRC20/TRC721 合约,Gateway 合约验证映射合法性。如果验证通过,将会产生 Deploy 事件
  3. oracle 监听侧链 Deploy 事件
  4. oracle 调用侧链 Gateway 合约在侧链创建基础功能的 TRC20/TRC721 合约,并将主链与侧链的合约进行映射。

4.3 转入功能(Deposit)

当用户需要将主链上的资产转移到侧链时,需要调用主链网关合约的转入功能。

deposit.png

具体流程为:

  1. 如果使用 TRC20/TRC721 代币,需要调用 TRC20/TRC721 合约 approve 方法,允许 gateway 转移自己资产(使用 TRX 无需此步)。
  2. 调用主链网关合约的 deposit 方法
  3. Oracle 监听 Deposit 事件
  4. Oracle 调用侧链网关合约进行资产转移操作
  5. 如果使用 TRC20/TRC721 代币,需要在侧链上 mint 相应数量的代币;如果使用 TRX 直接增加账户余额

4.4 转出功能(Withdraw)

当用户需要将侧链上的资产转移到主链时,需要调用侧链网关合约的转出功能。

withdraw

具体流程为:

  1. 如果使用 TRC20/TRC721 合约,调用合约的 withdraw 方法,合约会再去调用网关合约。如果使用 TRX,直接调用侧链网关合约进行转出操作。
  2. Oracle 监听转出事件
  3. 调用主链网关合约的转出方法
  4. 如果使用 TRC20/TRC721 合约,则网关合约会再调用合约方法;如果使用 TRX,直接调整账户余额

5. 激励

1)在一个维护期内,出块奖励相同

2)不同维护期,出块奖励会发生变化,计算公式为:

payPerBlock = fund / ((86400 / 3 ) * dayToSustainByFund)

其中,payPerBlock: 每个块出块奖励; fund: 当前 fund 值; dayToSustainByFund: 基金持续天数

3)出块奖励会分为两部分,按照 percentToPayWitness 比例分配给 witness,剩余分配给 founder,计算公式如下:

payForWitnessPerBlock = payPerBlock * percentToPayWitness / 100

payForFounderPerBlock = payPerBlock - payForWitnessPerBlock

其中,payForWitnessPerBlock: 每个块给 witness 的出块奖励; payForFounderPerBlock: 每个块给 founder 的出块奖励

III. 如何连接并使用 DAppChain

1. DAppChain 正式网节点列表

Full Nodes

Http 接口

  • sun.tronex.io/wallet (支持http跨域)
  • 47.90.245.159:8090
  • 47.90.211.50:8090
  • 47.252.6.19:8090
  • 47.89.185.14:8090

RPC 接口

  • 47.90.245.159:50051
  • 47.90.211.50:50051
  • 47.252.6.19:50051
  • 47.89.185.14:50051
Solidity Nodes

Http 接口

  • sun.tronex.io/walletsolidity (支持http跨域)
  • 47.90.245.159:8091
  • 47.90.211.50:8091
  • 47.252.6.19:8091
  • 47.89.185.14:8091

RPC 接口

  • 47.90.245.159:50061
  • 47.90.211.50:50061
  • 47.252.6.19:50061
  • 47.89.185.14:50061

Event Server

side chain

  • sun.tronex.io/event

DAppChain正式网gateway合约相关信息

SideChainID

  • 41E209E4DE650F0150788E8EC5CAFA240A23EB8EB7

TRON Network主网gateway合约地址

  • TL9q7aDAHYbW5KdPCwk8oJR3bCDhRwegFf

SUN Network DAppChain侧链 gateway合约地址

  • TGKotco6YoULzbYisTBuP6DWXDjEgJSpYz

2. DAppChain 测试网信息汇总

测试网节点列表

Full Nodes

Http 接口

  • suntest.tronex.io/wallet (支持http跨域)
  • 47.252.85.90:8090
  • 47.252.80.185:8090
  • 47.252.84.141:8090

RPC 接口

  • 47.252.85.90:50051
  • 47.252.80.185:50051
  • 47.252.84.141:50051
Solidity Nodes

Http 接口

  • suntest.tronex.io/walletsolidity (支持http跨域)
  • 47.252.85.90:8091
  • 47.252.80.185:8091
  • 47.252.84.141:8091

RPC 接口

  • 47.252.85.90:50060
  • 47.252.80.185:50060
  • 47.252.84.141:50060

Event Server

main chain

  • 47.252.81.14:8070(支持http跨域)

side chain

  • suntest.tronex.io/event (支持http跨域)

测试网gateway合约相关信息

SideChainID

  • 413AF23F37DA0D48234FDD43D89931E98E1144481B

主链合约

  • TFLtPoEtVJBMcj6kZPrQrwEdM3W3shxsBU

侧链合约

  • TRDepx5KoQ8oNbFVZ5sogwUxtdYmATDRgX

3. 测试币申请

4. 链接方式

用户可以使用多种方式链接到 DAppChain

  1. 通过 sun-scan 官网 (将要支持, 包括 tronlink)
  2. 通过 sun-client (见开发者文档)
  3. 通过 SDK (见开发者文档)

IV. 快速入门

如果您想在侧链上学习如何开发 TRON 智能合约以及 DApp,请参考下文的 JAVA SDK 以及 JS SDK 文档。

如果您是第一次接触 TRON 智能合约的开发,请您移步到我们的 github demo,参考我们的代码进行开发。

V. JAVA SDK

DAppChain 提供了 java 版本的 sdk 共开发者使用,包含了链上,链间多种功能的封装。

SDK 的初始化

使用 SDK 需要先初始化一个 SDK 对象。并实现 IServerConfig 接口传入初始化参数。如果需要多重签名功能,则还需要实现 IMultiTransactionSign 这个接口。

Sdk = new SunNetwork();
SunNetworkResponse<Integer> ret = sdk.init(new ServerConfigImpl(), new MultiSignTransactionImpl());

JAVA SDK 中包含三个 Service。

//Main-chain interface
sdk.getMainChainService();
//Side-chain interface
sdk.getSideChainService();
//Cross-chain interaction interface
sdk.getCrossChainService();

链间交互接口介绍

合约映射(Mapping)

  1. TRC20 映射
// Called by the deployer of the TRC20 contract on the main-chain to complete the mapping of the TRC20 contract from the main-chain to the side-chain, the standard 20 contract deployed in the side-chain corresponds to the main-chain TRC20 contract.
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().mappingTrc20(trxHash, mappingFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this mapping operation.
Parameter Description
trxHash deployContract transaction for deploying TRC20 contracts on the main-chain id
mappingFee Mapping Fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC721 映射
// Called by the deployer of the TRC721 contract on the main-chain to complete the mapping of the TRC721 contract from the main-chain to the side-chain, the standard TRC721 contract will be deployed in the side-chain corresponding to the main-chain TRC721 contract.
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().mappingTrc721(trxHash, mappingFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this mapping operation.
Parameter Description
trxHash deployContract transaction id for TRC721 contract on the main-chain
mappingFee Mapping Fee
feeLimit Maximum energy consumption when triggering a contract

资产转入(Deposit)

  1. TRX 资产转入
//Pledge a certain number of TRX from the main-chain to the side-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().depositTrx(num, depositFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this deposit operation.
Parameter Description
num TRX Quantity (Unit SUN)
depositFee Deposit fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC10 资产转入
//Pledge a certain number of designated TRC10 from the main-chain to the side-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().depositTrc10(tokenId, tokenValue, depositFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this deposit operation.
Parameter Description
tokenId Token ID of TRC10
tokenValue TRC10 Quantity of Assets
depositFee Deposit fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC20 资产转入
//Pledge a certain number of designated TRC20 from the main-chain to the side-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().depositTrc20(contractAddrStr, num, depositFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this deposit operation.
Parameter Description
contractAddrStr Main-chain TRC20 Contract Address
num TRC20 Asset Quantity
depositFee Deposit fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC721 资产转入
//Pledge a certain number of designated TRC721 from the main-chain to the side-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().depositTrc721(contractAddrStr, num, depositFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this deposit operation.
Parameter Description
ContractAddrStr Main-chain TRC721 Contract Address
num TRC721 Asset Quantity
depositFee Deposit fee
feeLimit Maximum energy consumption when triggering a contract

资产转出(Withdraw)

  1. TRX 资产转出
//Exit a certain number of TRX from the side-chain to the main-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().withdrawTrx(num, withdrawFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this withdraw operation.
Parameter Description
num TRX Quantity (Unit SUN)
withdrawFee Withdraw fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC10 资产转出
//Pledge a certain number of designated TRC10 from the side-chain to the main-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().withdrawTrc10(tokenId, tokenValue, withdrawFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this withdraw operation.
Parameter Description
tokenId Token ID of TRC10
tokenValue TRC10 Quantity of Assets
withdrawFee Withdraw fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC20 资产转出
//Pledge a certain number of designated TRC20 from the side-chain to the main-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().withdrawTrc20(contractAddrStr, num, withdrawFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this withdraw operation.
Parameter Description
contractAddrStr Sidechain TRC20 Contract Address
num TRC20 Asset Quantity
withdrawFee Withdraw fee
feeLimit Maximum energy consumption when triggering a contract
  1. TRC721 资产转出
//Pledge a certain number of designated TRC721 from the side-chain to the main-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().withdrawTrc721(contractAddrStr, num, withdrawFee, feeLimit);
//Return value: Use sdk.getSideChainService().getTransactionInfoById(txid) to query resp.getData().getTrxId() to get the nonce value of this withdraw operation.
Parameter Description
contractAddrStr Sidechain TRC721 Contract Address
num TRC721 Asset Quantity
withdrawFee Withdraw fee
feeLimit Maximum energy consumption when triggering a contract

重试(Retry)

  1. 资产转入重试
//Retry the unsuccessful main-chain deposit operation
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().retryDeposit(nonce, retryFee, feeLimit);
Parameter Description
nonce Deposit operation nonce value
retryFee Retry fee
feeLimit Maximum energy consumption when triggering a contract
  1. 资产转出重试
//Retry the unsuccessful side-chain withdraw operation
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().retryWithdraw(nonce, retryFee, feeLimit);
Parameter Description
nonce Withdraw operation nonce value
retryFee Retry fee
feeLimit Maximum energy consumption when triggering a contract
  1. 资产映射重试
//Retry the unsuccessful main-chain mapping operation
SunNetworkResponse<TransactionResponse> resp = sdk.getCrossChainService().retryMapping(nonce, retryFee, feeLimit);
Parameter Description
nonce Mapping operation's nonce value
retryFee Retry fee
feeLimit Maximum energy consumption when triggering a contract

侧链接口介绍

  1. 激励池注入
//Investors from the side-chain will inject funds into the side-chain fund pool
SunNetworkResponse<TransactionResponse> resp = sdk.getMainChainService().fundInject(amount);
Parameter Description
amount Quantity of funds injected into the side-chain fund pool (unit SUN)
  1. 侧链提案
//Query side-chain all proposal list information
SunNetworkResponse<TransactionResponse> resp = sdk.getSideChainService().listProposals();
//Parameter: None

//Query side-chain proposal information according to the proposal number
SunNetworkResponse<TransactionResponse> resp = getSideChainService().getProposal(id);
Parameter Description
id Proposal number
  1. 侧链参数
//Query all the parameters of the side-chain blockchain committee can be set
SunNetworkResponse<TransactionResponse> resp = getSideChainService().getSideChainParameters();

主链接口介绍

  1. 主链提案
//Query all the proposal list information of the main-chain
SunNetworkResponse<TransactionResponse> resp = sdk.getMainChainService().listProposals();
//Query side-chain proposal information according to the proposal number
SunNetworkResponse<TransactionResponse> resp = getMainChainService().getProposal(id);
Parameter Description
id Proposal number
  1. 主链参数
//Query all the parameters of the main-chain blockchain committee can be set
SunNetworkResponse<TransactionResponse> resp = getMainChainService().getChainParameters();

公用部分接口介绍

  1. 获得当前用户地址
//Get the address of the current user of sdk
SunNetworkResponse<byte[]> resp = getChainService().getAddress()
  1. 获得当前用户 TRX 账户余额
//Get the current user's TRX sdk
SunNetworkResponse<long> resp = getChainService().getBalance()
  1. 获得当前用户账户状态
//Get account information based on the address
SunNetworkResponse<Account> result = getChainService().getAccount(address);
  1. 链上 TRX 资产转移
//Transfer the TRX operation
SunNetworkResponse<TransactionResponse> = getChainService().sendCoin(toAddress, amount);
  1. 链上 TRC10 资产转移
//Transfer the TRC10 operation
SunNetworkResponse<TransactionResponse> = getChainService().transferAsset(toAddress, assertName, amount);

VI. SunWeb

SunWeb 是为 Tron SUN Network 开发的一款 js-sdk 工具,并且继承自 TronWeb。 SunWeb 里面封装了 main-chain 和 side-chain 两个对象,他们本质上就是 TronWeb 的对象实例,因此里面包含了 TronWeb 实例的所有属性和方法。例如用户可以使用 sunweb.mainchain.trx.getBalance() 来获取主网上的 balance。除此之外,SunWeb 增加了一些新的方法来支持主链和侧链的交互,如 deposit, withdraw, mapping, approve, injectFund 等操作,可参考源码。SunWeb 详细使用方法如下。

SunWeb 类

创建 SubWeb 实例

为了在应用中可以使用 SunWeb,你需要像下面这样创建一个 SunWeb 实例。

const sunWeb = new SunWeb(
  mainchain,
  sidechain,
  mainGatewayAddress,
  sideGatewayAddress,
  sideChainId);

其中 mainchain 和 sidechain 分别是主网和侧链的 TronWeb 实例。 TronWeb 实例化参考链接

如果需要连接 SUN Network 测试网,可以创建如下的 SunWeb 实例

const mainchain = new TronWeb( {
    fullNode: 'http://47.252.84.158:8090',
    solidityNode: 'http://47.252.84.158:8090',
    eventServer: 'http://47.252.84.141:8080',
    privateKey
});
const sidechain = new TronWeb({
    fullNode: 'http://47.252.85.90:8090',
    solidityNode: 'http://47.252.85.90:8091',
    eventServer: 'http://47.252.85.90:8090',
    privateKey
})
const sunWeb = new SunWeb(
  mainchain,
  sidechain,
  'TGHxhFu4jV4XqMGmk3tEQdSeihWVHE9kBP',
  'TBHr5KpbA7oACUysTKxHiAD7c6X6nkZii1',
  '41455CB714D762DC46D490EAB37BBA67B0BA910A59'
);

转入资产

资产转入的作用是将主链资产转入到侧链。

depositTrx

转入 TRX
// Format
sunWeb.depositTrx(callValue, depositFee, feeLimit, options);

// example
sunWeb.depositTrx(100000000, 10000, 1000000);
Arguments
Parameter Description Type Options
callValue Amount of TRX (Units in SUN) to deposit Integer (Units in SUN) Required
depositFee Deposit fee Integer (Units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

depositTrc10

转入 TRC10
// format
sunWeb.depositTrc10(tokenId, tokenValue, depositFee, feeLimit, options);

// example
sunWeb.depositTrc10(100059, 10000000, 10000, 100000);
Arguments
Parameter Description Type Options
tokenId Token Id of trc10 Integer Required
tokenValue Amount of trc10 token (Units in SUN) to deposit Integer (Units in SUN) Required
depositFee Deposit fee Integer (Units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

depositTrc20

转入 TRC20

在转入 TRC20 之前,必须先 mapping TRC20 合约到侧链,即调用 sunWeb.mappingTrc20(…) 函数。Mapping 合约后,再 approve TRC20, 即调用 sunWeb.approveTrc20(…) 函数。这两步都成功后,才能成功完成 depositTrc20 操作。

// format
sunWeb.depositTrc10(num, depositFee, feeLimit, contractAddress, options);

// example
sunWeb.depositTrc10(1000000, 10000, 1000000, 'TD9Jrm546pGkzRu7K5nitMxk8nn75wXNkQ');
Arguments
Parameter Description Type Options
num Amount of TRC20 (Units in SUN) to deposit Integer Required
depositFee Deposit fee Integer (Units in SUN) Required
feeLimit Cost limit Integer, long Required
contractAddress Main-chain TRC20 Contract Address String Required
options The permissions Id Object Optional

depositTrc721

转入 TRC721

与转入 TRC20 类似,先需要 mappingTrc721 和 approveTrc721。

// format
sunWeb.depositTrc721(id, depositFee, feeLimit, contractAddress, options);

// example
sunWeb.depositTrc10(1000000, 10000, 1000000, 'TCLRqK6aP2xsCZWhE2smkYzdRHf9uvyz5P');
Arguments
Parameter Description Type Options
id Id of TRC721 to deposit Integer Required
depositFee Deposit fee Integer (Units in SUN) Required
feeLimit cost limit Integer, long Required
contractAddress Main-chain TRC721 Contract Address String Required
options The permissions Id Object Optional

资产授权

在转入 TRC20 和 TRC721 之前,需要先调用 approveTrc20 和 approveTrc721 获得相应资产授权。

approveTrc20

授权 TRC20
// format
sunWeb.approveTrc20(num, feeLimit, contractAddress, options);

// example
sunWeb.approveTrc20(10000, 10000000, 'TGKuXDnvdHv9RNE6BPXUtNLK2FrVMBDAuA');
Arguments
Parameter Description Type Options
num Num of TRC20 Integer Required
contractAddress Main-chain TRC20 Contract Address String Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

approveTrc721

授权 TRC721
// format
sunWeb.approveTrc721(id, feeLimit, contractAddress, options);

// example
sunWeb.approveTrc721(100, 10000000, 'TUxDmFbEceGgjWCb6rLVcrFgnsWwofPdPq');
Arguments
Parameter Description Type Options
id Id of TRC721 Integer Required
contractAddress Main-chain TRC721 Contract Address String Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

资产映射

用户必须先将主链合约资产 TRC20/TRC721 映射到侧链以后,才能将合约资产转入到侧链。

mappingTrc20

映射 TRC20
// format
mappingTrc20(trxHash, mappingFee, feeLimit, options);

// example
mappingTrc20('548442d9080605a60adf1d30cc126a2b9c6308cbe9ec224f8c67a6c2590fa299', 100000, 10000, options);
Arguments
Parameter Description Type Options
trxHash The hash value of the transaction for the main-chain deployment TRC20 contract Hex string Required
mappingFee Mapping Fee Integer(Units in SUN) Required
feeLimit cost limit Integer, long Required
options The permissions Id Object Optional

mappingTrc721

映射 TRC721
// format
mappingTrc721(trxHash, mappingFee, feeLimit, options);

// example
mappingTrc721('548442d9080605a60adf1d30cc126a2b9c6308cbe9ec224f8c67a6c2590fa299', 100000, 1000, options);
Arguments
Parameter Description Type Options
trxHash The hash value of the transaction for the main-chain deployment TRC721 contract Hex string Required
mappingFee Mapping Fee Integer(units in SUN) Required
feeLimit cost limit Integer, long Required
options The permissions Id Object Optional

转出资产

用户可将资产从侧链转出回主链,转出资产操作由 SunWeb 向侧链发送命令。

withdrawTrx

转出 TRX
// Format
sunWeb.withdrawTrx(callValue, withdrawFee, feeLimit, options);

// example
sunWeb.withdrawTrx(100000000, 10000, 1000000);
Arguments
Parameter Description Type Options
callValue Amount of TRX (Units in SUN) to deposit Integer (Units in SUN) Required
withdrawFee Withdraw Fee Integer(Units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

withdrawTrc10

转出 TRC10
// format
sunWeb.withdrawTrc10(tokenId, tokenValue, withdrawFee, feeLimit, options);

// example
sunWeb.withdrawTrc10(100059, 10000000, 10000, 100000);
Arguments
Parameter Description Type Options
tokenId Token Id of TRC10 Integer Required
tokenValue Amount of TRC10 token (Units in SUN) to deposit Integer (Units in SUN) Required
withdrawFee Withdraw Fee Integer(Units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

withdrawTrc20

转出 TRC20
// format
sunWeb.withdrawTrc20(num, withdrawFee, feeLimit, contractAddress, options);

// example
sunWeb.withdrawTrc20(10000, 10000, 10000000, 'TWzXQmDoASGodMss7uPD6vUgLHnkQFX7ok');
Arguments
Parameter Description Type Options
Num Num of TRC20 Integer Required
withdrawFee Withdraw Fee Integer(units in SUN) Required
feeLimit Cost limit Integer, long Required
contractAddress Side-chain TRC20 Contract Address after mapping Integer Required
options The permissions Id Object Optional

withdrawTrc721

转出 TRC721
// format
sunWeb.withdrawTrc721(id, withdrawFee, feeLimit, contractAddress, options);

// example
sunWeb.withdrawTrc721(101, 1000, 10000000, 'TA2xrVESq2UcEtDtgPzxNJEiLgxmMVdtFR');
Arguments
Parameter Description Type Options
id Id of TRC721 Integer Required
withdrawFee Withdraw Fee Integer(units in SUN) Required
feeLimit Cost limit Integer, long Required
contractAddress Side-chain TRC20 Contract Address after mapping Integer Required
options The permissions Id Object Optional

注资

注资的主要作用是为侧链的基金池注入资金。

injectFund

// format
sunWeb.injectFund(num, feeLimit, options);

// example
sunWeb.injectFund(1000, 10000000);

Arguments

Parameter Description Type Options
num num of injecting Integer Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

重试

retryDeposit

// format
sunWeb.retryDeposit(nonce, retryDepositFee, feeLimit, options);

// example
sunWeb.retryDeposit(1000, 10000000);

Arguments

Parameter Description Type Options
nonce Nonce value of asset deposit Integer Required
retryDepositFee Fee of retry deposit operation Integer(units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

retryMapping

// format
sunWeb.retryMapping(nonce, retryMappingFee, feeLimit, options);

// example
sunWeb.retryMapping(1000, 10000, 10000000);

Arguments

Parameter Description Type Options
nonce Nonce value of asset deposit Integer Required
retryMappingFee Fee of retry mapping operation Integer(units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

retryWithdraw

// format
sunWeb.retryWithdraw(nonce, retryWithdrawFee, feeLimit, options);

// example
sunWeb.retryWithdraw(1000, 10000, 10000000);

Arguments

Parameter Description Type Options
nonce Nonce value of asset deposit Integer Required
retryWithdrawFee Fee of retry withdraw operation Integer(units in SUN) Required
feeLimit Cost limit Integer, long Required
options The permissions Id Object Optional

签名

SUN Network 的签名有一些改变,主链的签名逻辑和 TronWeb 的保持一致,侧链的签名逻辑有更改。因此,如果需要和 TronLink 一样弹出签名框,需要分别覆盖 sunWeb.mainchain.trx.sign()和 sunWeb.sidechain.trx.sign().

// format
sign((transaction = false), (privateKey = this.sidechain.defaultPrivateKey), (useTronHeader = true), (multisig = false));

VII. 如何成为超级代表

SUN Network非常欢迎社区加入到DAppChain的建设中来。由于侧链激励机制和TRON主网有所不同,SUN Network会分阶段来支持社区超级代表的当选。 侧链的超级代表激励机制使用了激励池的概念,所有的侧链本身的收益都会进入激励池,按一定比例分发给当选的超级代表。

由于在初始阶段参与侧链的用户较少,奖励将会被累积到激励池,超级代表并不会获得出块奖励。 当生态达到一定的规模时,我们会开启允许社区超级代表当选的提议。这样可以保证社区超级节点可以获得稳定的可观奖励,并且同时兼顾去中心化的理念。 超级代表的奖励是浮动的,理论上生态越大超级节点得到的收益就会越高,这也会进一步鼓励超级代表参与侧链的建设。

VIII. 如何在DAppChain部署自己的DApp

DApp的开发者可以将自己在TRON Network上的DApp移植到DAppChain上以扩大生态建设。同时也允许仅在DAppChain上从零开始开发应用。在DAppChain上应用可获得的免费带宽和能量资源将会更多,能量燃烧的价格也会变低从而帮助开发者减少成本。

DAppChain支持的DApp部署类型

根据开发者具体的商业需求,DApp可以被分为以下类型:

Type A 仅在DAppChain上被支持的DApp

Type B TRON Network及DAppChain上均支持的DApp

仅在DAppChain上被支持的DApp

在DAppChain上开发应用的流程和在TRON Network上非常的类似。但需要注意几个关键的事实:

  1. DAppChain和TRON Network并不共享相同的资源系统,所以请向DAppChain转入一定数量的TRX来支付常规的部署合约,调用合约的操作。

  2. 开发者可以使用TRONSCAN, TRONLINK, sun-cli或者sdk(java/nodejs)执行TRX的转入。

  3. DApp开发者可以在TRON Network上发行资产,并将其注册到gateway合约中,这样可以在DAppChain上生成一个相对应的合约。在这种情况下,合约资产可以在两个网络中正常的被转移。我们也允许用开发者直接在DAppChain上发行TRC20/TRC721资产,但是请注意这些资产无法从DAppChain中被转出回到TRON Network,原因在于这个通证并非是在TRON Network中被创建的。

  4. 被创建的资产合约为官方提供的标准TRC20/TRC721资产合约,仅仅提供了标准的TRC20/TRC721接口,这就意味着用户无法在生成的合约中使用开发者自定义的方法。例如,即使在TRON Network上发行的资产合约中定义了铸币方法,在DAppChain上的对应生成的合约中由于开发者自定义的方法并不会被复制,用户将无法调用铸币函数。

  5. 交易签名过程和TRON Network不同,如果想做自己的实现,请参见sunweb的代码。

  6. 在DApp中,开发者可能需要实现链间的资产转移。但这并不是强制需要实现的逻辑。请参考下面的部分。

对于Type B DApp的开发建议

基于DAppChain部署一份DApp代码

关于如何将DApp的逻辑从TRON Network移植到DAppChain,可以参见Type A DApp的逻辑,移植和从零开始的部署有很多的相似之处。最大的不同在于开发者需要部署两份几乎相同的代码在两个分离的网络中而不是仅仅关心一个网络。

更多的是,开发者需要统一的将DAppChain和TRON Network看做一个整体。开发者需要根据自己的应用逻辑考虑类似将资产从整体的生态的一部分转移到另一部分的问题。

DApp中的链间资产转移

资产转入/转出:

用户可以选择第三方工具或者官方提供的工具将资产转入或者转出DAppChain, 因此对于DApp而言,提供链间资产转移方法并非强制。

工具在这里可以是TRONSCAN, TRONLINK或者sun-cli等等。然而,我们建议开发者的DApp支持链间资产转移,尤其是就Type B DApp而言,对于用户十分友好。

我们提供了多种方法支持开发者将链间资产转移逻辑嵌入开发的DApp, 包括:

java jdk, sun-sdk

js库, sunweb

资产映射

如果DApp在TRON Network发行过自己的TRC20/TRC721资产,并且需要将这些合约资产参与到DApp的逻辑中,需要使用映射操作将资产合约映射到DAppChain上产生一个相对应的资产合约。

资产映射操作可以通过TRONSCAN, sun-cli手动完成。同时,也可以通过sun-sdk以及sunweb达成目标。此操作对于一类TRC20/TRC721资产必须且仅需要被执行一次。

然而,仅有资产合约的部署者可以触发映射合约函数。如果开发者并非需要使用的TRC20/TRC721合约部署者,需要在使用前确认目标资产合约是否已经被映射。

工具

sunweb和tronweb基本等价,而sunweb提供了额外的SUN Network 和 TRON Network的链间交互功能。suweb同时也是官方推荐的移植工具。

IX. 如何部署自己的侧链

开始部署

1. 部署主链gateway合约,生成相应账户,并配置主链fullnode

  • 1.生成一个账号 Owner 并且给予充足余额, 作为主网gateway合约的部署者以及侧链的初始拥有者。
  • 2.在主链上生成多个账号 O1-On 作为创世Oracle群组
  • 3.使用wallet-cli,Owner 在主链部署主链gateway合约,获得合约地址 C1
    • wallet-cli命令: deploycontract ...
  • 4.通过C1生成侧链id
  • 5.对多个oracle地址,使用Owner账户调用主链gateway合约的addOracle(address)方法一个一个的添加oracle
    • wallet-cli命令: triggercontract $main_gateway addOracle(address) $new_oracle false 1000000000 0 0 #
  • 6.在主链激活每个oracle,并且保证每个oracle余额充足。
    • wallet-cli命令: sendcoin $oracle_address value
  • 7.启动主链的fullnode,配置kafka,连接TRON主链 * 下载event-plugin 见 https://github.com/tronprotocol/event-plugin
    • 配置kafka命令见 https://github.com/tronprotocol/event-plugin
    • 使用event.subscribe相关的配置启动fullnode:

配置文件:

event.subscribe = {
    path = "zip absolute path" // absolute path of plugin
    server = "kafka ip:kafka port" // target server address to receive event triggers
    dbconfig="" // dbname|username|password
    topics = [
        {
          triggerName = "block" // block trigger, the value can't be modified
          enable = false
          topic = "block" // plugin topic, the value could be modified
        },
        {
          triggerName = "transaction"
          enable = false
          topic = "transaction"
        },
        {
          triggerName = "contractevent"
          enable = true
          topic = "contractevent"
        },
        {
          triggerName = "contractlog"
          enable = true
          topic = "contractlog"
        }
    ]
 
    filter = {
       fromblock = "" // the value could be "", "earliest" or a specified block number as the beginning of the queried range
       toblock = "" // the value could be "", "latest" or a specified block number as end of the queried range
       contractAddress = [
           "" // contract address you want to subscribe, if it's set to "", you will receive contract logs/events with any contract address.
       ]
 
       contractTopic = [
           "" // contract topic you want to subscribe, if it's set to "", you will receive contract logs/events with any contract topic.
       ]
    }
}

2. Sun-cli配置

  • 1.配置文件中写上主链、侧链node,主链gateway地址

初始配置文件:

mainchain {
  net {
    type = mainnet
  }

  fullnode = {
    ip.list = [
      ""
    ]
  }

  RPC_version = 2

  gateway_address = ""
}

sidechain {
  net {
    type = mainnet
  }

  fullnode = {
    ip.list = [
    ]
  }


  RPC_version = 2
  gateway_address = ""

  sideChainId = ""
}
  • 注意mainchain.gateway_address写上主链地址,例如:

    • gateway_address = "TAcLUguLig3n6zCC5BQQxwSJbFwJseAxQB"
  • 2.启动 Sun-cli

3. 配置侧链

  • 1.为侧链生成若干创世见证者地址,注意保留私钥。
  • 2.启动侧链witness节点, 注意在下面的配置文件中填写相应的Owner,GR账户,GO账户,节点信息列表等。

配置文件:

net {
  type = mainnet
  # type = testnet
}

storage {
  # Directory for storing persistent data

  db.directory = "database",
  index.directory = "index",

  # You can custom these 14 databases' configs:

  # account, account-index, asset-issue, block, block-index,
  # block_KDB, peers, properties, recent-block, trans,
  # utxo, votes, witness, witness_schedule.

  # Otherwise, db configs will remain defualt and data will be stored in
  # the path of "output-directory" or which is set by "-d" ("--output-directory").

  # Attention: name is a required field that must be set !!!
  properties = [
    //    {
    //      name = "account",
    //      path = "storage_directory_test",
    //      createIfMissing = true,
    //      paranoidChecks = true,
    //      verifyChecksums = true,
    //      compressionType = 1,        // compressed with snappy
    //      blockSize = 4096,           // 4  KB =         4 * 1024 B
    //      writeBufferSize = 10485760, // 10 MB = 10 * 1024 * 1024 B
    //      cacheSize = 10485760,       // 10 MB = 10 * 1024 * 1024 B
    //      maxOpenFiles = 100
    //    },
    //    {
    //      name = "account-index",
    //      path = "storage_directory_test",
    //      createIfMissing = true,
    //      paranoidChecks = true,
    //      verifyChecksums = true,
    //      compressionType = 1,        // compressed with snappy
    //      blockSize = 4096,           // 4  KB =         4 * 1024 B
    //      writeBufferSize = 10485760, // 10 MB = 10 * 1024 * 1024 B
    //      cacheSize = 10485760,       // 10 MB = 10 * 1024 * 1024 B
    //      maxOpenFiles = 100
    //    },
  ]

}

node.discovery = {
  enable = true
  persist = true
  bind.ip = ""
  external.ip = null
}

node.backup {
  port = 10001
  priority = 8
  members = [
  ]
}

node {
  # trust node for solidity node
  # trustNode = "ip:port"
  trustNode = "127.0.0.1:50051"

  # expose extension api to public or not
  walletExtensionApi = true

  listen.port = 18888

  connection.timeout = 2

  tcpNettyWorkThreadNum = 0

  udpNettyWorkThreadNum = 1

  # Number of validate sign thread, default availableProcessors / 2
  # validateSignThreadNum = 16

  maxActiveNodes = 30

  maxActiveNodesWithSameIp = 2

  minParticipationRate = 0

  p2p {
    version = 201909101 # 201909101: sunnet;
  }

  active = [
    # Active establish connection in any case
    # Sample entries:
    # "ip:port",
    # "ip:port"

  ]

  passive = [
    # Passive accept connection in any case
    # Sample entries:
    # "ip:port",
    # "ip:port"
  ]

  http {
    fullNodePort = 8090
    solidityPort = 8091
  }

  rpc {
    port = 50051

    # Number of gRPC thread, default availableProcessors / 2
    # thread = 16

    # The maximum number of concurrent calls permitted for each incoming connection
    # maxConcurrentCallsPerConnection =

    # The HTTP/2 flow control window, default 1MB
    # flowControlWindow =

    # Connection being idle for longer than which will be gracefully terminated
    maxConnectionIdleInMillis = 60000

    # Connection lasting longer than which will be gracefully terminated
    # maxConnectionAgeInMillis =

    # The maximum message size allowed to be received on the server, default 4MB
    # maxMessageSize =

    # The maximum size of header list allowed to be received, default 8192
    # maxHeaderListSize =

    # Transactions can only be broadcast if the number of effective connections is reached.
    minEffectiveConnection = 0
  }

}


seed.node = {
  # List of the seed nodes
  # Seed nodes are stable full nodes
  # example:
  # ip.list = [
  #   "ip:port",
  #   "ip:port"
  # ]
  ip.list = [

  ]
}

genesis.block = {
  # Reserve balance
  assets = [
    {
      accountName = "Owner"
      accountType = "AssetIssue"
      address = ""
      balance = "0"
    },
    {
      accountName = "GenesisOracle1"
      accountType = "AssetIssue"
      address = ""
      balance = "0"
    },
    {
      accountName = "GenesisOracle2"
      accountType = "AssetIssue"
      address = ""
      balance = "0"
    },
    {
      accountName = "GenesisOracle3"
      accountType = "AssetIssue"
      address = ""
      balance = "0"
    },
    {
      accountName = "GenesisOracle4"
      accountType = "AssetIssue"
      address = ""
      balance = "0"
    },
    {
      accountName = "Blackhole"
      accountType = "AssetIssue"
      address = "T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb"
      balance = "-9223372036854775808"
    }
  ]

  witnesses = [
    {
      address: ,
      url = "http://GR1.com",
      voteCount = 100000004
    },
    {
      address: ,
      url = "http://GR2.com",
      voteCount = 100000003
    },
    {
      address: ,
      url = "http://GR3.com",
      voteCount = 100000002
    },
    {
      address: ,
      url = "http://GR4.com",
      voteCount = 100000001
    },
    {
      address: ,
      url = "http://GR5.com",
      voteCount = 100000000
    }
  ]

  timestamp = "0" #2017-8-26 12:00:00

  # mandatory to have sideChainId
  sideChainId = ""
}

#localwitness = [
#]

localwitnesskeystore = [
   "localwitnesskeystore.json"
]

block = {
  needSyncCheck = true
  maintenanceTimeInterval = 21600000 // 6 hours: 21600000(ms)
  proposalExpireTime = 64800000 // 18 hours: 64800000(ms)
}

trx.reference.block = "solid" //head;solid

vm = {
  supportConstant = true
  minTimeRatio = 0.0
  maxTimeRatio = 10.0
  saveInternalTx = true

  # In rare cases, transactions that will be within the specified maximum execution time (default 10(ms)) are re-executed and packaged
  # longRunningTime = 10
}

committee = {
  chargingSwitchOn = 0
  # voteSwitch = 0 // for test only
}

sidechain = {
  chargingType = 0   //0:trx, 1:sun_token
  //chargingBandwidth = 1   //0:off, 1:on  if committee.chargingSwitchOn == 0, chargingBandwidth is always off
  energyFee = 5 // 1 sun per energy, can not be 0    proposal 11
  totalEnergyLimit = 100000000000 // 100_000_000_000 frozen energy limit
  maxCpuTimeOfOneTx = 50 // max cpu time to execute single smart contract transaction. default 50ms. proposal 13
  witnessMaxActiveNum = 5 // max witness number
}

log.level = {
  root = "INFO" // TRACE;DEBUG;INFO;WARN;ERROR
}
  • 2.启动侧链的fullnode,配置kafka,连接侧链
  • 3.使用sun-cli,Owner 在侧链上部署侧链gateway合约(设置合约部署者付全部费用),获得合约地址 C2
    • sun-cli的deploycontract命令(不能使用wallet-cli)
  • 4.如果是多个oracle的话,调用侧链gateway合约的addOracle(address)方法一个一个的添加oracle
    • sun-cli命令: triggercontract $sidechain_gateway addOracle(address) "$oracel_address" false 1000000000 0 0 0
  • 5.某个GR 提proposal让侧链节点更改侧链gateway地址, createproposal之后其他2/3的GR approveproposal
    • sun-cli 命令: createproposal 1000001 $sidechain_gateway
    • sun-cli 命令: approveproposal 1 true

5. 重启 sun-cli

  • 将侧链gateway地址C2,配置进sun-cli的配置文件,重启sun-cli

6. 配置 Oracle

  • 启动oracle(如果有多个oracle的话,一一启动)

配置文件:

mainchain {
  fullnode {
    ip.list = [
      ""
    ]
  }

  solidity {
    ip.list = [
      ""
    ]
  }
}

sidechain {
  fullnode {
    ip.list = [
      ""
    ]
  }

  solidity {
    ip.list = [
      ""
    ]
  }

  chain.id = 
}

kafka {
  server = ""
  # group.id = 
  authorization {
    user = 
    passwd = 
  }
}

gateway {
  mainchain.address = 
  sidechain.address = 
}

oracle {
  # private.key = 
  keystore=""
  retryTimes = 3
}

initTaskSwitch = true

7. 设置主侧链合约属性

  • Owner账户更具部署需求分别在主侧链修改合约的最小转入值,手续费等属性。

8. Owner所有者向侧链的GO账户注入初始资金以供侧链跨链交易运行

  • 每个oracle建议值(100 trx)

9. 转出开启收费开关的提案

  • 某个GR创建proposal,createproposal 1000000 1 。之后等待2/3的GR通过提案。

测试是否部署成功

1. depositTRX流程

  • 主链上某个账号A2,调用主链gateway合约的depositTRX或者fallback函数充值TRX

    • sun-cli 命令: deposit trx $main_gateway $num $feelmit
  • 等待一段时间之后,在侧链上查看账户余额(查看账号被创建、查看余额)

    • sun-cli 命令: getAccount $address
  • 主链上再次使用账号A2,调用主链gateway合约的depositTRX或者fallback函数充值TRX

  • 等待一段时间之后,在侧链上查看账户余额是否增加正确

2. depositTRC10流程

  • 主链上某个账号A3,发行TRC10

    • 发行 TRC10 的 sun-cli 命令: assetissue nmbb 10000000000 1 1 0 2019-10-13 2019-12-31 abc abc.com 1000 10000
    • 查看所有 TRC10 token: ListAssetIssue
  • 调用主链gateway合约的depositTRC10或者fallback函数充值TRC10

    • sun-cli 命令: deposit trc10 $main_gateway $trc10Id $num $feelmit
  • 等待一段时间之后,在侧链上查看TRC10余额(A3账号被创建,对应TRC10也被创建)

    • sun-cli 命令: getAccount $address
  • 主链上再次使用账号A3,调用主链 gateway 合约的 depositTRC10 或者fallback函数充值 TRC10

  • 等待一段时间之后,在侧链上查看TRC10余额是否正确

    • sun-cli 命令: getAccount $address

3. depositTRC20流程

  • 主链部署TRC20合约

  • A4 调用主链gateway合约的 depositTRC20,查看交易是否失败,失败是正确的预期

    • sun-cli 命令: deposit trc20 mainchainTrc20ContractAddress mainGatewayAddress num feelmit
  • TRC20开发者在主链上调用主链gateway的mappingTRC20,完成主链和侧链TRC20的映射,侧链上对应TRC20合约被创建

    • sun-cli 命令: triggercontract $main_chain_gateway mappingTRC20(bytes) $deployed_transaction_id false 1000000000 0 0 #
  • A4调用主链gateway合约的depositTRC20

  • 等待一段时间之后,在侧链gateway里mainToSideContractMap(address)查看TRC20映射关系(A4账号不会被创建)

  • 调用对应的TRC20合约的balanceOf(address)查看账户余额是否正确增加

4. depositTRC721流程

  • 主链部署TRC721合约

  • 主链上某个账号A5,调用主链gateway合约的depositTRC721,查看交易是否失败,失败是正确的预期

    • sun-cli 命令: deposit trc721 $mainchain_trc721_contract $main_chain_gateway $trc721_tokenId $feelmit
  • TRC721开发者在主链上调用主链gateway的mappingTRC721,完成主链和侧链TRC721的映射,对应TRC721合约被创建

    • sun-cli 命令: triggercontract $main_chain_gateway mappingTRC721(bytes) $deployed_transaction_id false 1000000000 0 0 #
  • A5调用主链gateway合约的depositTRC721

  • 等待一段时间之后,在侧链gateway里mainToSideContractMap(address)查看TRC721映射关系(A5账号不会被创建)

  • 调用对应的TRC721合约的balanceOf(address)查看对应tokenId的所属关系

5. withdrawTRX流程

  • 侧链上账号A2,调用侧链gateway合约的withdrawTRX
    • sun-cli 命令: withdraw trx $trx_num $fee_limit
  • 等待一段时间之后,在主链上查看账户余额

6. withdrawTRC10流程

  • 侧链上账号A3,调用侧链对应TRC20合约的withdrawal
    • sun-cli 命令: withdraw trc10 $trc10Id $value $fee_limit
  • 等待一段时间之后,在主链上查看账户TRC10余额

7. withdrawTRC20流程

  • 侧链上账号A4,调用侧链对应TRC20合约的withdrawal
    • sun-cli 命令: withdraw Trc20 $side_trc20_address $value $fee_limit
  • 等待一段时间之后,在主链上查看主链对应TRC20的余额

8. withdrawTRC721流程

  • 侧链上账号A5,调用侧链对应TRC721合约的withdrawal
    • sun-cli 命令: withdraw Trc721 $sideTrc721Address $trc721_tokenId $fee_limit
  • 等待一段时间之后,在主链上查看对应TRC721账户的tokenId的所属关系

9. retryWithdraw流程

  • 侧链上按照nonce值来重试
    • sun-cli 命令: triggercontract $sidechaingateway retryWithdraw(uint256) $nonce false 1000000000 0 0 0

10. 提出开启能量消耗提案前的准备

  • gateway合约部署者从主链deposit一大笔trx进侧链,并freeze 带宽,energy

    • sun-cli 命令: deposit trx $mainGatewayAddress $num $feelmit
    • freeze同主网一致
  • Oracle 从主链deposit一大笔trx进入侧链,并freeze 带宽,energy,供gateway部署者能量不足时的deposit调用。

    • sun-cli 命令 (和1相同): deposit trx $mainGatewayAddress $num $feelmit
    • freeze同主网一致
  • 某一个witness提出 energyChargingSwitchOn == 1的proposal

    • witnesses通过proposal
      • sun-cli 命令: createproposal 1000000 1 //eg. createproposal 1000000 1
    • 等待proposal生效
      • sun-cli 命令: approveproposal 1 true

11. 测试能量消耗下的转入,提款是否符合预期

  • 请在开启 能量收费开关之后, 测试 前述1~9的命令.

X. RoadMap

DAppChain 作为 TRON 扩容计划的一部分,肩负着去中心化,繁荣 TRON 生态的使命。对于整个生态的所有建设者而言,将会伴随 DAppChain 的发展度过 L1,L2,L3 三个阶段。我们将会随着计划地开展以及开发工作的进一步完成,为社区开放更多的角色,让社区可以以不同的形式参与到整个生态体系中来。

roadmap

  • L1: First DAppChain (第一侧链)

在 L1 阶段,TRON 将对外公布自己的第一条同构侧链,DAppChain。对 TRON 主网进行扩容,同时更好地支持 DApp 的生态发展。

在 L1 阶段,基金会对社区所开放的角色有:

User:链基本功能的使用者

Developer:合约和 DApp 开发者

Witness: 链交易验证者,负责侧链交易打包

在这个阶段,DAppChain 初始由官方搭建。官方鼓励社区参选 witness,参与侧链的治理,并最终实现社区自治的 DAppChain。

  • L2: Autonomous Chains (多条社区运营的侧链)

SUN Network 侧链有初始 DAppChain 的同时,将允许开发者建立自己的侧链,可以使用自己的代币进行该侧链生态的治理。侧链可通过定制参数,让侧链更适合自身 DApp 的业务特性,比如更低的资源消耗,更快的产块速度等。

L2 阶段将鼓励社区自主运营多条侧链。

  • L3: Fair Network(仲裁者机制主导的完整网络体系)

在生态扩大之后,链间的行为将会由社区 Judger 节点进行验证治理。将以 zk-snark/Truebit-liked 的形式相结合,对 Judger 的行为给予奖惩,保证整个网络的正常工作。

L3 阶段将把侧链的仲裁者角色开放给社区。