Entiendo que puede enviar ethereum a un contrato inteligente, aunque cuando hace esto sendTransaction
no parece que especifique una función en el contrato inteligente cuando hace esto. No entiendo muy bien cómo esto es útil. Sin embargo, lo que no puedo averiguar cómo hacer es enviar ethereum a una función que está configurada como pagadera. Estoy usando ethers.js y puedo crear un contrato y llamar a funciones que son visibles (solo lectura) sin problema, pero no puedo averiguar cómo enviar ethereum con la transacción a una función específica
export const testContract = async (address, abi) => {
const wei = Utils.parseEther("0.1")
const url = "http://localhost:8545"
const provider = new Providers.JsonRpcProvider(url)
// Load the wallet to deploy the contract with
const privateKey =
"0x123"
const wallet = new Wallet(privateKey, provider)
var contract = new Contract(address, abi, wallet)
const price = await contract.retrievePrice()
console.log("price " + price) //logs the price set in the constructor when the contract was made (WORKS)
const testAddress = await contract.isUser(
"0x456"
)
console.log("testAddress ", testAddress) //checks if the given address is a user on the contract (WORKS)
const gasPrice = await provider.getGasPrice()
console.log("gas price: ", gasPrice.toString()) //returns the price of gas from the network (WORKS)
try {
const addToUsers = await contract.requestAccess({ //call function to request access, from the current wallet (REVERTS)
value: wei
})
console.log("result of sending transaction ", addToUsers)
} catch (error) {
console.log("error.... ", error) //fires as the contract reverted the payment
}
}
¿ Alguna ayuda sobre por qué las llamadas contract.requestAccess
vuelven a mí? No puedo entender cómo llamar a una función específica y enviar Ether. ¡Gracias!
Respuesta al comentario
Bien, entonces la función en el contrato de solidez se ve así:
function requestAccess() payable {
require(msg.value == price, "Incorrect sum sent to contract");
_addUser(msg.sender);
}
Comenté el requerimiento, para probar eso, pero aún se revierte. _addUser es de un contrato del que hereda la mina, y parece
function _addUser(address account) internal {
users.add(account);
emit UserAdded(account);
}
users
es Roles.Role private users;
y se sienta en el contrato padre
contract Users {
using Roles for Roles.Role;
que importa de openzeppelin "openzeppelin-solidity/contracts/access/Roles.sol"
Puede notar en los comentarios que no pude resolver lo que no funcionaba para mí, pero no soy un fanático de las respuestas "funciona, gracias" que no ayudan a otros. Así que he puesto un ejemplo de trabajo en esencia para cualquiera que esté buscando esto. Solo necesita hacer algunos cambios para ser específico a su situación, pero debería ser relativamente sencillo. https://gist.github.com/amlwwalker/89bc2c5a2b631527bb7def922b4c8306
Cita de https://github.com/ethers-io/ethers.js/issues/563
let overrides = {
// To convert Ether to Wei:
value: ethers.utils.parseEther("1.0") // ether in this case MUST be a string
// Or you can use Wei directly if you have that:
// value: someBigNumber
// value: 1234 // Note that using JavaScript numbers requires they are less than Number.MAX_SAFE_INTEGER
// value: "1234567890"
// value: "0x1234"
// Or, promises are also supported:
// value: provider.getBalance(addr)
};
// Pass in the overrides as the 3rd parameter to your 2-parameter function:
let tx = await exchangeContract.ethToTokenSwapOutput(tokens_bought, deadline, overrides);
No probé el código, pero cada vez que desee enviar ether junto con un método, debe "anularlo".
Const overrides = {
value: ethers.utils.parseEther("1.0"), //sending one ether
gasLimit: 30000 //optional
}
//call your payable method using and use the override as a parameter
await contract.requestAccess( overrides )
En el objeto de anulaciones, puede insertar varias cosas, como gasLimit
overrides.from - el msg.sender (o CALLER) para usar durante la ejecución del código
overrides.value - el msg.value (o CALLVALUE) para usar durante la ejecución del código
overrides.gasPrice - el precio a pagar por gas (teóricamente); dado que no hay transacción, no se cobrará ninguna tarifa, pero el EVM aún requiere un valor para informar a tx.gasprice (o GASPRICE); la mayoría de los desarrolladores no requerirán esto
overrides.gasLimit - la cantidad de gas (teóricamente) para permitir que un nodo use durante la ejecución del código; dado que no hay transacción, no se cobrará ninguna tarifa, pero el EVM aún procesa la medición de gas para que las llamadas como gasleft (o GAS) informen valores significativos
overrides.blockTag: una etiqueta de bloque para simular la ejecución, que se puede usar para un análisis histórico hipotético; tenga en cuenta que muchos backends no admiten esto, o pueden requerir planes pagos para acceder, ya que los requisitos de almacenamiento y procesamiento de la base de datos del nodo son mucho más altos
Thomas Vanderstraeten
amlwwalker
amlwwalker
Thomas Vanderstraeten
amlwwalker