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)
PupSt4r
  • 49
  • 6

1 Answers1

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});
Shubham Sharma
  • 1,188
  • 1
  • 3
  • 16
  • 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 May 20 '22 at 04:51
  • I updated the answer. Try this method. – Shubham Sharma May 20 '22 at 05: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 May 20 '22 at 05: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. – Shubham Sharma May 20 '22 at 06:16