如何在波场上开发dApp

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

最近波场(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等各种版本的实现)。

attachments-2019-06-hE4SwEat5d0af08ca1953.jpeg


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:

attachments-2019-06-pba8Oyqx5d0af0b4459e5.jpeg

目前实网TPS峰值为748:

attachments-2019-06-BjcE11d15d0af0cc758eb.jpeg

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)

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

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

创建超级节点: 9999 TRX


发行TRC-10代币: 1024 TRX


创建新账户: 0.1 TRX


创建一个交易对: 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)


12.搭建开发环境

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

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

attachments-2019-06-DxaCl6bi5d0af171f3864.png

如果想要在本地开发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

attachments-2019-06-YtAqlqVY5d0af1c08f0cc.jpeg

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

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


attachments-2019-06-ofIk0nae5d0af1e5107f9.jpeg

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合约了,界面长这样:

attachments-2019-06-96O4yP5R5d0af236457b8.jpeg

编译合约:点击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:

attachments-2019-06-5eCwoSBI5d0af2876bed2.jpeg

接下了就可以用下面的命令进入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.<utils>:各种编码和加密相关的工具,比如address,base58
tronWeb.contract:生成合约对象
tronWeb.<method>:各种工具方法

具体的调用方法参见上面的API列表链接,或者你也可以直接看源码:

attachments-2019-06-4YRtt8qI5d0af35b83547.jpeg

16.总结

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

更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
或关注飞久微信公众号:

attachments-2019-06-rMrWJn5y5d0af38346659.jpeg

  • 发表于 2019-06-20 10:50
  • 阅读 ( 835 )
  • 分类:波场TRON

0 条评论

请先 登录 后评论
不写代码的码农
张桐

架构师

6 篇文章

作家榜 »

  1. 张新 440 文章
  2. 正权 404 文章
  3. 神仙锅锅 371 文章
  4. 董先生 361 文章
  5. 流星法援 246 文章
  6. 唐专员 139 文章
  7. 专业追损 139 文章
  8. 罗先生 139 文章