0

Problem

Whenever I call the paytest function (please see code snippet below) from javascript (please see code snippet below) i receive the below posted error message. Whether i use address.send, address.transfer or address.call, doesnt matter.Nothing works. I have plenty of test ETH on all accounts.

I use hardhat for my local blockchain.

Please help me. i am getting insane.

Solidity Code

    contract DC is ERC1155, Ownable {
    
    function paytest (address receiver, uint256 amount) public payable{
            (bool success, bytes memory _data) = payable(receiver).call{value:amount}("");
             require (success, "transaction failed");
             data=_data;
    }

    event Log(string fun, address sender, uint value, bytes data);

    fallback() external payable {
        emit Log("fallback", msg.sender, msg.value, msg.data);
    }

    receive() external payable {
        emit Log("receive", msg.sender,msg.value, "");
        
    }

Javascript File

   async function main () { // boiletplate function 
    
    
    const address = '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9'; // actual contract address
    const DC = await ethers.getContractFactory('DC');
    const dc = await DC.attach(address);
    
    const [owner, addr1, addr2] = await ethers.getSigners(); 
    await dc.connect(addr1).paytest(address,ethers.utils.parseEther("1.0"));

Error message console

C:\Users\Admin\hhtest>npx hardhat run --network localhost ./scripts/index.js
ProviderError: Error: VM Exception while processing transaction: reverted with reason string 'transaction failed'
    at HttpProvider.request (C:\Users\Admin\hhtest\node_modules\hardhat\src\internal\core\providers\http.ts:78:19)
    at GanacheGasMultiplierProvider.request (C:\Users\Admin\hhtest\node_modules\hardhat\src\internal\core\providers\gas-providers.ts:312:34)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

1 Answer 1

1

There is a small syntax error in your code. You cannot send the required ETH directly in the function like that. You have to send it in a different block under the name "value". So, instead of:

await dc.connect(addr1).paytest(address,ethers.utils.parseEther("1.0"));

Try this,

await dc.connect(addr1).paytest(address,{ value: ethers.utils.parseEther("1.0")});

Update: The other method I personally use to use convertWithDecimal() function when inputting the value of ETH. The function automatically handles the BigNumber errors.

const isInt = (n: any) => {
  return n % 1 === 0;
};

const convertWithDecimal = (value: any, decimal: any) => {
  if (value > 0) {
    if (isInt(value)) {
      value = parseInt(value);
      value = BigNumber(value).multiply(decimal);
    } else {
      value = value * decimal;
      value = toFixed(value);
      value = parseInt(value.toString().split(".")[0]);
      value = toFixed(value);
      value = BigNumber(value);
    }
    return value.toString();
  } else {
    return 0;
  }
};

const toFixed = (x: any) => {
  if (Math.abs(x) < 1.0) {
    var e = parseInt(x.toString().split("e-")[1]);
    if (e) {
      x *= Math.pow(10, e - 1);
      x = "0." + new Array(e).join("0") + x.toString().substring(2);
    }
  } else {
    var e = parseInt(x.toString().split("+")[1]);
    if (e > 20) {
      e -= 20;
      x /= Math.pow(10, e);
      x += new Array(e + 1).join("0");
    }
  }
  return x;
};

Just paste it in your JS file and when inputting ETH value, change the syntazx to this.

await dc.connect(addr1).paytest(address,{ value: convertWithDecimal(1, 10**18});
4
  • Thanks for the suggestion. it now throws another error: C:\Users\Admin\hhtest>npx hardhat run --network localhost scripts/index.js Error: invalid BigNumber value (argument="value", value={"value":{"type":"BigNumber","hex":"0x0de0b6b3a7640000"}}, code=INVALID_ARGUMENT, reason: 'invalid BigNumber value', code: 'INVALID_ARGUMENT', argument: 'value', value: { value: BigNumber { value: "1000000000000000000" } } }
    – PupSt4r
    Commented May 20, 2022 at 4:51
  • I updated the answer. Try this method. Commented May 20, 2022 at 5:16
  • This worked. I really really appreciate your help. thank you!!! What I dont understand: why do i need to supply the amount as {value:} inside my .js file? To my understanding, the {value:} is already specified inside the paytest() smartcontract function. Why do i need to do this twice? I seem to miss something very fundamental
    – PupSt4r
    Commented May 20, 2022 at 5:47
  • I am glad it worked. Whenever you create a function which accepts ETH, the ETH value is not passed in the arguments. Rather it is sent with the function, like a payload. So, in our JS file we need to mention that payload separately in the block. Mentioning how much ETH we will send along this method. Commented May 20, 2022 at 6:16

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.