【问题标题】:payable modifier with transfer() in solidity带有 transfer() 的支付修饰符
【发布时间】:2022-09-27 16:21:43
【问题描述】:

我正在尝试在智能合约中使用存款和提取 ETH 代币。

contract A

function deposit() public payable{
  require(msg.value >= 0, \"Value amount to be deposit\");
  withdraw(msg.value);
}

function withdraw(uint256 _amount) internal{
   uint256 amount = 2 * _amount //modifying the amount(bonus or whatsoever)
   payable(msg.sender).transfer(amount);
}

上面的sn-p就是简单的表单充提功能。 在这里存款工作正常,将帐户中的某些 ETH 存入合约地址。 在执行结束时,它调用了withdraw,但传输函数仍然接受消息值作为参数,它似乎覆盖了数量参数。我已经在 remix ide 中验证了这些交易。

有人请帮我解决这个问题吗?

    标签: ethereum solidity smartcontracts


    【解决方案1】:

    我使用 receive() 函数编辑了合约以接收 ETH。在安全帽脚本中,所有者将 100ETH 转移到合约中以模拟您的问题。编辑了合同,一切似乎都很好。

    pragma solidity ^0.8.0;
    
    import "hardhat/console.sol";
    
    contract ContractA {
        event Received(address sender, uint value);
    
        receive() external payable {
            emit Received(msg.sender, msg.value);
        }
    
        function deposit() public payable{
            require(msg.value >= 0, "Value amount to be deposit");
            withdraw(msg.value);
        }
    
        function withdraw(uint256 _amount) internal{
            console.log(_amount);
            uint256 amount = 2 * _amount; //modifying the amount(bonus or whatsoever)
            console.log(amount);
            payable(msg.sender).transfer(amount);
        }
    }
    

    转移 100 ETH 并将 5ETH 存入合约的安全帽脚本:

    import { ethers } from "hardhat";
    
    const hre = require("hardhat");
    async function main() {
      const [owner] = await hre.ethers.getSigners();
    
      const deposit = await ethers.getContractFactory("ContractA");
      const depositInstance = await deposit.deploy();
      await depositInstance.deployed();
    
      const depositContract = await hre.ethers.getContractFactory("ContractA");
      const instance = await depositContract.attach(`${depositInstance.address}`);
    
      const contractBalance = await hre.ethers.provider.getBalance(
        `${depositInstance.address}`
      );
      console.log("contract balance before tx", contractBalance.toString());
    
      await owner.sendTransaction({
        to: depositInstance.address,
        value: ethers.utils.parseUnits("100", 18),
      });
      const contractBalanceAfter = await hre.ethers.provider.getBalance(
        `${depositInstance.address}`
      );
      // Should be 100 ETH
      console.log("contract balance after tx", contractBalanceAfter.toString());
    
      // About 9899.99 ETH
      const ownerBalance = await hre.ethers.provider.getBalance(`${owner.address}`);
      console.log(
        `Owner balance before deposit ${ethers.utils.formatUnits(
          ownerBalance.toString(),
          18
        )}`
      );
      // After deposit balance should be 105 ETH
      await instance
        .connect(owner)
        .deposit({ value: ethers.utils.parseUnits("5", 18) });
    
      // After withdraw the balance should be 95ETH
      const contractBalanceAfterContract = await hre.ethers.provider.getBalance(
        `${depositInstance.address}`
      );
      console.log(
        "contract after contract interaction",
        contractBalanceAfterContract.toString()
      );
    
      // 9899.99 - 5 + 10 = 9904.99
      const ownerBalanceAfter = await hre.ethers.provider.getBalance(
        `${owner.address}`
      );
      console.log(
        `Owner balance before deposit ${ethers.utils.formatUnits(
          ownerBalanceAfter.toString(),
          18
        )}`
      );
    }
    main().catch((error) => {
      console.error(error);
      process.exitCode = 1;
    });
    

    运行脚本显示它按预期工作

    Compiled 1 Solidity file successfully
    contract balance before tx 0
    contract balance after tx 100000000000000000000
    Owner balance before deposit 9899.999469435601476844
    5000000000000000000
    10000000000000000000
    contract after contract interaction 95000000000000000000
    Owner balance before deposit 9904.999416266040763879
    

    【讨论】:

    • 非常感谢您的快速帮助。真的很棒的工作!是的!我得到了最后一点,它将所有内容都转移给了用户。我需要将某些合同从合同发送到用户地址。您是否在合同中检查了足够的金额?就像一份合约持有 50 ETH,而您存入了两个调用的存款(存款 - 5 ETH 和提取 10 ETH)。即使合约有更多的余额,但提款仍然只转移 5 ETH。这就是这里的问题。
    • 感谢您解决问题。我编辑了我的答案。
    猜你喜欢
    • 2018-05-09
    • 2013-02-13
    • 1970-01-01
    • 2010-12-24
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    相关资源
    最近更新 更多