Application Binary Interface
The Application Binary Interface (ABI) is a data encoding scheme for working with smart contracts. The types defined in the ABI are the same as those you encounter when writing smart contracts with Solidity.
Using ABI in Trident
The abi package in Trident includes libraries to encode/decode ABIs. Take calling function totalSupply() public view returns (uint256) function as an example to illustrate how to interact with a contract using ABI
// 1. Define function parameters (empty for totalSupply)
List<Type> inputParameters = Collections.emptyList();
// 2. Create function and encode
Function function = new Function(
"totalSupply", // Function name
inputParameters, // Function input parameters
Arrays.asList(new TypeReference<Uint256>() {}) // Function output parameters
);
String encodedHex = FunctionEncoder.encode(function);
// 3. Call the contract
TransactionExtention txnExt = client.triggerConstantContract(
ownerAddress, // Caller address
contractAddress, // Contract address
encodedHex // Encoded function call
);
// 4. Decode the result
String result = Numeric.toHexString(txnExt.getConstantResult(0).toByteArray());
BigInteger totalSupply = (BigInteger) FunctionReturnDecoder.decode(
result,
function.getOutputParameters()
).get(0).getValue();
// For tokens with 18 decimals (like JST), the result might be:
// 9900000000000000000000000000
Type Matching
The parameter types in your code must exactly match the function definition in the smart contract. For example:
// In smart contract
function transfer(address _to, uint _value) public returns (bool) // uint is alias for uint256
// In Java code - Correct ✓
List<Type> params = Arrays.asList(
new Address("TRxxxxxxxxxxxxxxxxxxxxxxxxxxx"), // address type
new Uint256(1000000) // uint256 type
);
// In Java code - Wrong ✗
List<Type> params = Arrays.asList(
new Utf8String("TRxxxxxxxxxxxxxxxxxxxxxxxxxxx"), // wrong type for address
new Int256(1000000) // wrong type for uint
);
For TRC10 token, use Uint256 even if the contract parameter is defined as trcToken:
// In Java code
List<Type> params = Arrays.asList(
new Address("TRxxxxxxxxxxxxxxxxxxxxxxxxxxx"), // address _to
new Uint256(1000016), // trcToken _id
new Uint256(1000000) // uint256 _amount
);
Using incorrect types will result in transaction failure or unexpected behavior.
Struct Support (ABI v2)
Trident supports ABI v2: structs (Solidity tuple types), nested structs, arrays of structs and nested arrays can all be encoded and decoded.
Map a Solidity struct to a Java class by extending StaticStruct (all fields are fixed-size types) or DynamicStruct (contains at least one dynamic field such as string, bytes or a dynamic array), and pass the fields to the super constructor in declaration order:
// In smart contract
struct MarketParams {
address loanToken;
address collateralToken;
address oracle;
address irm;
uint256 lltv;
}
import org.tron.trident.abi.datatypes.Address;
import org.tron.trident.abi.datatypes.StaticStruct;
import org.tron.trident.abi.datatypes.generated.Uint256;
public class MarketParams extends StaticStruct {
public MarketParams(Address loanToken, Address collateralToken,
Address oracle, Address irm, Uint256 lltv) {
super(loanToken, collateralToken, oracle, irm, lltv);
}
}
A struct class works like any other Type:
- Encode: pass an instance as a function parameter to
FunctionEncoder.encode, or encode it standalone withTypeEncoder.encode(struct)— for example to computekeccak256(abi.encode(struct))identifiers. - Decode: reference the class with
new TypeReference<MarketParams>() {}inFunctionReturnDecoder.decode, and the decoder instantiates it through the constructor above.
Structs nest naturally: a DynamicStruct can contain a StaticStruct field, and DynamicArray<SomeStruct> handles arrays of structs.
For complete, runnable walkthroughs decoding and re-encoding real mainnet transactions of JustLend V2 and SunSwap V4 with structs, see Complex ABI Examples.
Packed Encoding
TypeEncoder.encodePacked(type) implements Solidity's abi.encodePacked — values are concatenated without padding, as commonly used for hash-based signatures and commitments.