通过 HTTP API 部署与调用智能合约
使用原始 HTTP API 调用部署和调用 TRON 智能合约——这是需要完全控制交易构造时使用的 底层路径。
前置阅读
本文将详细介绍部署与调用 TRON 智能合约的底层原始 HTTP API 接口路径。虽然大多数开发者在日常开发中会使用更高层封装的 SDK 工具(如 TronWeb、TronBox 或 TronIDE),但这些工具在底层最终都会落到下文所列出的这些 API 节点上。当您需要构建自定义的开发工具、从非 JavaScript 环境中集成 TRON 合约,或者需要对交易结构拥有完全的精细控制时,直接调用这些底层 HTTP API 将是最佳选择。
智能合约部署
部署智能合约的核心逻辑是创建一笔 CreateSmartContract 类型的系统交易。您可以通过调用全节点的 API 接口 wallet/deploycontract 来创建该交易。交易成功构建后,还需要经过私钥签名,方能广播至网络中:
BASE_URL=https://api.shasta.trongrid.io # 示例——替换为任意 TRON 节点(TronGrid、第三方或自建)
curl --request POST \
--url ${BASE_URL}/wallet/deploycontract \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"owner_address": "41D1E7A6BC354106CB410E65FF8B181C600FF14292",
"abi": "[{\"constant\":false,\"inputs\":[{\"name\":\"key\",\"type\":\"uint256\"},{\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"key\",\"type\":\"uint256\"}],\"name\":\"get\",\"outputs\":[{\"name\":\"value\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",
"bytecode": "608060405234801561001057600080fd5b5060de8061001f6000396000f30060806040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631ab06ee58114604d5780639507d39a146067575b600080fd5b348015605857600080fd5b506065600435602435608e565b005b348015607257600080fd5b50607c60043560a0565b60408051918252519081900360200190f35b60009182526020829052604090912055565b600090815260208190526040902054905600a165627a7a72305820fdfe832221d60dd582b4526afa20518b98c2e1cb0054653053a844cf265b25040029",
"fee_limit": 100000000,
"origin_energy_limit": 100000,
"name": "SomeContract",
"call_value": 0,
"consume_user_resource_percent": 100
}
'返回的交易构造结果(派生字段已缩写):
{
"visible": false,
"txID": "<transaction-id>",
"contract_address": "<contract-address-hex>",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"owner_address": "41d1e7a6bc354106cb410e65ff8b181c600ff14292",
"new_contract": {
"bytecode": "608060405234801561001057600080fd5b5060de8061001f6000396000f30060806040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631ab06ee58114604d5780639507d39a146067575b600080fd5b348015605857600080fd5b506065600435602435608e565b005b348015607257600080fd5b50607c60043560a0565b60408051918252519081900360200190f35b60009182526020829052604090912055565b600090815260208190526040902054905600a165627a7a72305820fdfe832221d60dd582b4526afa20518b98c2e1cb0054653053a844cf265b25040029",
"consume_user_resource_percent": 100,
"name": "SomeContract",
"origin_address": "41d1e7a6bc354106cb410e65ff8b181c600ff14292",
"abi": {
"entrys": [
{
"inputs": [
{
"name": "key",
"type": "uint256"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "set",
"stateMutability": "Nonpayable",
"type": "Function"
},
{
"outputs": [
{
"name": "value",
"type": "uint256"
}
],
"constant": true,
"inputs": [
{
"name": "key",
"type": "uint256"
}
],
"name": "get",
"stateMutability": "View",
"type": "Function"
}
]
},
"origin_energy_limit": 100000
}
},
"type_url": "type.googleapis.com/protocol.CreateSmartContract"
},
"type": "CreateSmartContract"
}
],
"ref_block_bytes": "0a49",
"ref_block_hash": "975853d6629c8702",
"expiration": 1652153760000,
"fee_limit": 100000000,
"timestamp": 1652153701556
},
"raw_data_hex": "<abridged>"
}示例中的 fee_limit 为 100,000,000 sun(100 TRX),仅作为该测试网示例的费用上限,并不是固定部署成本。部署前应先估算 Energy,通过 wallet/getchainparameters 查询当前 getEnergyFee 完成换算,并确保不超过 getMaxFeeLimit。
wallet/deploycontract 只负责构造未签名交易。响应中的 txID、contract_address 和 raw_data 不代表合约已经部署成功;客户端仍需签名并调用 wallet/broadcasttransaction。广播后使用 wallet/gettransactioninfobyid 查询 receipt,确认执行成功后,预计算的 contract_address 才是可用的链上合约地址。
虽然 TRON 网络中各类区块链交易的底层交易结构在本质上是完全相同的,但它们的核心区别在于 raw_data 数据体中 contract.parameter.value 字段所携带的具体参数。
在智能合约部署交易中,contract.parameter.value 包含以下核心数据:
owner_address—— 交易发起方的账户地址,即该合约的部署方地址。new_contract—— 待部署的智能合约的完整详细配置:origin_address—— 智能合约所有者的账户地址。contract_address—— 系统预分配的智能合约部署地址。abi—— 智能合约的 ABI 接口定义。bytecode—— 编译生成的合约二进制字节码。call_value—— 部署时向合约内充入的原生 TRX 数量。consume_user_resource_percent—— 用户能耗分摊比例,即调用者分摊能量费用的百分比。name—— 智能合约的名称。origin_energy_limit—— 部署者为该合约设定的单次交易代付能量上限,单位为能量(无单位整数,与fee_limit的 sun 单位无关)。
call_token_value—— 部署时随交易向新合约内注入的 TRC-10 Token数量。token_id—— 注入的 TRC-10 Token对应的唯一数字 ID。
智能合约调用与查询
调用写入方法:triggersmartcontract
triggersmartcontract调用智能合约中会修改状态的写操作函数,需要创建一笔 TriggerSmartContract 类型的系统交易。您可以通过调用全节点的 API 接口 wallet/triggersmartcontract 来构建此交易。交易创建完成后,同样需要经过本地签名并广播至全网。
BASE_URL=https://api.shasta.trongrid.io # 示例——替换为任意 TRON 节点(TronGrid、第三方或自建)
curl -X POST ${BASE_URL}/wallet/triggersmartcontract -d '{
"contract_address":"419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector":"transfer(address,uint256)",
"parameter":"00000000000000000000004115208EF33A926919ED270E2FA61367B2DA3753DA0000000000000000000000000000000000000000000000000000000000000032",
"fee_limit":100000000,
"call_value":0,
"owner_address":"41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}'参数详细说明:
contract_address—— 目标智能合约的链上地址。owner_address—— 发起此笔调用的账户地址。function_selector—— 合约中待触发的目标函数签名(函数选择器)。parameter—— 经 ABI 编码后的函数入参数据。例如在本例中,该方法需要传入两个编码后的参数(分别对应address和uint256类型)。有关如何对参数进行转换,请参阅参数的编码与解码。fee_limit—— 调用方该笔交易的能耗预算上限,以 sun 为单位。关于其与实际能量的折算关系,请参阅 FeeLimit 与能量成本管理。call_value—— 随该笔调用交易发送给目标智能合约的 TRX 数量。
执行上述命令后,将返回包含待签名交易数据的 JSON 构造结果:
{
"result": {
"result": true
},
"transaction": {
"visible": false,
"txID": "d2ce86097df40287ad45ebc67f0d546ee98c2d7cd7c101e4d4d5b0c8a752d900",
"raw_data": {
"contract": [{
"parameter": {
"value": {
"data": "a9059cbb00000000000000000000004115208ef33a926919ed270e2fa61367b2da3753da0000000000000000000000000000000000000000000000000000000000000032",
"owner_address": "41977c20977f412c2a1aa4ef3d49fee5ec4c31cdfb",
"contract_address": "419e62be7f4f103c36507cb2a753418791b1cdc182"
},
"type_url": "type.googleapis.com/protocol.TriggerSmartContract"
},
"type": "TriggerSmartContract"
}],
"ref_block_bytes": "1c51",
"ref_block_hash": "74912b480b7b887c",
"expiration": 1652169501000,
"fee_limit": 100000000,
"timestamp": 1652169442098
},
"raw_data_hex": "0a021c51220874912b480b7b887c40c8d2e7e78a305aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541977c20977f412c2a1aa4ef3d49fee5ec4c31cdfb1215419e62be7f4f103c36507cb2a753418791b1cdc1822244a9059cbb00000000000000000000004115208ef33a926919ed270e2fa61367b2da3753da000000000000000000000000000000000000000000000000000000000000003270b286e4e78a30900180c2d72f"
}
}其中 result.result: true 只表示交易构造和节点预校验成功,不表示合约调用已经执行。必须继续完成本地签名与广播,并通过 wallet/gettransactioninfobyid 检查 receipt,才能判断链上执行是否成功。
合约调用交易中 contract.parameter.value 包含以下内容:
owner_address—— 发起调用的账户地址。contract_address—— 目标智能合约的地址。data—— 经过 ABI 规则编码后的完整调用数据:前 4 个字节为函数选择器(由函数签名执行 Keccak-256 哈希后截取前 4 字节所得,用于供虚拟机 TVM 寻址定位对应的方法),后续字节为经填充对齐后的参数列表。有关详细规则,请参阅参数的编码与解码。call_value—— 随该交易随附给智能合约的 TRX 数量。token_id—— 随交易附带的 TRC-10 Token ID。call_token_value—— 随交易向目标合约发送的 TRC-10 Token数量。
调用只读方法:triggerconstantcontract
triggerconstantcontract对于智能合约中未修改状态的只读查询方法(即 view 或 pure 修饰的函数),您可以通过调用全节点的 API 接口 wallet/triggerconstantcontract 进行触发。由于此类调用纯属本地模拟查询,无需在区块链上达成共识,因此无需对其进行交易签名,也不必广播至全网:
BASE_URL=https://api.shasta.trongrid.io # 示例——替换为任意 TRON 节点(TronGrid、第三方或自建)
curl -X POST ${BASE_URL}/wallet/triggerconstantcontract -d '{
"contract_address":"419E62BE7F4F103C36507CB2A753418791B1CDC182",
"function_selector":"balanceOf(address)",
"parameter":"000000000000000000000041977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB",
"owner_address":"41977C20977F412C2A1AA4EF3D49FEE5EC4C31CDFB"
}'参数详细说明:
contract_address—— 目标智能合约地址。owner_address—— 发起查询请求的模拟账户地址。function_selector—— 待查询的目标合约函数签名。parameter—— 传入查询函数的 ABI 编码参数。关于如何对参数进行转义,请参阅参数的编码与解码。
返回结果:
{
"result": {
"result": true
},
"constant_result": ["0000000000000000000000000000000000000000000000000000000430e1b700"],
"transaction": {
"ret": [{}],
"visible": false,
"txID": "7f47212aed2fdab232195feece54fc302bde2ce379e92ffd0d0e95206ce7a3bb",
"raw_data": {
"contract": [{
"parameter": {
"value": {
"data": "70a08231000000000000000000000041977c20977f412c2a1aa4ef3d49fee5ec4c31cdfb",
"owner_address": "41977c20977f412c2a1aa4ef3d49fee5ec4c31cdfb",
"contract_address": "419e62be7f4f103c36507cb2a753418791b1cdc182"
},
"type_url": "type.googleapis.com/protocol.TriggerSmartContract"
},
"type": "TriggerSmartContract"
}],
"ref_block_bytes": "5ab1",
"ref_block_hash": "f24f075df912f43e",
"expiration": 1590382815000,
"timestamp": 1590382762536
},
"raw_data_hex": "0a025ab12208f24f075df912f43e4098cecfd1a42e5a8e01081f1289010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412540a1541977c20977f412c2a1aa4ef3d49fee5ec4c31cdfb1215419e62be7f4f103c36507cb2a753418791b1cdc182222470a08231000000000000000000000041977c20977f412c2a1aa4ef3d49fee5ec4c31cdfb70a8b4ccd1a42e"
}
}constant_result—— 合约函数的只读查询结果列表。本例中返回的值为原始十六进制格式,代表uint256类型的余额。有关如何将此十六进制解码为十进制数值,请参阅参数的编码与解码。
使用 data 字段调用
除了直接输入函数选择器和参数外,您还可以严格按照 Solidity 的 ABI 编码规范,将函数选择器与其入参编码拼装为一个完整的十六进制大字符串,并将其直接作为 data 字段传入。
以调用一个标准的 TRC-20 合约中的转账函数 transfer 为例,其标准的函数签名为 transfer(address,uint256)。
假设我们需要向接收方地址 TJRabPrwbZy45sbavfcjinPJC18kjpRTv8 转账 100 单位的Token:
- 确定函数选择器 —— 对
transfer(address,uint256)函数签名字符串执行 Keccak-256 哈希计算,取哈希值的前 4 个字节。计算结果为a9059cbb。 - 进行参数编码:
- 目标地址
TJRabPrwbZy45sbavfcjinPJC18kjpRTv8:首先转换为底层以41开头的 21 字节十六进制格式(415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb),然后在其高位(左侧)补 11 字节零以对齐至 32 字节。 - 转账数量
100:转换为十六进制值64,并在高位补零以对齐至 32 字节。
- 目标地址
- 拼装数据体 —— 将上述计算所得的函数选择器、补零对齐后的地址参数、补零对齐后的Token数量参数,顺次连接拼接在一起,即可组成最终的
data属性值:
a9059cbb0000000000000000000000415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb0000000000000000000000000000000000000000000000000000000000000064
完整调用:
BASE_URL=https://api.shasta.trongrid.io # 示例——替换为任意 TRON 节点(TronGrid、第三方或自建)
curl --request POST \
--url ${BASE_URL}/wallet/triggersmartcontract \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"owner_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g",
"contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
"data": "a9059cbb0000000000000000000000415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb0000000000000000000000000000000000000000000000000000000000000064",
"fee_limit": 1000000000,
"call_value": 0,
"visible": true
}
'返回结果:
{
"result": {
"result": true
},
"transaction": {
"visible": true,
"txID": "e33c025b615a5125c8a28ec7e012a8b880c5d855f010c07dca45cb2d40609b82",
"raw_data": {
"contract": [{
"parameter": {
"value": {
"data": "a9059cbb0000000000000000000000415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb0000000000000000000000000000000000000000000000000000000000000064",
"owner_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g",
"contract_address": "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs"
},
"type_url": "type.googleapis.com/protocol.TriggerSmartContract"
},
"type": "TriggerSmartContract"
}],
"ref_block_bytes": "8e6a",
"ref_block_hash": "9858ac3fec3262ff",
"expiration": 1747130115000,
"fee_limit": 1000000000,
"timestamp": 1747130056923
},
"raw_data_hex": "0a028e6a22089858ac3fec3262ff40b8c7c7c8ec325aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541fd49eda0f23ff7ec1d03b52c3a45991c24cd440e12154142a1e39aefa49290f2b3f9ed688d7cecf86cd6e02244a9059cbb0000000000000000000000415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb000000000000000000000000000000000000000000000000000000000000006470db81c4c8ec3290018094ebdc03"
}
}相关资源
- 部署上链 —— 学习如何使用 TronIDE 或 TronBox 部署智能合约
- 与智能合约交互 —— 掌握在脚本和应用中读取状态和写入合约的方法
- 参数的编码与解码 —— 掌握如何为底层 HTTP API 接口手工编码
data数据体 - FeeLimit 与能量成本管理 —— 掌握部署与调用的能耗成本控制技巧
- 快速通道 —— 体验使用命令行工具 TronBox 在 10 分钟内完成合约部署
Updated 12 days ago