区块链大学区块链研习社区块链技术文章

Tron(波场)实践篇

2018-12-21  本文已影响0人  陨石坠灭
logo

参考文档

官方文档: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使用到的相关技术和插件:

安装钱包插件

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

合约部署

获取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多次,如果不行,可以打开vpn

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", 
    100, 
    "TZDCUCy3Wn1HhJVseANdrhzqDYCTEue8xT"
);

发送Token:

tronWeb.transactionBuilder.sendToken(
    "TXPHCzmAmjyERtWES6EXTYqUPfJfQSzp2m", 
    100,
    "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. 部署合约失败

可能原因:

目前部署时有提示:

Uncaught TypeError: Cannot read property 'Error'

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

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

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

代码中转换地址:

tronWeb.address.fromHex/tronWeb.address.toHex

6. 如何计算energyBandWidth

计算工具:
https://tronstation.io/energycalc

7. 如何查询测试网的交易记录

查询网址:
https://shasta.tronscan.org

输入自己的账号地址即可

上一篇下一篇

猜你喜欢

热点阅读