With useDapp, in order to call a payable function and pass along a value we are using the useContractFunction method, which will automatically forward arguments to the underlying ethers.js contract object - this means that we don't need to explicitly do anything other than just pass the value, like we do inside the call to setCount inside the Count component:
function handleSetCount() {
const _count = parseInt(input) {
if (_count) {
setCount(_count); // passing _count here, which is handled by useContractFunction and sent through to the contract by ethers under the hood
}
}
}
Hi Jacob, thanks for the reply. I did have a read of the documentation but I am still a little stuck! I am able to call the contract with arguments when it is not expecting a value for the message but when it is expecting a value I am still not able to trigger this.
If I call it like this:
mintButton.tsx
import {useContractMethod } from "../hooks";
const { state: setMintTeaState, send: mintIt } = useContractMethod("mintTea");
function handleMint() {
if (account) {
mintIt(account, 1);
}
}
index.ts
export function useContractMethod(methodName: string) {
I am able to mint a token if the contract function is not expecting payment (the first 200 tokens are free). If I try beyond the first 200 I get an error in metamask, MetaMask - RPC Error: execution reverted: Value below price.
I have tried passing in a value as a third argument to mintIt() e.g.
function handleMint() {
if (account) {
mintIt(account, 1, ethers.utils.parseEther("50000000000000000"));
}
}
but when I run this metamask does not pop up a transaction as it does when I run it without the third argument.
The contract abi for the mintTea function looks like this and takes just two arguments, the address and the number to mint.
Sorry for such a long question, I am still very new to dapp development in general so am probably missing something quite basic! Any suggestions would be greatly welcomed, I have been trying various things to get this to work for a few days now but feel like I may be missing something obvious.
Hi George - the value property is a special property that is added to the msg object that the contract function receives - you can pass in your arguments sequentially and add a configuration object as the last argument:
mintTea(arg1, arg2, {
value: PARSED_ETH_VALUE
});
Here's a concrete example - I updated the contract I used in this tutorial with a payable function called "takeTwoVariables":
I replaced "handleSetCount" with "handleTwoVariables" in the onClick handler, so when the user clicks "Set Count" we will send 0.05 ether to the payable function along with the 2 integers (_count & 2). If the value property is not set, or set to 0, the function will revert because in the contract there is now a require statement, so the value must be > 0.
So, the TLDR is that you add arguments sequentially (based on their defined order in the contract), and you add "special" properties on the msg object like "value" inside the config object.
I hope that makes sense! Feel free to ask any more questions if that isn't quite clear :)
Hi George,
With useDapp, in order to call a payable function and pass along a value we are using the useContractFunction method, which will automatically forward arguments to the underlying ethers.js contract object - this means that we don't need to explicitly do anything other than just pass the value, like we do inside the call to setCount inside the Count component:
function handleSetCount() {
const _count = parseInt(input) {
if (_count) {
setCount(_count); // passing _count here, which is handled by useContractFunction and sent through to the contract by ethers under the hood
}
}
}
Btw here's the specific documentation for useContractFunction: usedapp.readthedocs.io/en/latest/c...
Hi Jacob, thanks for the reply. I did have a read of the documentation but I am still a little stuck! I am able to call the contract with arguments when it is not expecting a value for the message but when it is expecting a value I am still not able to trigger this.
If I call it like this:
mintButton.tsx
import {useContractMethod } from "../hooks";
index.ts
export function useContractMethod(methodName: string) {
}
I am able to mint a token if the contract function is not expecting payment (the first 200 tokens are free). If I try beyond the first 200 I get an error in metamask, MetaMask - RPC Error: execution reverted: Value below price.
I have tried passing in a value as a third argument to mintIt() e.g.
but when I run this metamask does not pop up a transaction as it does when I run it without the third argument.
The contract abi for the mintTea function looks like this and takes just two arguments, the address and the number to mint.
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_count",
"type": "uint256"
}
],
"name": "mintTea",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
and here is the mintTea and price functions from the Solidity contract:
Sorry for such a long question, I am still very new to dapp development in general so am probably missing something quite basic! Any suggestions would be greatly welcomed, I have been trying various things to get this to work for a few days now but feel like I may be missing something obvious.
Hi George - the value property is a special property that is added to the msg object that the contract function receives - you can pass in your arguments sequentially and add a configuration object as the last argument:
mintTea(arg1, arg2, {
value: PARSED_ETH_VALUE
});
Here's a concrete example - I updated the contract I used in this tutorial with a payable function called "takeTwoVariables":
Inside Count.tsx, I've imported utils from ethers (so we can parse our value):
// Count.tsx
And I've added a new function called "handleTwoVariables":
I replaced "handleSetCount" with "handleTwoVariables" in the onClick handler, so when the user clicks "Set Count" we will send 0.05 ether to the payable function along with the 2 integers (_count & 2). If the value property is not set, or set to 0, the function will revert because in the contract there is now a require statement, so the value must be > 0.
So, the TLDR is that you add arguments sequentially (based on their defined order in the contract), and you add "special" properties on the msg object like "value" inside the config object.
I hope that makes sense! Feel free to ask any more questions if that isn't quite clear :)
Thank you so much. That works perfectly and makes sense now. Thanks for taking the time to reply in such detail, it has really helped!