Por ejemplo, digamos que cada vez que un usuario ejecuta con éxito una función de contrato que calcula la suma de dos números, me gustaría cobrar una tarifa de ETH del 1% que se envía a una cuenta separada del contrato. Mi solución actual "funciona", pero no es una buena solución como puede imaginar. Tal como está, el usuario tiene que firmar dos transacciones separadas, una tras otra. Primero, para firmar el monto de la tarifa y, en segundo lugar, para firmar la función del contrato. ¿Cómo haría para crear una transacción que incluya tanto la tarifa como la función del contrato juntas? Estoy usando Ethers.js para la biblioteca de conveniencia, pero estoy abierto a otras soluciones.
Contrato de Solidez
//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; } }Reaccionar
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!"); }); }En caso de que el monto de la transferencia entrante sea alguno y usted cobre el 1%, debe llamar a la función add con el monto value*(1+fee) .
Teniendo en cuenta que fee está en el rango 0-1 y hay una variable total para un costo de transacción total sin tarifa.
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; } }