Search code examples
solidityhedera-hashgraphhedera

What is the "full unit" of the native coin (HBAR) on Hedera?


In my smart contract, I would like to accept exactly 1 full HBAR unit in a payable function. The following code would work in Ethereum, by specifying 1 ether.

pragma solidity 0.8.18;

contract Example {
    function payMeOneHbar () public payable {
        require(msg.value == 1 ether, "Payment required is exactly 1 HBAR");
        /* ... other code */
    }
}

Does Hedera have the equivalent concept to 1 ether? (I cannot specify 1 hbar in Solidity, as that isn't recognised by solc.)

I tried accepting 1 HBAR and expected it would have the same function as 1 ether


Solution

  • Simply specify 100_000_000 or 10^8 in place of 1 ether, like so:

    pragma solidity 0.8.18;
    
    contract Example {
        function payMeOneHbar () public payable {
            require(msg.value == 100_000_000, "Payment required is exactly 1 HBAR");
            /* ... other code */
        }
    }
    

    Note that the absolute numerical value is different from that on Ethereum.


    Detailed explanation

    In Solidity syntax, ether is simply a constant that is equal to 10^18 (1,000,000,000,000,000,000). Ref: Solidity Lang - Ether Units

    • 1 wei = 1 wei
    • 1 gwei = 1,000,000,000 wei
    • 1 ether = 1,000,000,000,000,000,000 wei

    In Solidity syntax there is no concept of hbar, but we can use a constant value of 10^8 (100,000,000) in its place. Ref: Hedera - HBAR and Hedera Helpdesk - What are the official HBAR cryptocurrency denominations?

    • 1 Gℏ = 1,000,000,000 ℏ
    • 1 Mℏ = 1,000,000 ℏ
    • 1Kℏ = 1,000 ℏ
    • 1 ℏ = 1 ℏ
    • 1,000 mℏ = 1 ℏ
    • 1,000,000 μℏ = 1 ℏ
    • 100,000,000 tℏ = 1 ℏ

    Try it out

    You can try this out manually using the following Solidity code:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity ^0.8.18;
    
    contract NativeCoinUnits {
        // for ethereum,
        // - the "full unit" of the native coin is an ether, and
        // - the "smallest unit" is a wei
        uint256 public oneWei = 1 wei;
        bool public isOneWei = (oneWei == 1);
        uint256 public oneEther = 1 ether;
        bool public isOneEther = (oneEther == 1e18);
    
        // for hedera,
        // - the "full unit" of the native coin is an hbar, and
        // - the "smallest unit" is a tinyhbar
        uint256 public oneTinybar = 1;
        bool public isOneTinybar = (oneTinybar == 1);
        uint256 public oneHbar = 100_000_000; // note specify manually, no unit
        bool public isOneHbar = (oneHbar == 1e8);
    }
    
    

    Hot link to try this out in Remix

    ... and if you deploy it, and invoke each of the auto-generated getter functions, you should get this result:

    Remix IDE getter invocation results for the NativeCoinUnits smart contract

    As you can see, all of the isOne... boolean values are true; and all the one... unsigned integer values are equal to the constants from the reference values copied above.