Develop a smart contract on TRON smartly to optimize energy usage

When writing smart contracts, especially on networks like TRON, it’s crucial to consider energy optimization techniques. Energy costs money—so the less energy your contract consumes, the more cost-effective it is for you and your users. In this tutorial, we’ll cover a series of best practices and patterns to help you optimize energy usage and write more efficient Solidity code.


  1. Use calldata Instead of memory for Function Parameters when possible
    Concept:
    Function parameters that are arrays or strings can be declared as memory or calldata. Declaring them as calldata is often cheaper because calldata parameters are read-only references directly to the call data, rather than allocating new memory. One limitation is that you cannot modify a calldata parameter inside the function, unlike memory parameters.
    Why It Saves Energy:
    calldata reduces the amount of copying and storage needed, as it references the input data directly.
    Note: In Solidity, calldata is only valid for parameters of external functions.
    Example:


  1. Pack Variables to Optimize Storage
    Concept:
    Storage in Solidity is organized in 32-byte slots. Multiple smaller variables (like uint8, bool) can be packed into a single 32-byte slot if they are declared consecutively. By carefully ordering variables, you reduce the total number of storage slots needed, directly saving energy.
    Why It Saves Energy:
    Each storage slot costs energy to read and write. Fewer storage slots used = lower energy costs.
    Example:


  1. Delete Unused Variables Rather Than Setting to Zero
    Concept:
    When a variable is no longer needed, use delete variableName; instead of assigning it to zero. The delete operation resets the variable to its default value—zero for numeric types—and may result in an energy refund. In contrast, just setting the variable to zero still consumes energy without offering this refund.
    Why It Saves Energy:
    Storage refunds are given when you clear storage. Using delete can be slightly more energy-efficient.
    Example:

  1. Don’t Shrink Variables Without Need
    Concept:
    If you’re not packing variables together, using smaller data types (like uint8 or uint128) does not necessarily save energy. In fact, sometimes using full uint256 is cheaper because the TVM operates on 256-bit words natively. Also, converting between smaller and larger types can add overhead.
    Why It Saves Energy:
    Using the default uint (which is uint256) can avoid unnecessary conversion instructions and is often simpler and cheaper unless you’re explicitly packing variables.
    Example:


  1. Use Events Instead of On-Chain Storage When Possible
    Concept:
    If you want to record some information for later reference, but don’t need to read it back on-chain, using events is cheaper than using on-chain storage. Events are stored in the transaction logs which are cheaper and don’t consume permanent storage space.
    Why It Saves Energy:
    On-chain storage is the most expensive operation in Solidity. Events, while still costing some energy, are far cheaper than storage writes.
    Example:

  1. Use Libraries for Repeated Code
    Concept:
    If you have multiple contracts using the same math functions, put these functions in a library and link the library to the contracts. This reduces duplicate code and potentially saves energy if the function is reused many times.
    Why It Saves Energy:
    Libraries can help centralize code, and when deployed once, you don’t need to redeploy or replicate code multiple times.
    Note: Whether this saves energy depends on your usage pattern. If you have many contracts calling the same code, a library can be beneficial.
    Example:


  1. Short-Circuiting in Boolean Operations
    Concept:
    In Solidity, the && and || operators will stop evaluating as soon as they know the final outcome. This is known as 'short-circuiting.
    Why It Saves Energy:
    By placing the condition that most likely returns false first in an &&, or the condition that likely returns true first in an ||, you minimize unnecessary function calls.
    Example1:

Example2:


  1. Avoid Assignments Unless Needed
    Concept:
    Initializing variables or assigning values that are never used wastes energy. Only assign if you actually need the value.
    Why It Saves Energy:
    Each assignment costs energy. Avoiding unnecessary assignments reduces energy usage.
    Example:


  1. Minimize Operations on Storage Variables Inside Loops
    Concept:
    Reading and writing storage variables is expensive. Doing it inside a loop is even more costly. Instead, load the value into a memory variable, work with it, and then write it back once.
    Why It Saves Energy:
    Fewer storage operations mean lower energy usage.
    Example:


  1. Use Fixed-Size Rather Than Dynamic-Size Arrays Where Possible
    Concept:
    Fixed-size arrays are cheaper to handle than dynamic arrays, as dynamic arrays involve additional overhead for managing size and potential resizing.
    Why It Saves Energy:
    Less overhead for managing array length and resizing means fewer operations and hence lower energy.
    Example:

  1. Prefer mapping Over Arrays If Possible
    Concept:
    mapping lookups are cheaper than array operations in some cases, especially if you need to store sparse data or just keyed lookups without iteration.
    Why It Saves Energy:
    Mappings provide constant-time lookups without maintaining indexing overhead.
    Example:

  1. Use bytes Instead of string Where Possible
    Concept:
    Strings are expensive because they are essentially dynamic arrays of bytes. If you don’t need human-readable text and only store binary data, use bytes. Even if you need to store ASCII text, if it’s processed as raw data, bytes may be more optimal.
    Why It Saves Energy:
    Working directly with bytes removes unnecessary conversion and formatting layers. This streamlined approach can lower processing requirements, which in turn reduces energy consumption over time.
    Example:

  1. Use external or internal Over public When Possible
    Concept:
    Functions marked as public can be called both internally and externally. If your function is never called internally, use external. If your function is never called externally, use internal. External functions are sometimes cheaper when called from outside the contract, as they do not require a wrapper function to be generated.
    Why It Saves Energy:
    External/internal function calls can save energy by allowing the TVM to read directly from calldata without copying arguments into memory.
    Example:


6 Likes