如何在波场上开发dApp

最近波场(TRON)发起了“加速器计划”,吸引开发者在波场上开发dApp,奖金总额高达100万美金。

今天抽了点时间研究了下波场:波场是从EthereumJ上fork出来的,共识机制换成了改良过的DPoS,另外借鉴了EOS上的RAM/CPU机制(对应Energy/Bandwidth Point)。智能合约还是用Solidity写的,唯一可能需要改动的地方:把代码里的货币单位ether/wei换算成trx/sun(波场币的最小面额是sun,孙宇晨的sun。。。),1 TRX = 1,000,000 sun。

所以,以太坊上的dApp,几乎不需要任何改动就可以移植到波场上。这里首先介绍一下波场的一些技术特点,心急赚钱的兄弟可以跳过,直接跳到第12节看怎么部署合约、连接前端就可以了,哈哈~

1.体系架构

TRON采用了三层体系架构:

  • 存储层:存储区块数据和状态数据

  • 核心层:包括智能合约模块、账户管理模块、共识模块等

  • 应用层:即各种dApp跟钱包等应用

另外,协议方面是用Google protobuf定义的,目前只有Java版本的实现,后续计划会扩展到其他语言(跟以太坊类似,以太坊也有geth,EthereumJ,cpp-ethereum等各种版本的实现)。
如何在波场上开发dApp_第1张图片

2.节点类型

波场网络定义了3种类型的节点:

  • 超级节点(Super Representative Witness Node):负责生产区块

  • 全节点(Full Node):提供API服务,广播交易和区块

  • Solidity节点(Solidity Node):同步区块,提供查询API

这跟EOS基本是一样的,出于安全性考虑,最终用户是不可能直接跟超级节点通信的,需要通过全节点跟Solidity节点访问网络。如果你想做一个交易所,则需要部署一个全节点和一个Solidity节点。

3.共识机制

波场的共识机制采用的是改良过的DPoS,称为TPoS。

网络中每6小时投一次票,选出27个超级节点负责出块和共识。投票是通过抵押TRX完成的,如果用户想取消抵押,需要等待3天才能释放。选出的超级节点轮流出块,每3秒出一个块,出块奖励会放在“超级账本“的一个子账户中,超级节点过24小时才能提取。

那么,所谓的“改良”体现在哪里呢?

我们知道,EOS的DPoS有一个问题:只有投票给前21个超级节点的用户可以分红,投给落选节点的用户一分钱都得不到。久而久之,大家就都不愿意投给排在后面的节点了,从而加剧中心化的风险。波场在DPoS基础上做了一些改良,使得落选的打包节点、投票给中选者的用户、投票给落选者的用户均可能获得一定量的补偿,以激励他们持续参与之后的竞选流程。

具体来说,奖励分为两类:

(1)投票奖励(vote reward)

每出一个块,将产生16 TRX的“投票奖励”,这部分奖励将由前127个候选节点共同瓜分。

因此,每过一轮(6小时),这127个候选节点一共会瓜分16TRX/block × 20blocks/min × 60mins/hr × 6hrs = 115,200 TRX。

(2)出块奖励(block reward)

每出一个块,将产生32 TRX的“出块奖励”,由27个超级节点共同瓜分。

因此,每过一轮(6小时),这27个候选节点一共会瓜分32TRX/block × 20blocks/min × 60mins/hr × 6hrs = 230,400TRX。

需要注意的是,这27个节点的最终收益是它们获得的“投票奖励”和“出块奖励”之和。

另外,波场承诺2021年1月1日前不增发,之后每年会增发固定数量的TRX。

4.委员会

当前轮次中的27个超级节点组成一个委员会,如果需要修改网络参数配置,则必须由其中一个超级节点发起提案,当收到超过19个赞成票时即可通过提案,并于3天后应用新的网络参数配置。

5.TPS

既然共识机制从PoW改成了TPoS,TPS必然会有提升。官方宣称能达到2000 TPS:
如何在波场上开发dApp_第2张图片
目前实网TPS峰值为748:
在这里插入图片描述

6.账户

账户有基本账户、资产发布账户和合约账户三种类型:

  • 普通账户:存储TRX
  • token账户:存储TRC-10代币
  • 合约账户:存储智能合约

一个账户包含账户名称、账户类型、地址、余额、投票、其他资产、上次操作时间等7种属性。更进一步的,基本账户可以申请成为验证节点,验证节点具有额外的属性,比如投票统计数目、公钥、URL、以及历史表现等等。

账户地址的生成规则结合了以太坊和比特币的特点:

  • 首先生成私钥-公钥对
  • 算出公钥的哈希,取后20个字节作为地址:addr = keccak256(public_key)[12:31]
  • 在addr前加上一个字节41,然后算哈希,取前4个字节作为验证码:checksum = keccak256(41, addr)[0:3]
  • 把验证码添加到之前生成的地址的后面,总长度24个字节:(addr, checksum)
  • 对上一步的结果取Base58编码,得到33个字节长度的输出
  • 在最前面加上字母T,生成最终地址,因此最终地址长度为34个字节

7.存储

数据存储主要分为两类:

  • 区块数据:仍然采用LevelDB
  • 状态数据:波场设计了一种新的存储方式KhaosDB,据称可以在分叉的情况下快速切换主链,具体细节没有深究

8.交易

交易签名和以太坊一样采用secp256k1算法,每笔交易需要等待19个区块确认,按3秒一个块来算,确认一笔交易最少需要57秒,还是比较快的。

另外,波场也借鉴了EOS中的TaPoS的概念,交易头中包含近期区块的hash,从而可以减少分叉风险。

交易有多种类型,包括账户创建、转账、转账资产、资产投票、见证节点投票、见证节点创建、资产发布、合约部署等26种类型。代码里把这些类型定义为ContractType,不是很理解。。。

另外,波场借鉴了EOS中的RAM/CPU的设计,在执行普通交易时需要消耗Bandwidth Point,而执行智能合约操作时则需要同时消耗Bandwidth Point和Energy,后面会一一介绍。

9.带宽模型(Bandwidth Point)

执行普通交易需要消耗“Bandwidth Point”,简称BP,类似于EOS中CPU。

每人每天5000个免费BP,如果不够用需要额外抵押TRX获取BP。消耗的BP数量和交易字节数成正比,如果BP用完了,则会消耗用户的TRX,具体消耗顺序:

用户抵押TRX获得的BP > 用户每天5000个免费BP > 消耗TRX(字节数*10 SUN)

上面的规则适用于创建和修改操作,执行查询操作是不收费的。

另外,有一些特殊交易类型采用固定收费方式:

  1. 创建超级节点: 9999 TRX
  2. 发行TRC-10代币: 1024 TRX
  3. 创建新账户: 0.1 TRX
  4. 创建一个交易对: 1024 TRX (波场内建DEX支持,基于Bancor协议)

10.能量模型(Energy)

首先提一下波场的虚拟机TVM,是在EVM的基础上改的,增加了一些投票相关的built-in函数。

另外Solidity也是从以太坊fork出来的,兼容Solidity ^0.4.24。

TVM执行智能合约需要消耗Energy,和以太坊的gas不同,Energy需要通过抵押TRX来获得。这一点和EOS上的RAM有点类似,但是不尽相同,EOS上的RAM是要用你手里的EOS去买的,而Energy则是通过抵押获得的,抵押率是一个网络参数,由委员会负责制定和修改。

看了下目前的代码,Energy的计算跟以太坊gas的计算方式基本没啥区别~

11.TRC-10和TRC-20 token

ERC-20 token大家都比较熟悉,对应到波场上叫TRC-20。另外,波场上还有一种TRC-10 token,可以理解为一种“一键发币”功能,用来应付类似于积分或者优惠券之类的需求已经足够了。

发行TRC-10 token只需要指定下面这些参数,然后发送一笔交易就搞定了:(需要消耗1024 TRX)

  • 名称
  • 总量
  • 对TRX的兑换率
  • 流通周期
  • 描述
  • 网站
  • 每个账户的最大带宽消耗
  • 总带宽消耗
  • 锁仓数量

TRC-10 token通过API和智能合约都能访问(Explorer上也可以查到),但是只有固定的对外接口。TRC-20可以对接口进行定制,但是只能通过智能合约进行访问。另外,TRC-10的交易费用比TRC-20低1000倍,且只消耗Bandwidth Point,不消耗Energy。

12.搭建开发环境

介绍了这么多,那么怎么在波场上开发dApp呢?

波场的开发工具配套还是挺全的,基本上以太坊上有的它都有,参考下表中的对比:

以太坊 波场
智能合约 Solidity Solidity
前端 Web3 TronWeb
开发框架 Truffle TronBox
IDE Remix TronStudio
Chrome插件 MetaMask TronLink
IaaS Infura TronGrid

如果想要在本地开发dApp,建议使用docker模式在本地运行一个私有测试网,包含一个全节点、一个Solidity节点和一个Event Server(可以监听合约event):

docker run -it -p 8091:8091 -p 8092:8092 -p 8090:8090 -p 50051:50051 -p 50052:50052 --rm --name tron trontools/quickstart:1.2.6

其中8090和8091分别是全节点和Solidity节点的HTTP端口,50051和50052分别是全节点和Solidity节点的gRPC端口,8092是Event Server的通信端口。

可以用下面的命令验证一下节点是否运行正常:

docker exec -it tron ps aux

如何在波场上开发dApp_第3张图片

默认情况下会帮你创建10个测试账户,每个账户里有10000TRX,可以用下面的命令查询账户信息:

curl http://127.0.0.1:8090/admin/accounts

如何在波场上开发dApp_第4张图片

13.使用TronStudio开发智能合约

TronStudio是波场的智能合约开发IDE,类似于以太坊中的Remix。

首先下载TronStudio源码:

git clone https://github.com/tronprotocol/tron-studio

然后编译,注意必须是Java8,我机器上装的Java10编译会报错。。

./gradlew build -x test -x check

启动TronStudio:

java -jar build/libs/TronStudio.jar

接下来就可以愉快地编写HelloWorld合约了,界面长这样:
如何在波场上开发dApp_第5张图片

编译合约:点击Compile按钮

部署合约:首先点击右上角齿轮,配置Local TVM地址和端口:127.0.0.1:50051,然后点击右边的Deploy按钮就可以了。合约部署完后可以在右边的面板中发起合约调用。

14.测试TronWeb API

和以太坊中的Web3类似,波场中的dApp使用TronWeb和节点进行通信。

如果你只是想在命令行上试用一下TronWeb的API,可以下载下面的工具,类似于以太坊的geth控制台:

git clone https://github.com/tronprotocol/docker-tron-quickstart.git

然后安装依赖:

cd docker-tron-quickstart
cd app
npm install
cd ..

注意:代码中默认指定的端口是9090,需要改成我们刚刚运行docker时指定的端口号,修改app/src/config.js:
如何在波场上开发dApp_第6张图片
接下了就可以用下面的命令进入node命令行了:

node tronWeb

比如我们可以用下面的命令查询区块信息、交易的执行情况:

tronWeb.trx.getCurrentBlock().then(result => console.log(result))

tronWeb.trx.getTransaction('0f71dd1bd643bb953fe6d609d05112d8645b1e621e5dffd248cda46069c1af5e').then(result => console.log(result))

完整API列表参见:https://developers.tron.network/v3.0/reference#tronwebapi

15.使用TronWeb连接前端

如果你是一个前端程序员,需要在代码里访问节点,那么只需要在你的项目添加tronweb依赖:

npm install tronweb

然后就可以在代码使用了,以调用上面的HelloWorld合约为例:

const TronWeb = require('tronweb');
const HttpProvider = TronWeb.providers.HttpProvider;
const fullNode = new HttpProvider('http://127.0.0.1:8090');    //Your local TVM URL  
const solidityNode = new HttpProvider('http://127.0.0.1:8091');
const eventServer = 'http://127.0.0.1:8092';
const privateKey = '6d8d7cdc92dbcbe945643efe1a9fcd80d875ea82fbee3460ee0207611d12e1e9';

const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);

async function changestate(){
  let contractAddress = 'TKjGYzq8svwBZXKSsV1bsmNZTeMswrncHe';   //Your address
  let contract = await tronWeb.contract().at(contractAddress);
  let resultPost = await contract.postMessage("TRON to the Future").send();
  let resultGet = await contract.getMessage().call();
  console.log('resultGet: ', resultGet);
}

changestate()

首先需要创建一个TronWeb对象,其中fullNode和solidityNode参数是必须指定的,后面两个参数可选。

TronWeb对象内部包含了好几个模块:

  • tronWeb.trx:用于各种信息查询
  • tronWeb.transactionBuilder:用于交易和投票
  • tronWeb.:各种编码和加密相关的工具,比如address,base58
  • tronWeb.contract:生成合约对象
  • tronWeb.:各种工具方法

具体的调用方法参见上面的API列表链接,或者你也可以直接看源码:
如何在波场上开发dApp_第7张图片

16.总结

波场目前前的实现基本上就是以太坊+DPoS,同时借鉴了EOS上的一些概念。实际上,在波场上开发dApp和在以太坊上基本没多大区别,想赚快钱的小伙伴赶紧行动起来,提交自己的dApp作品吧,截止时间是2019年1月4日,第一名的奖金是20万美金哦~

更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
或关注飞久微信公众号:
如何在波场上开发dApp_第8张图片

你可能感兴趣的:(区块链)