【问题标题】:How do I charge a transaction fee when a function in my contract is executed?执行合约中的功能时如何收取交易费?
【发布时间】:2022-01-05 19:23:29
【问题描述】:

例如,假设每次用户成功执行计算两个数字之和的合约函数时,我想收取 1% 的 ETH 费用,该费用会发送到与合约不同的账户。我当前的解决方案“有效”,但它不是您可以想象的好解决方案。就目前而言,用户必须一个接一个地签署两个单独的交易。一是签署费用金额,二是签署合约功能。我将如何创建一项同时包含费用和合约功能的交易?我正在使用 Ethers.js 作为便利库,但我对其他解决方案持开放态度。

团结合同

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Calculate {
  uint private c = 123;

  constructor() {
    getC();
  }

  function getC() public view returns (uint) {
    return c;
  }

  function add(uint _a, uint _b) public {
    c = _a + _b;
  }
}

反应

  async function add() {
    await requestAccount();
    await sendETH();
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();
    const contract = new ethers.Contract(
      calculateAddress,
      Calculate.abi,
      signer
    );
    const tx = await contract.add(a, b);
    await tx.wait();
    getC();
  }

  async function sendETH() {
    await requestAccount();
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();
    const tx = {
      from: connectedAccount,
      to: fundAcct,
      value: ethers.utils.parseEther(fee.toString()),
    };
    signer.sendTransaction(tx).then((transaction) => {
      console.dir(transaction);
      alert("Send finished!");
    });
  }

【问题讨论】:

    标签: javascript reactjs ethereum solidity ethers.js


    【解决方案1】:

    如果传入的转账金额是任意的,而你收取1%,你必须用value*(1+fee)金额调用add函数。

    考虑到fee 在0-1 的范围内,并且有一个total 变量表示无费用的总交易成本。

    const tx = await contract.add(a, b, {value: ethers.utils.parseEther(fee.toString()).mul(total)});
    
    //SPDX-License-Identifier: Unlicense
    pragma solidity ^0.8.0;
    
    import "hardhat/console.sol";
    
    contract Calculate {
      uint private c = 123;
      address separateContract;
    
      constructor(address _separateContract) {
        getC();
        separateContract = _separateContract;
      }
    
      function getC() public view returns (uint) {
        return c;
      }
    
      function add(uint _a, uint _b) public payable {
        separateContract.send(msg.value / 100); // send 1% to a separate contract
        c = _a + _b;
      }
    }
    

    【讨论】:

    • 这确实是在以太坊中做到这一点的唯一方法。在 metamask(或其他 rpc 客户端)中,它只会显示为价值总额 + 费用作为一个数字,然后气体作为一个单独的数字......如果确认弹出窗口能更好地解决问题,那就太好了,但我猜我们还没有!
    猜你喜欢
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2022-09-29
    • 2017-05-11
    • 2014-04-14
    • 2022-01-15
    • 2022-08-17
    • 1970-01-01
    相关资源
    最近更新 更多