0

If I have an amount less than 1 NEAR let's say .5 near, how do I convert it and store it using assemblyscript in a near protocol smart contract?

I tried to convert it to f64 first and make the arithmetic operation then convert it back to u128 like:

u128.fromF64((ONE_NEAR.toF64() * .5))

but fromF64 gives the following error

ExecutionError: 'WebAssembly trap: An arithmetic exception, e.g. divided by zero.'
John
  • 10,165
  • 5
  • 55
  • 71

2 Answers2

3

I think you are going about this the wrong way. You need to operate on yoctoNEAR instead of 0.5 NEAR.

Below examples are taken directly from the docs

https://docs.near.org/docs/api/naj-quick-reference#utils

NEAR => yoctoNEAR

// converts NEAR amount into yoctoNEAR (10^-24)

const { utils } = nearAPI;
const amountInYocto = utils.format.parseNearAmount("1");

YoctoNEAR => NEAR

// converts yoctoNEAR (10^-24) amount into NEAR

const { utils } = nearAPI;
const amountInNEAR = utils.format.formatNearAmount("1000000000000000000000000");
John
  • 10,165
  • 5
  • 55
  • 71
  • This is using JS sdk in the frontend of the dapp I need something that can convert from near to yocto in my smart contact using assembly script for example `let yocto = toYocto(.5)` //yocto should have 5*10^23 – Hamza Tahir Jun 30 '22 at 12:58
1

basically, you have to multiply the near amount (e.g. 1.25) by a large number first (e.g. 1000000) in order to preserve the fraction before you convert the number to Yocto using toYoctob128(u128.from(amount)). and after the successful conversion, you can use u128.div() (e.g. u128.div(amountInU128, u128.from(1000000))) to get the correct value.

P.S. The larger the number you multiply by first the more accurate the conversion will be but be careful not to exceed the number and u128 limit.

Here is a complete example:

Contract Class:

  nearToYocto(x: string): u128 {
    let amountBase = (parseFloat(x) * BASE_TO_CONVERT);
    return u128.div(toYoctob128(u128.from(amountBase)), u128.from(BASE_TO_CONVERT));
  }

utils:

export const BASE_TO_CONVERT = 1000000.0;

export function toYoctob128(amount: u128): u128 {
  return u128.mul(ONE_NEAR, amount)
}