I understand that you can send ethereum to a smart contract, although when you do this with sendTransaction
it doesn't seem that you specify a function on the smart contract when you do this. I don't quite understand how this is useful.
However what I can't find out how to do, is to send ethereum to a function that is set as payable.
I'm using ethers.js and can create a contract, and call functions that are viewable (read only) no problem, but I cant work out how to send ethereum with the transaction to a specific function
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
}
}
Any help as to why calling contract.requestAccess
is reverting on me? I can't quite work out how to call a specific function and send Ether.
Thanks!
Response to comment
Ok right, so the function in the solidity contract looks like:
function requestAccess() payable {
require(msg.value == price, "Incorrect sum sent to contract");
_addUser(msg.sender);
}
I commented out the require, to try that but still reverts. _addUser is from a contract mine inherits from, and looks like
function _addUser(address account) internal {
users.add(account);
emit UserAdded(account);
}
users
is Roles.Role private users;
and sits in the parent contract
contract Users {
using Roles for Roles.Role;
which imports from openzeppelin "openzeppelin-solidity/contracts/access/Roles.sol"