0

I work on Truffle and my project is simple. contract A should transfer some ether to contract B. contract A is funded enough. In contract A, there is a function called payment that performs the transfer and uint val is its parameter that tells the function the ether value to transfer. Whenever i try the function in Truffle console the following error occurs:

Error: invalid number value (arg="val", coderType="uint256", value=1000000000000000000)

I don't know how to assign a correct value as an argument to payment function.

contract A:

pragma solidity ^0.5.12;

contract A{

    event Payment(address receiver, uint value);

    function payment(uint val) public payable returns(string memory){
        address(uint160(0xae1b77270ae418bDd72e14e842F57D9EC2DBD1d8)).transfer(val);\\Transfer to contract B
        emit Payment(0xae1b77270ae418bDd72e14e842F57D9EC2DBD1d8, val);
        return "Payment done successfully";
    }

    function() external payable{}
} 

contract B:

contract B{
    function balanceView() public view returns(uint){
        return address(this).balance;           
    }

    function() external payable{}
}

The command i tried in Truffle console:

truffle(develop)> A.deployed().then(function(ins){app=ins})
undefined
truffle(develop)> app.payment.sendTransaction(1000000000000000000)

2 Answers 2

0

Change this:

sendTransaction(1000000000000000000)

To this:

sendTransaction({value: '1000000000000000000'})
8
  • Actually, shouldn't it be val instead of value ? Commented May 15, 2020 at 12:04
  • @FlorianCastelain: No, it shouldn't. You're probably looking at function payment, which has nothing to do with all of this. And in any case, the names of input parameters in contract functions have no impact or meaning when you call those functions from an off-chain script (or from anywhere else for that matter). Commented May 15, 2020 at 12:15
  • @goodvibration: Thanks for your answer. It worked. Just a thing: if i want to set the recipient address as an argument in .sendTransaction(...) what shouls i do? As i realized payment does not need a corresponding parameter for that. Am i right?
    – Alireza
    Commented May 15, 2020 at 12:40
  • @A.Kiakojouri: You're welcome. What do you mean by "recipient"? Commented May 15, 2020 at 12:44
  • @goodvibration: I mean i want to type the address of contract B in .sendTransaction(...) on Truffle console instead i use address(uint160(0xae1b77270ae418bDd72e14e842F57D9EC2DBD1d8)).transfer(val) in contract A file.
    – Alireza
    Commented May 15, 2020 at 12:52
1

It is because of MAX_SAFE_INTEGER of JavaScript. As you can see here ,the MAX_SAFE_INTEGER constant has a value of 9007199254740991 (9,007,199,254,740,991 or ~9 quadrillion). The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers. It can only safely represent integers between -(2^53 - 1) and (2^53 - 1). alongside that, you use uint and you can't use the negative section of this interval. Thus, you are restricted more. You can solve that via:

  1. Pass a number non-out-of the MAX_SAFE_INTEGER .
  2. As @goodvibration answered, removed .payment() argument and pass your given value with .sendTransaction({value:<value>}).
4
  • An EVM uint is by default 256 bits in size. The biggest number is therefore (2^256)-1, which is 115792089237316195423570985008687907853269984665640564039457584007913129639935. Commented May 5, 2021 at 7:53
  • What is happening in the question is that it's hitting the Javascript MAX_SAFE_INTEGER limit, which is 9007199254740991. 1000000000000000000 is above this limit, so value must be passed as a string, not an integer. Commented May 5, 2021 at 7:53
  • @RichardHorrocks Thanks for your pointing. I altered the answer by your guide. Please check it.
    – Kiasha
    Commented May 5, 2021 at 8:23
  • Yep, that looks good. However, your recommendation in point 1) would restrict the user to passing values below MAX_SAFE_INTEGER into the contract, even though the contract supports much higher numbers. When considering wei values, 1 ETH has 18 decimal places :-) The way around this is to pass the large integer as a string. (This is what the code in the accepted answer is doing - notice the ' around the value.) Commented May 5, 2021 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.