波场(Tron)开发指南

in #starnote6 months ago

波场开发的实践总结:基础工具的使用,和合约的交互方法,单位转换和监听事件等。
-> 前往星空笔记

Sort:  

波场中得到的uint数据都是16进制(hex,如:[{"_hex":"0x0f4240"}]),如果在js中做加减乘除可以自动转换成10进制,也可以自动调整。
1 trx = 1000000 sun

uint public b = 1 trx;

let  b = await contract.b().call() //查询方法view
console.log(333, 'b', tronWeb.toBigNumber(b).toFixed())
//333 "b" "1000000"

tronWeb.fromSun()
> tronWeb.fromSun("1000000")
'1'
本地创建的得到 object
浏览器创建的得到 string

tronWeb.toSun()
tronWeb.toSun(10)
>"10000000"
Loading...
Loading...

货币
类似于solidity对ether的支持,波场虚拟机的代码支持的货币单位有trx和sun,其中1trx = 1000000 sun,大小写敏感,只支持小写。目前Tron-IDE支持trx和sun,在remix中,不支持trx和sun,如果使用ether、finney等单位时,注意换算(可能会发生溢出错误)。 我们推荐使用Tron-IDE代替remix进行tron智能合约的编写。

区块相关
block.blockhash(uint blockNumber) returns (bytes32):指定区块的区块哈希——仅可用于最新的 256 个区块且不包括当前区块;而 blocks 从 0.4.22 版本开始已经不推荐使用,由 blockhash(uint blockNumber) 代替
block.coinbase (address): 产当前区块的超级节点地址
block.difficulty (uint): 当前区块难度,波场不推荐使用,设置恒为0
block.gaslimit (uint): 当前区块 gas 限额,波场暂时不支持使用, 暂时设置为0
block.number (uint): 当前区块号
block.timestamp (uint): 当前区块以秒计的时间戳
gasleft() returns (uint256):剩余的 gas
msg.data (bytes): 完整的 calldata
msg.gas (uint): 剩余 gas - 自 0.4.21 版本开始已经不推荐使用,由 gesleft() 代替
msg.sender (address): 消息发送者(当前调用)
msg.sig (bytes4): calldata 的前 4 字节(也就是函数标识符)
msg.value (uint): 随消息发送的 sun 的数量
now (uint): 目前区块时间戳(block.timestamp)
tx.gasprice (uint): 交易的 gas 价格,波场不推荐使用,设置值恒为0
tx.origin (address): 交易发起者

Loading...
async transfer(){
  console.log(161222, "Yes, catch it:", window.tronWeb)
  let tronweb = window.tronWeb
  let sendTransaction = await tronweb.trx.sendTransaction("TVJ1Waucj32mSMuFRab7kn73Pm6KyZGBmg", 1000)
  console.log(566, sendTransaction)
}
let res = await that.axios.get('/Test.json')
// console.log(66744, res)
let data = res.data
let tronWeb = window.tronWeb
let address = tronWeb.address.fromHex(data.networks['*'].address)  //转变成base58
let contract = tronWeb.contract(data.abi, address)
let s = await contract.a().call() //查询方法view
let stringx = 'WSTEEM是ERC20代币,旨在打通STEEM和以太坊网络的通道,使资产自由流通!'
let s2 = await contract.set(stringx).send() //更改方法

Tron-Web:JavaScript接口,用于提供常用的账户,地址,转账,合约相关操作。相当于Ethereum的web3js。

tron-box:提供合约编译,部署,测试的命令行工具。作用相当于Ethereum的truffle工具链。

tronLink,tronPay: 提供浏览器环境的钱包插件,为dapp提供便利和安全的执行环境,相当于Ethereum的MetaMask,Scatter。

tron-grid:社区维护的主网和测试网HTTP API接口,相当于Ethereum社区中的Infura。

Tron-IDE: 一款帮助开发者开发智能合约的在线编辑器。它具有模块化的特点,以插件的方式为开发者提供智能合约的编辑,编译,部署,调试等功能。

用公钥P作为输入,计算SHA3得到结果H, 这里公钥长度为64字节,SHA3选用Keccak256。
取H的最后20字节,在前面填充一个字节0x41得到address。

对address进行basecheck计算得到最终地址,所有地址的第一个字符为T。

其中basecheck的计算过程为:首先对address计算sha256得到h1,再对h1计算sha256得到h2,取其前4字节作为check填充到address之后得到address||check,对其进行base58编码得到最终结果。

我们用的字符映射表为:
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

在波场中地址格式为:"TPY1jv2wrnEHpQAxfQ7BbpyKsDQRZTYDPX"
16进制表示:"4194cdf62db7f02319ec3b9a4009ba60854a896072"
转换函数:tronWeb.address.fromHex(address) //16进制转base58
this.tronWeb.address.toHex(dd) //base58转16进制
eg:
NutboxsPeanuts:
(base58) TYuDs3D3RZVXKhfPocYSyDBV8rES3MEiSs
(hex) 41fb89f2d17db9b45988645908a623855d956d5ba9

注意:波场区块链底层仍是使用的16进制的方式,但是与前端交互的却是使用的base58

Loading...
const dataToWei = function(data){
  let a = data * 1e18
  return this.tronWeb2.toBigNumber(a).toFixed()
}

export {dataToWei}

const dataFromWei = function(data){
  let b = data * 1e-18
  return this.tronWeb2.toBigNumber(b).toFixed(6)
}

export {dataFromWei}

tronscan

tronscan.jpg

TRC20通证和ERC20通证类似,不过因为编译的版本不一致,导致在波场中OpenZeppelin的库无法使用,只能使用原文件。通读下通证的代码,函数基本一致,倒也不用太过担心。这里是PNUT合约,大家可以参考。

TRC20通证合约布署上线后,还需要在tronscan中录入,然后才能上线justswap和poloni这样的DEX。如上图所示,几个输入的参数要和通证合约保持一致,否则无法录入成功!

几点说明:

  1. 像PNUT这样是通过挖矿来分发的,并没有初始量。但tronscan中录入必须有这项参数,所以,可以设初始总量为1。tronscan网络会每隔一段时间(大约是24小时)对这些参数进行更新。当你第二天去查PNUT的总量时,这个参数会更新。
  2. 精度(小数位)最好设为6,而不是18!波场这边的最小单位是sun, 1trx = 1000000sun。并且poloni也只接受6位精度的通证。
  3. 在媒体和联系尽量填全,有助于提升大家对于通证的了解和信心。

最多只花费多少个trx,单位是sun

文档说明

let instance = this.$store.state.nutPoolInstance
await instance.withdrawPeanuts().send({feeLimit:20_000_000})

async test10(){
  let instance = this.$store.state.steemInstance
  let a = await instance.test10().send({
    feeLimit:20_000_000,
    callValue:0,
    shouldPollResponse:true
  })
},
//方法一
let abi = [...];       
let instance = await tronWeb.contract(abi,'contractAddress')
let result = await instance.function_name(para1,para2,...).call()
let result2 = await instance.function_name(para1,para2,...).send()

//方法二
可以省略abi这个参数
let instance = await tronWeb.contract().at('contractAddress');
let result = await instance.function_name(para1,para2,...).call()
let result2 = await instance.function_name(para1,para2,...).send()

//方法三
tronWeb.transactionBuilder.triggerConstantContract(contractAddress,functions, options,parameter,issuerAddress)
eg1:
let parameter = []
let transaction = await tronWeb.transactionBuilder.triggerSmartContract("419e62be7f4f103c36507cb2a753418791b1cdc182", "name()", {},
    parameter,"417946F66D0FC67924DA0AC9936183AB3B07C81126")
eg2:
let parameter1 =  [{type:'uint256',value:100}]
let transaction = await tronWeb.transactionBuilder.triggerSmartContract("419896f9376893d4882fa2375ab1732a943d19f8c2", "getTrxToTokenInputPrice(uint256)", {},parameter1,"412692a1d44cc5a51eefdb8e11e8cd1c20d802e474")
async getPool(){
  let contract = 'TXk8rQSAvPvBBNtqSoY6nCfsXWCSSpTVQF'
  let instance = await tronWeb.contract().at(contract)
  let exchange = await instance.getExchange('TPZddNpQJHu8UtKPY1PYDBv2J5p5QpJ6XW').call()
  // let exchange2 = this.tronWeb2.address.fromHex(exchange)

  let poolcontract = 'TPt2a3GtKMY5972mWa2aL3KKVY6ScWX2G2'
  let PoolInstance = await tronWeb.contract().at(poolcontract)
  let balance = await PoolInstance.balanceOf('TPt2a3GtKMY5972mWa2aL3KKVY6ScWX2G2').call()
},
Loading...