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
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:
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.