Home指南API 参考手册
指南API 参考手册社区Discord博客FAQ漏洞赏金公告中心English(英文版)Log In
指南

TRON Solidity 智能合约调用合约指南

本文介绍了如何在 TRON 网络上使用 Solidity 进行智能合约之间的调用(Contract-to-Contract Calls),并提供了实际代码示例。

什么是合约调用合约?

在智能合约开发中,一个合约可以调用另一个合约来执行特定功能或获取数据。这种调用模式可提高代码复用率,实现复杂的业务逻辑,并增强系统的模块化。
在 TRON 中,智能合约调用合约是通过接口或合约地址直接调用完成的。

调用方式

通过接口调用合约

这种方式推荐使用,因为它明确了被调用合约的函数签名,增加了代码的可读性与安全性。
假设你已有合约 ContractB,需要从合约 ContractA 调用:

定义接口

// IContractB.sol
pragma solidity ^0.8.0;

interface IContractB {
    function increment(uint256 value) external returns (uint256);
}

实现调用

// ContractA.sol
pragma solidity ^0.8.0;

import "./IContractB.sol";

contract ContractA {
    address public contractBAddress;

    constructor(address _contractBAddress) {
        contractBAddress = _contractBAddress;
    }

    function callIncrement(uint256 value) public returns (uint256) {
        IContractB contractB = IContractB(contractBAddress);
        uint256 newValue = contractB.increment(value);
        return newValue;
    }
}

直接使用地址调用

在不知道合约具体接口时,或者需要动态调用时,可以直接使用合约地址。

pragma solidity ^0.8.0;

contract ContractA {
    address public contractBAddress;

    constructor(address _contractBAddress) {
        contractBAddress = _contractBAddress;
    }

    function callIncrement(uint256 value) public returns (uint256) {
        (bool success, bytes memory result) = contractBAddress.call(
            abi.encodeWithSignature("increment(uint256)", value)
        );
        require(success, "Call failed");
        return abi.decode(result, (uint256));
    }
}

给合约地址转账调用

给某个合约地址直接转账一定数量的 TRX 时,会触发目标合约的 receiverfallback 方法。

pragma solidity ^0.8.0;

contract ContractA {
    address public contractBAddress;

    constructor(address _contractBAddress) {
        contractBAddress = _contractBAddress;
    }

    function directTransfer() external payable {
        payable(contractBAddress).transfer(msg.value);
    }
}

调用合约的注意事项

  • 资源限制:调用其他合约会额外消耗能量(Energy),注意预留足够的能量资源。
  • 调用深度:Solidity 在 TRON 上的调用深度有一定限制,避免递归调用过深造成失败。
  • 错误处理:应使用 requireassert 确保调用成功,并适当处理失败情况。

示例场景

假设 ContractB 实现简单的计数器逻辑:

// ContractB.sol
pragma solidity ^0.8.0;

contract ContractB {
    uint256 public counter;

    function increment(uint256 value) external returns (uint256) {
        counter += value;
        return counter;
    }
}

通过上文 ContractA 调用 ContractBincrement 方法,实现计数器的跨合约调用。

实践部署步骤

  1. 部署 ContractB 并记录其地址。
  2. 部署 ContractA 时,构造函数参数填写 ContractB 的地址。
  3. 通过 ContractAcallIncrement 方法调用 ContractB 的方法进行测试。