相关文章推荐
满身肌肉的八宝粥  ·  【Day31】ChatGPT請教教我:Jes ...·  4 月前    · 
纯真的羽毛球  ·  constexpr (C++) | ...·  1 周前    · 
粗眉毛的镜子  ·  請說明 (NOT) LIKE ...·  8 月前    · 
安静的领结  ·  发展中法语言教育 共促两国青年交流 - ...·  1 年前    · 
悲伤的沙滩裤  ·  追求男女平等的女权,为何在网上争议不断?_女 ...·  1 年前    · 
胡子拉碴的饼干  ·  环球人物·  1 年前    · 
无邪的猴子  ·  一桩提前张扬的转会:萨内离开曼城,德国球员终 ...·  1 年前    · 
Code  ›  Tron(波场)实践篇开发者社区
const
https://cloud.tencent.com/developer/article/1578954
至今单身的牛排
2 年前
作者头像
陨石坠灭
0 篇文章

Tron(波场)实践篇

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > 全栈之路 > Tron(波场)实践篇

Tron(波场)实践篇

作者头像
陨石坠灭
发布 于 2020-01-21 15:43:34
5.9K 2
发布 于 2020-01-21 15:43:34
举报

参考文档

官方文档: https://github.com/tronprotocol/Documentation/tree/master/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3

TronLink官方文档: https://developers.tron.network/docs/wallet-integration

TronWeb官方文档: https://developers.tron.network/docs/tron-web-intro

共识机制(POW、POS、DPOS、PBFT及POP)才是区块链的灵魂: https://baijiahao.baidu.com/s?id=1596184609683656426&wfr=spider&for=pc

由于Tron与eth相似,所以大部分可以参考Web3js。同时,会针对Tran的一些特点做出相对应的拓展。

接下来列出Tron使用到的相关技术和插件:

  • 操作系统:Mac
  • 编辑器:Vscode
  • 开发语言:Typescript
  • 合约语言:Solidity
  • 第三方库:tron-web.js https://github.com/tronprotocol/tron-web
  • Chrome插件-TronLink

安装钱包插件

1. 下载插件

下载地址: https://chrome.google.com/webstore/detail/tronlink/ibnejdfjmmkpcnlpebklmnkoeoihofec

2. 设置密码、保存助记词

助记词最好保存到本地,忘了还可以凭借助记词找回账号。

点击 Export 按钮即可看到密钥和助记词

3. 切换到设置界面,然后切换到测试网的配置

Settings -> Node selection -> Shasta Testnet

4. 获取trx

获取地址: https://www.trongrid.io/shasta/#request

复制插件 Accounts 界面的账号地址,然后粘贴到输入框,然后点击 SUBMIT 按钮。

获取TRX: https://www.trongrid.io/shasta/#request

查看账号信息: https://tronscan.org/#/account

API地址: https://api.shasta.trongrid.io

参考: https://github.com/Tronbox-boxes/metacoin-box

ps: 下载后需要删除 package-lock.json 文件

官方文档参考: https://developers.tron.network/docs/tron-box-contract-deployment

1. 下载代码

git clone https://github.com/Tronbox-boxes/metacoin-box

2. 修改 tronbox.js 配置

参数 fee_limit 设置的值相对大一些,部署的时候就不会因为部署费用问题而导致部署失败。

consume_user_resource_percent: 0, fee_limit: 1000000000, ...

3. 删除 package-lock.json 文件,并初始化

若初始化失败,只可以执行 npm install 多次,如果不行,可以打开V**

cd metacoin-box/
rm package-lock.json
npm cache clean --force
npm install

4. 创建 .env 文件

.env 文件:

PK=<你的密钥>
NODE=https://api.shasta.trongrid.io
NETWORK=shasta

5. 编译和部署

source .env
rm -rf ./build
tronbox compile
tronbox migrate --network $NETWORK

6. 调用合约

首先初始化:

npm install fs --save-dev
npm install tronweb --save-dev

编写 index.js :

const fs = require('fs');
const TronWeb = require('tronweb');
const HttpProvider = TronWeb.providers.HttpProvider;
const fullNode = new HttpProvider(process.env.NODE);
const solidityNode = new HttpProvider(process.env.NODE);
const eventServer = process.env.NODE;
const privateKey = process.env.PK;
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
const contrctJson = JSON.parse(fs.readFileSync('./build/contracts/Migrations.json', 'utf8'));
const address = contrctJson['networks']['*'].address;
(async () => {
    try {
        let contract = await tronWeb.contract().at(address);
        let param = {
            feeLimit: 1000000000,
            callValue: 0,
            shouldPollResponse: true
        let result = await contract.setCompleted(1).send(param);
        console.log('result: ', result);
    } catch(e){
        console.error(e);
    console.log('complement.');
})();

nodejs - tronweb

const TronWeb = require('tronweb');
const HttpProvider = TronWeb.providers.HttpProvider;
const fullNode = new HttpProvider('https://api.trongrid.io');
const solidityNode = new HttpProvider('https://api.trongrid.io');
const eventServer = 'https://api.trongrid.io/';
const privateKey = 'da14...9f0d0';
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);

TronLink插件用法:

window.onload = function() {
  if (!window.tronWeb) {
    const HttpProvider = TronWeb.providers.HttpProvider;
    const fullNode = new HttpProvider('https://api.trongrid.io');
    const solidityNode = new HttpProvider('https://api.trongrid.io');
    const eventServer = 'https://api.trongrid.io/';
    const tronWeb = new TronWeb(
        fullNode,
        solidityNode,
        eventServer,
    window.tronWeb = tronWeb;
};

获取余额:

var balance = await tronWeb.trx.getBalance(userAddress);

发送交易:

tronWeb.transactionBuilder.sendTrx(
    "TXPHCzmAmjyERtWES6EXTYqUPfJfQSzp2m", 
    "TZDCUCy3Wn1HhJVseANdrhzqDYCTEue8xT"
);

发送Token:

tronWeb.transactionBuilder.sendToken(
    "TXPHCzmAmjyERtWES6EXTYqUPfJfQSzp2m", 
    "WIN", 
    "TCanwMYEkP1e6ZWSA2gdU6jDEm1TxWMYQF"
);

tronWeb.transactionBuilder.withdrawBlockRewards(
    "TXPHCzmAmjyERtWES6EXTYqUPfJfQSzp2m"
);

获取账号信息:

tronWeb.trx.getAccount("TNDFkUNA2TukukC1Moeqj61pAS53NFchGF");

获取带宽:

tronWeb.trx.getBandwidth("TNDFkUNA2TukukC1Moeqj61pAS53NFchGF");

获取账号资源:

tronWeb.trx.getAccountResources("TXPHCzmAmjyERtWES6EXTYqUPfJfQSzp2m");

初始化合约对象:

const priceOracle = 
    tronWeb.contract(
        contract["PriceOracle.sol:PriceOracle"].abi,  
        contract["PriceOracle.sol:PriceOracle"].address
    );

添加监听事件:

priceOracle["PriceUpdate"]().watch((err, {result}) => {
    if (err) return console.error('Failed to bind event listener:', err);
    console.log(result);
});

转码与编码:

tronWeb.toUtf8("74657374")
result = "test"
tronWeb.toHex("test")
result = "74657374"

判断是否连接:

tronWeb.isConnected()

合约方法调用:

Use call to execute a pure or view smart contract method

let abi = [...];
let contract = await tronWeb.contract({abi});
let result = await contract.["合约方法名称"](<合约参数>).call();

Use send to execute a non-pure or modify smart contract method

let result = await contract.calculateValue(5).send({
    feeLimit:10000,
    callValue:10000,
    shouldPollResponse:true
});

绑定合约:

async function triggercontract(){
  let contractInstance = await tronWeb.contract().at("contract address in hex string");
  //watch event if there is 
  contractInstance["event_name"]().watch(function(err, res) {
    console.log("error " + err);
    console.log('eventResult:',res);
  let args = {
    callValue:0,
    shouldPollResponse: true
  let result  = await contractInstance.function_name(para1,para2,...).send(args);

遇到的问题

1. bytes32编码问题

由于合约中部分字段类型为bytes32,调用合约的时候直接报错了

解决方法:

调用Tronweb.sha3即可将字符串转化为bytes32类型。

let args = {
    callValue:0,
    shouldPollResponse: true
var contractInstance = tronWeb.contract().at(address);
contractInstance['funcName'](tronWeb.sha3(param1)).send(args);

2. 合约调用回滚

回滚的话只要是因为设置得参数不符合要求,要看具体情况,这里说其中的一种:

如果调用合约方法时需要支付TRX,则需要设置callValue。

加入调用合约需要支付0.0001 TRX,调用方法为func:

let args = {
    callValue:tronWeb.toSun(0.0001),
    shouldPollResponse: true,
    feeLimit: 1000000000
var contractInstance = tronWeb.contract().at(address);
await contractInstance.func(tronWeb.sha3(param1)).send(args);

3. 部署合约失败

可能原因:

  • 1. 费用不足
  • 2. Solidity版本问题

目前部署时有提示:

Uncaught TypeError: Cannot read property 'Error'

从错误并不能看出什么,但是合约版本设置不正确会导致这个问题。

从合约例子来看,可以使用0.4.23版本

  • 3. Solidity中的library单独作为合约文件时出现的问题
Uncaught TypeError: Cannot read property 'foreach'

inline修饰时,json文件api为空数组,将inline转化为public即可。

function sub(uint256 a, uint256 b) inline pure {    

4. tronWeb的API

地址: https://developers.tron.network/v3.0/reference#wallets-accounts

只看到了英文的地址,并且官方API索引做得太差了,要找到这个地址还是比较困难的。

5. 关于编码转换

工具地址: https://tronscan.org/#/tools/tron-convert-tool

选择Base58Check_HexString,输入地址,然后点击Decode或者Encode

代码中转换地址:

 
推荐文章
满身肌肉的八宝粥  ·  【Day31】ChatGPT請教教我:Jest 單元測試(下) - 完整語法&教學 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
4 月前
纯真的羽毛球  ·  constexpr (C++) | Microsoft Learn
1 周前
粗眉毛的镜子  ·  請說明 (NOT) LIKE 運算子是用來做什麼的?|ExplainThis
8 月前
安静的领结  ·  发展中法语言教育 共促两国青年交流 - 中华人民共和国教育部政府门户网站
1 年前
悲伤的沙滩裤  ·  追求男女平等的女权,为何在网上争议不断?_女性_平均主义_男人
1 年前
胡子拉碴的饼干  ·  环球人物
1 年前
无邪的猴子  ·  一桩提前张扬的转会:萨内离开曼城,德国球员终究都是拜仁的_运动家_澎湃新闻-The Paper
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号