交易
交易是来自账户私钥签名后的指令,账户可以通过发起交易来更新 TRON 网络的状态,最简单的交易是将 TRX 从一个账户转移到另一个账户。
改变 TRON 网络状态的交易需要广播到整个网络,任何一个节点都可以广播交易请求。超级节点收到交易后执行交易,并将其打包进区块,然后将区块广播到网络的其他节点。
交易只有被超级节点打包进区块后,并且区块被确认了,交易才最终被确认。
一个交易的格式如下:
{
"raw_data":
{
"contract": [{<-->}],
"ref_block_bytes": "c145",
"ref_block_hash": "c56bd8a3b3341d9d",
"expiration": 1646796363000,
"data": "74657374",
"timestamp": 1646796304152,
"fee_limit":10000000000
},
"signature":["47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" ]
}交易主要包括以下字段:
raw_data.contract- 交易的主体内容,contract是一个列表,但目前只用到一个元素。TRON 支持多种类型的交易,不同类型的交易,contract 内容不一样,如果是 TRX 转账类型交易,contract 会包含转账金额,接收人等信息。对于不同的交易类型,该字段的具体内容请参考各交易类型全解析 。raw_data.ref_block_bytes- 交易引用块的高度,使用了引用块高度的第 6 到 8(不包含)字节,共 2 字节 。引用块用于 TRON TAPOS 机制,以防止交易在不包含该引用块的分叉链上被重放 。有效的引用区块范围为最新的 65536 个区块,通常建议使用最新固化的区块作为引用区块 。关于如何在代码中设置此字段,请参考 这里。raw_data.ref_block_hash- 交易引用块的hash,使用了引用块hash的第8到16(不包含)字节,共8字节,引用块用于TRON TAPOS机制,可以防止分叉链交易重放, 引用块一般选择最新固化的区块。raw_data.expiration- 交易过期时间,超过这个时间,交易将不再被打包。如果用户调用java-tron节点的API创建交易体,节点会自动设置过期时间,一般是在创建交易时节点最高区块的时间戳基础上再增加60秒,可以在节点的配置文件中修改过期时间间隔,最大不能超过24小时。raw_data.data- 交易备注。raw_data.timestamp- 交易时间戳,设置交易创建时间。但实际上,该字段并非必须设置,因为包含该交易的区块时间戳才是该交易实际的链上时间戳。raw_data.fee_limit- 执行智能合约交易所允许消耗的最大能量费用,只有智能合约部署和调用交易需要设置,其他交易无需设置。signature- 发送方对交易的签名,交易有了签名就可以证明该交易来自发送方,并非恶意者所伪造。
交易的类型
TRON网络支持多种不同类型的交易,比如TRX转账交易、TRC10转账交易、创建智能合约交易、触发智能合约交易、质押TRX交易等等。
创建不同类型的交易,需要调用不同的API接口, 例如部署合约交易的类型是CreateSmartContract,需要调用wallet/deploycontractAPI来创建交易,质押TRX获取资源交易的类型是FreezeBalanceV2Contract,需要调用 wallet/freezebalancev2API来创建交易:
$ curl -X POST https://api.shasta.trongrid.io/wallet/freezebalancev2 -d '{"owner_address":"TCrkRWJuHP4VgQF3xwLNBAjVVXvxRRGpbA","frozen_balance": 2100000,"resource" : "BANDWIDTH","visible":true}' | jq
{
"visible": true,
"txID": "e54bab34838a59e85d5684e46a2e8e512cd11dfb07b35a9728adeaf3d2666fa6",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"frozen_balance": 2100000,
"owner_address": "TCrkRWJuHP4VgQF3xwLNBAjVVXvxRRGpbA"
},
"type_url": "type.googleapis.com/protocol.FreezeBalanceV2Contract"
},
"type": "FreezeBalanceV2Contract"
}
],
"ref_block_bytes": "7139",
"ref_block_hash": "d291dee525445093",
"expiration": 1646902209000,
"timestamp": 1646902151591
},
"raw_data_hex": "0a0271392208d291dee52544509340e8d39598f72f5a58080b12540a32747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e467265657a6542616c616e6365436f6e7472616374121e0a15411fafb1e96dfe4f609e2259bfaf8c77b60c535b9310a0968001180370a7939298f72f"
}更多交易类型请参考:TRON网络交易类型,更多的HTTP API请参考:HTTP API。
交易的生命周期
交易在其生命周期中会依次经历以下几个阶段:
- 交易被创建及签名
- 交易被广播到TRON网络,节点(包括产块节点)接收到交易后,对其验证并执行通过后,将其放入交易缓存池中
- 产块节点从交易缓存池中按照交易被放入的先后顺序逐一取出交易,将其打包进新区块,然后将新区块广播到TRON网络。
- 交易将被“确认”。一个交易是否被确认取决于这个交易所在的区块是否被确认,TRON的区块确认机制是某个区块产出后,19个不同的产块节点基于这个区块产出了后续区块,那么这个区块视为被确认。
创建交易
对于创建交易,有很多的库和工具可以选择,下面以tronweb创建一个TRX转账的交易为例说明如何创建交易:
const unsignedTxn = await tronWeb.transactionBuilder.sendTrx("TVDGpn4hCSzJ5nkHPLetk8KQBtwaTppnkr", 100, "TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL");
>{
"visible": false,
"txID": "9f62a65d0616c749643c4e2620b7877efd0f04dd5b2b4cd14004570d39858d7e",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"amount": 100,
"owner_address": "418840e6c55b9ada326d211d818c34a994aeced808",
"to_address": "41d3136787e667d1e055d2cd5db4b5f6c880563049"
},
"type_url": "type.googleapis.com/protocol.TransferContract"
},
"type": "TransferContract"
}
],
"ref_block_bytes": "0add",
"ref_block_hash": "6c2763abadf9ed29",
"expiration": 1581308685000,
"timestamp": 1581308626092
},
"raw_data_hex": "0a020add22086c2763abadf9ed2940c8d5deea822e5a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15418840e6c55b9ada326d211d818c34a994aeced808121541d3136787e667d1e055d2cd5db4b5f6c880563049186470ac89dbea822e"
}签名交易
发送交易前,必须由发送方使用私钥对其进行签名。
交易签名过程
- 计算交易的哈希
- 使用发送者账户的私钥对该交易哈希进行签名
- 将生成的签名结果添加到交易对象中
大多数的SDK都实现了上述的交易签名流程,并封装成接口供开发者调用,以tronweb为例,用户可以直接调用sign方法完成交易的签名。
tronweb签名示例
使用tronweb对上面创建的交易进行签名:
const signedTxn = await tronWeb.trx.sign(unsignedTxn, privateKey);
>{
"visible": false,
"txID":"9f62a65d0616c749643c4e2620b7877efd0f04dd5b2b4cd14004570d39858d7e",
"raw_data":
{
"contract": [{<-->}],
"ref_block_bytes": "0add",
"ref_block_hash": "6c2763abadf9ed29",
"expiration": 1581308685000,
"timestamp": 1581308626092
},
"raw_data_hex": "0a020add22086c2763abadf9ed2940c8d5deea822e5a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15418840e6c55b9ada326d211d818c34a994aeced808121541d3136787e667d1e055d2cd5db4b5f6c880563049186470ac89dbea822e",
"signature": [ "47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" ]
}广播交易
用户将交易发送到节点后,节点会尝试在其本地执行并验证该交易, 有效的交易将被继续广播到其他节点,无效的交易被该节点丢弃,这将有效防止垃圾交易在网络中无效广播,占用网络资源。
使用tronweb对已签名的交易进行广播:
const receipt = await tronWeb.trx.sendRawTransaction(signedTxn);
>{
"result": true,
"transaction":
{
"visible": false,
"txID": "9f62a65d0616c749643c4e2620b7877efd0f04dd5b2b4cd14004570d39858d7e",
"raw_data":
{
"contract": [{<-->}],
"ref_block_bytes": "0add",
"ref_block_hash": "6c2763abadf9ed29",
"expiration": 1581308685000,
"timestamp": 1581308626092
},
"raw_data_hex": "0a020add22086c2763abadf9ed2940c8d5deea822e5a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15418840e6c55b9ada326d211d818c34a994aeced808121541d3136787e667d1e055d2cd5db4b5f6c880563049186470ac89dbea822e",
"signature": [ "47b1f77b3e30cfbbfa41d795dd34475865240617dd1c5a7bad526f5fd89e52cd057c80b665cc2431efab53520e2b1b92a0425033baee915df858ca1c588b0a1800" ]
}
}交易确认
一个交易是否被确认取决于这个交易所在的区块是否被确认,TRON的区块确认机制是某格区块得到了19个SR的认可,即某个区块产出后, 18个不同的产块节点基于这个区块产出了后续区块,那么这个区块视为被确认。
java-tron节点提供了/walletsolidty/* 接口,方便用户查询被确认的交易,/walletsolidty/*和/wallet/*的区别是/wallet/*查询到的交易是说明该交易已经上链但不一定被确认,/walletsolidty/*查询到的交易说明该交易已经上链同时也已经被固化,也就是交易被确认。
不同的交易的确认方法有所不同:
- 系统合约交易
创建智能合约类型和触发智能合约类型以外的所有类型的交易,都属于系统合约交易。系统合约交易确认方法:- 通过
/walletsolidity/gettransactioninfobyid或者/walletsolidity/gettransactionbyidAPI能够查询到交易,即为确认
- 通过
- 智能合约交易
创建智能合约和触发智能合约交易,因为交易需要在虚拟机中执行,某些交易执行过程中会抛出一些异常,这些交易能够上链,但不代表交易是执行成功的, 有两种确认智能合约交易是否执行成功的方法:- 通过
/walletsolidity/gettransactioninfobyidAPI查询到的返回值中receipt.result等于success - 通过
/walletsolidity/gettransactionbyidAPI查询到的返回值中transaction.ret.contractRet是success
- 通过
- 内部交易
内部交易是合约中向其他普通地址或者合约地址转账的交易,首先通过/walletsolidity/gettransactioninfobyidAPI查询到内部交易记录,使用内部交易记录中的rejected字段来判断该内部交易是否被确认,但对于HTTP和GRPC接口有所不同:- HTTP接口:成功的内部交易,默认不返回
rejected字段, 失败的内部交易,rejected等于true。 - GRPC接口:成功的内部交易,
rejected字段等于false,表示这笔内部交易没有被舍弃, 失败的内部交易,rejected等于true。
- HTTP接口:成功的内部交易,默认不返回
交易费用
除了查询操作,任何上链的交易都要消耗系统资源。所有类型的交易都需要消耗带宽,智能合约部署和调用交易除了消耗带宽以外, 还需要消耗能量,当账户内的可用带宽或能量不足时,需要燃烧TRX来支付相应资源费用。除了资源费用,一些特殊交易还需支付额外的其它费用。
带宽费用
交易消耗的带宽数量等于上链的交易所占用的字节数,其中包括三部分:交易的raw_data,交易签名以及交易结果。这三部分进行protobuf序列化编码后所占的字节数即为交易所消耗的带宽数量。
当账户内可用的通过质押获取的带宽和每日免费带宽均不足时,需要燃烧TRX来支付带宽费用:
为支付带宽费用而燃烧的TRX = 交易消耗的带宽总量 * 带宽单价
当前带宽单价为1000sun。
TRX和TRC10转账交易的接收地址是一个新地址时,这笔交易会激活这个新地址,这种情况下,如果创建者账号中没有足够的通过质押获得的带宽,这笔交易将消耗 0.1TRX 作为带宽费用。
如何预估交易的带宽消耗量请参考 这里。
能量费用
智能合约部署和调用交易除了消耗带宽以外,还需要消耗能量。能量的消耗是在合约执行时逐条指令计算并扣除的,首先会消耗交易发起者质押获取的能量,如果消耗完这部分能量后还不够,会继续燃烧账户的TRX来支付交易所需的能量资源。
为支付能量费用而燃烧的TRX = (交易需要消耗的能量总量 - 调用者账户内可用的能量数量) * 能量单价
当前能量单价为 100 sun。如何预估能量消耗请参考 这里。
其它费用
对于一些特殊交易除了资源费用以外,还需要支付额外的其它费用,如果交易发起者对交易添加了备注,则需要额外支付 1TRX 的交易备注费用,如果交易使用了多重签名,即交易的签名数量大于1,则交易发起者需要额外支付 1TRX 的多签费用。此外,针对下列特定类型的交易,还需要支付相应的交易费用:
| 交易类型 | 说明 | 费用 |
|---|---|---|
| WitnessCreateContract | 申请成为超级代表候选人 | 9999 TRX |
| AssetIssueContract | 发行TRC10代币 | 1024 TRX |
| AccountCreateContract | 创建新账户,即激活账户 | 1 TRX |
| AccountPermissionUpdateContract | 更新账户权限 | 100 TRX |
| ExchangeCreateContract | 创建交易对 | 1024 TRX |
注意,对于TransferContract或TransferAssetContract类型的交易,即TRX转账、TRC10代币转账,如果目标地址未激活,则该交易也会触发创建新账户,会扣除1TRX的新账户创建费用,同时,如果交易发起者账户内通过质押获得的带宽不足时,还需要支付 0.1TRX 作为带宽费用。
内部交易
我们平常说的交易一般指由外部账户触发的交易,比如智能合约调用交易,而在智能合约函数被执行的过程中,可能还会触发其它合约函数的调用、向外部账户转移TRX/TRC10代币、或者可能还会进行质押、投票、资源代理等操作,这种发生在智能合约调用期间的交易被称为内部交易。因此内部交易是由合约账户在TVM中触发的交易。
内部交易的产生
本节以在去中心化交易所中使用USDT交换TRX为例,来说明内部交易的产生。
下面为TRX-USDT交易对合约的 tokenToTrxSwapInput 方法,它可以根据用户输入的卖出的USDT数量,为用户换取TRX:
function tokenToTrxSwapInput(uint256 tokens_sold, uint256 min_trx, uint256 deadline) public returns (uint256) {
return tokenToTrxInput(tokens_sold, min_trx, deadline, msg.sender, msg.sender);
}
function tokenToTrxInput(uint256 tokens_sold, uint256 min_trx, uint256 deadline, address buyer, address payable recipient) private nonReentrant returns (uint256) {
require(deadline >= block.timestamp && tokens_sold > 0 && min_trx > 0);
uint256 token_reserve = token.balanceOf(address(this));
uint256 trx_bought = getInputPrice(tokens_sold, token_reserve, address(this).balance);
uint256 wei_bought = trx_bought;
require(wei_bought >= min_trx);
recipient.transfer(wei_bought);
require(address(token).safeTransferFrom(buyer, address(this), tokens_sold));
emit TrxPurchase(buyer, tokens_sold, wei_bought);
emit Snapshot(buyer,address(this).balance,token.balanceOf(address(this)));
return wei_bought;
}
我们可以看到该合约方法中一共有四处代码涉及到触发其它合约或者为外部账户转账,分别为:
- 第7行:
token.balanceOf(address(this)),用于查询本合约的USDT余额 - 第11行:
recipient.transfer(wei_bought),用于给交换者账户转账TRX - 第13行:
address(token).safeTransferFrom(buyer, address(this), tokens_sold)),用于从交换者账户中转移USDT到本合约中 - 第15行:
token.balanceOf(address(this)),用于查询本合约的USDT余额
以上四处代码分别对应了通过 TRONSCAN 或者通过 API 接口查询到的内部交易。
内部交易的用处
内部交易可以为用户提供一些重要信息,比如:
- 失败交易定位 - 如果内部交易失败,则整个交易将失败。通过内部交易可以达到通知用户故障点的确切位置的目的,有助于快速定位并解决问题。
- 智能合约监控 - 您部署的智能合约可以与其他合约进行交互。通过内部交易可以了解合约何时与哪个合约进行了交互,以达到监控智能合约的目的。
- 智能合约分析 - 由于内部交易可能很复杂,通过查看智能合约执行的内部交易数量,您可以大概了解该合约的性能。
- 批量交易 - 向多个目的地址批量发送交易(如批量转账 TRX)时,使用内部交易能更便捷、安全地确保代币准确送达。
内部交易的存储
内部交易的用处很多,可以指导和告知用户交易的执行情况,但节点默认不保存内部交易信息,需要手动通过节点配置文件开启:
vm = {
...
saveInternalTx = true
saveFeaturedInternalTx = true
...
}
saveInternalTx:是否支持内部交易saveFeaturedInternalTx:在saveInternalTx开启的情况下,是否保存Stake2.0相关内部交易
内部交易存储配置项开启后,重启节点,从重启时刻开始,节点将保存其内部交易,用户可以根据外层交易的交易ID来查看其内部交易,不支持直接通过内部交易的hash来查看内部交易详情。 通过gettransactioninfobyid API可以查询一笔交易中的内部交易。
内部交易的示例
节点保存的内部交易中包含如下信息:
hash:内部交易的哈希值caller_address:调用者地址transferTo_address:调用的合约地址或者接收TRX/TRC10代币的账户地址callValueInfo.callValue:转账的TRX/TRC10代币的数量callValueInfo.tokenId:转账的TRC10 name或者id;转账TRX时,该字段为空。note:指令类型,比如call、create、 suicide、freezeBalanceV2ForEnergy、freezeBalanceV2ForBandwidth、unfreezeBalanceV2ForBandwidth等等rejected:内部交易是否执行成功,true为执行失败extra:目前主要用于保存投票的情况,以json格式记录投票的SR及其票数
下面我们根据各个示例来看内部交易包含的信息:
1. 智能合约调用其它智能合约方法
这里有一个示例,该交易是一个外部地址调用了"TQn9Y...."合约,"TQn9Y...."合约中又调用了"TR7NHq...."合约:
{
"id": "50e6dd05c37b8666cf4a689fe6c0d52053b76b53d8649b256e6b9dca8c9df098",
......
"internal_transactions": [
{
"hash": "380f4d87271b83afcf5e867271ee2d30b36c19d3eeb15a043477bce7fd5b2079",
"caller_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"transferTo_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"callValueInfo": [
{}
],
"note": "63616c6c"
},
.......
]
}
上述内部交易的包含的信息如下:
internal_transactions.caller_address是调用者地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address是合约中调用的另外一个合约的地址internal_transactions.callValueInfo本例中在调用其它合约时没有通过value传入TRX/TRC10 代币,因此该字段值为空。如果在合约调用其它合约函数时附带了value信息,则将通过该字段体现出来internal_transactions.note是指令说明,为Hex格式,将其转换为字符串后即可得到明文的操作信息,本例为call
2. 智能合约向外部账户转账 TRX
这里有一个示例,该交易是一个外部地址调用了"TQn9Y...."合约,"TQn9Y...."合约中又向"TQnpn...."地址转入了TRX:
{
"id": "50e6dd05c37b8666cf4a689fe6c0d52053b76b53d8649b256e6b9dca8c9df098",
......
"internal_transactions": [
......
{
"hash": "f47fede2a45e722e6406421d0df16142e159ae7404525de5a595f4fc0c357e26",
"caller_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"transferTo_address": "TQnpnLZJYMzH5xku535rAiYTnqYXTDTEHQ",
"callValueInfo": [
{
"callValue": 4514968563
}
],
"note": "63616c6c"
},
......
]
}
internal_transactions.caller_address是调用者地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address是转账TRX的目标地址internal_transactions.callValueInfo[0].callValue是转账TRX数额,单位为suninternal_transactions.note是指令说明,为Hex格式,将其转换为字符串后即可得到明文的操作信息,本例为call
3. 智能合约向外部账户转账 TRC10 代币
TRC10转账与TRX转账基本相同,只在如下两个字段有所不同:
internal_transactions.callValueInfo[0].callValue是转账的TRC10代币数额。internal_transactions.callValueInfo[0].tokenId是转账的TRC10 name或者id。由于第14号委员会提议允许通证同名,因此,在该提议生效前(5537806之前的区块),该字段表示转账TRC10的代币名称,在该提议生效后(5537806以及之后的区块),该字段表示转账TRC10的代币ID。
4. 智能合约质押TRX
这里有一个示例,该交易是一个外部地址调用了"TU8Mb...."合约,"TU8Mb...."合约中又进行了质押操作,质押1000TRX以获取能量:
{
"id": "9d25a4fe417e0c7540cc5c5841e1d8c9215aec556d9b06e18910ed8b5088f0d8",
......
"internal_transactions": [
{
"hash": "a3a4d666e7bf0729bbd8b5e5ad7afb7f8dd20191e7298ea9dbd17af345c96ed5",
"caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
"transferTo_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
"callValueInfo": [
{
"callValue": 1000000000
}
],
"note": "667265657a6542616c616e63655632466f72456e65726779"
}
]
}
internal_transactions.caller_address是质押发起者地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address是质押资源接收地址,也就是质押发起者地址,即该合约地址internal_transactions.callValueInfo[0].callValue是质押的TRX金额(单位为sun)internal_transactions.note是指令说明,为Hex格式,将其转换为字符串后即可得到明文的操作信息。本例中为freezeBalanceV2ForEnergy,表示合约质押TRX以获取能量。如果是合约质押获取带宽,则该字段值为freezeBalanceV2ForBandwidth
5. 智能合约解质押TRX
这里有一个示例,该交易是一个外部地址调用了"TU8Mb...."合约,"TU8Mb...."合约中又进行了解质押操作,解锁为获取带宽而质押的100TRX:
{
"id": "dc110091fbd1568f8b264f287c7e0896d1afaf47b906a9e684fd17d57c7a1151",
......
"internal_transactions": [
{
"hash": "16f73bdad5e9f984e082909b1028fff0b9865952131e681ca887446f8ec89918",
"caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
"transferTo_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
"callValueInfo": [
{
"callValue": 100000000
}
],
"note": "756e667265657a6542616c616e63655632466f7242616e647769647468"
}
]
}
internal_transactions.caller_address是解质押发起地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address是解锁的质押本金接收地址,即外部地址直接调用的合约地址internal_transactions.callValueInfo[0].callValue是解质押的TRX金额(单位为sun)internal_transactions.note是指令说明,本例中为unfreezeBalanceV2ForBandwidth,表示合约解锁为获取带宽而质押的TRX。如果是合约解锁为获取能量而质押的TRX,则该字段值为unfreezeBalanceV2ForEnergy
6. 智能合约为其它账户代理资源
这里有一个示例,该交易是一个外部地址调用了"TU8Mb...."合约,"TU8Mb...."合约中又进行了资源代理操作,它将500000000sun的能量份额代理给了"TUznH...."地址:
{
"id": "342daa21f8865786295c45bb80e2f257740091e4e1a3a546b90daa51bcbcbd18",
......
"internal_transactions": [
{
"hash": "58382a79c3af68c472383580309a81a9322e7520a48b6463917ba9219ca32a7d",
"caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
"transferTo_address": "TUznHJfHe6gdYY7gvWmf6bNZHuPHDZtowf",
"callValueInfo": [
{
"callValue": 500000000
}
],
"note": "64656c65676174655265736f757263654f66456e65726779"
}
]
}
internal_transactions.caller_address是资源代理地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address是资源接收地址internal_transactions.callValueInfo[0].callValue是代理质押的TRX数额(单位为sun)internal_transactions.note是指令说明,本例中为delegateResourceOfEnergy,表示代理能量资源操作。如果是合约代理带宽,则该字段值为delegateResourceOfBandwidth
7. 智能合约取消为其它账户的资源代理
这里有一个示例,该交易是一个外部地址调用了"TU8Mb...."合约,"TU8Mb...."合约中又进行了取消资源代理操作,它取消了为"TUznH...."地址代理的200000000sun能量份额:
{
"id": "aa3961ffb0781d8b66d5e22368e92708135dac9c81eac1e2adcaa8546d729bc8",
......
"internal_transactions": [
{
"hash": "1a8524704098770d9c6535e1112d1fb91855363c8366c93810f3cb56e8ee12bf",
"caller_address": "TU8MbhYhurKv4T3xAHQKZCeP4DtFCmWLMt",
"transferTo_address": "TUznHJfHe6gdYY7gvWmf6bNZHuPHDZtowf",
"callValueInfo": [
{
"callValue": 200000000
}
],
"note": "756e44656c65676174655265736f757263654f66456e65726779"
}
]
}
internal_transactions.caller_address是资源代理地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address是资源接收地址,即取消为该地址的资源代理internal_transactions.callValueInfo[0].callValue是取消代理的TRX数额(单位为sun)internal_transactions.note是指令说明,本例中为unDelegateResourceOfEnergy,表示取消能量资源代理操作。如果是合约取消带宽资源代理,则该字段值为unDelegateResourceOfBandwidth
8. 智能合约为超级代表投票
这里有一个示例,该交易是一个外部地址调用了"TNaDY...."合约,"TNaDY...."合约中又进行了投票操作,为超级代表"TUoHa...."和"TUznH...."分别投票200和400:
{
"id": "58506325f692eee0bd730d97a0086f8b0c50e8aa5392b9e4b0edd5fb0916a718",
......
"internal_transactions": [
{
"hash": "792b26cb6fbd1c92030721c62f7fd14522a94f412e04b05442d78e1ce743c9f4",
"caller_address": "TNaDYZaXEpL1LY8Uk4LtGTwwQrGzXTwss9",
"callValueInfo": [
{}
],
"note": "766f74655769746e657373",
"extra": "{\"votes\":[{\"vote_address\":\"TUoHaVjx7n5xz8LwPRDckgFrDWhMhuSuJM\",\"vote_count\":200},{\"vote_address\":\"TUznHJfHe6gdYY7gvWmf6bNZHuPHDZtowf\",\"vote_count\":400}]}"
}
],
......
}
internal_transactions.caller_address:是为超级代表投票的地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address:对于合约投票交易,该字段值为空,所以在返回结果中不显示该字段internal_transactions.callValueInfo: 对于合约投票交易,该字段值为空数组internal_transactions.note:是指令说明,本例中为voteWitness,表示为超级代表投票操作internal_transactions.extra:投票详情,以JSON格式记录投票的SR及其票数:votes[i].vote_address为SR地址,votes[i].vote_count为票数
9. 智能合约提取奖励
这里有一个示例,该交易是一个外部地址调用了"TNaDY...."合约,"TNaDY...."合约中又进行了提取奖励操作,提取了443803418sun的奖励:
{
"id": "8dc24b5ce1399b553cd173529e77b22172d9abf31e9f50dd32c473bcc5234b71",
......
"internal_transactions": [
{
"hash": "e5b047a4a3d64407c93a9e667a083fe52c52b24e859e3a44488249436e79c8d4",
"caller_address": "TNaDYZaXEpL1LY8Uk4LtGTwwQrGzXTwss9",
"transferTo_address": "TNaDYZaXEpL1LY8Uk4LtGTwwQrGzXTwss9",
"callValueInfo": [
{
"callValue": 443803418
}
],
"note": "7769746864726177526577617264"
}
]
}
internal_transactions.caller_address:是提取奖励的地址,即外部地址直接调用的合约地址internal_transactions.transferTo_address:是接收奖励的地址,即外部地址直接调用的合约地址internal_transactions.callValueInfo[0].callValue: 提取的TRX奖励数额,单位为suninternal_transactions.note:是指令说明,本例中为withdrawReward,表示提取奖励
Updated about 2 months ago