web3.js
web3.js copied to clipboard
`web3.eth.Contract.methods.myMethod()` does not accept to insert any parameters.
Expected behavior
- Expect
web3.eth.Contract.methods.myMethod(myParam)
works with parameters. - The expectation behavior is explained in comments like below.
Actual behavior
- I implemented smart contract in solidity, and already deployed it to Goerli test network.
- ABI file was extracted, and I added the file into my code repository.
- Thus, ABI file was OK. However, the below things are bothering me.
-
web3.eth.Contract.methods.setSystemAddress(address)
does not allow the parameter (see the below image). - The error says
You need 0 arguments, but you got 1 argument.
.
Steps to reproduce the behavior
- Setting as below Environment.
- Get ABI file into
web3.eth.Contract
whatever you have to generateContract
. - Call
web3.eth.Contract.methods.yourMethod
with some parameters. - The syntax does not allow you insert any parameters.
Logs
Sorry, the compile cannot be processed, any error logs cannot be provided.
Environment
- Use
yarn
(classic v1) package manager - Use
NestJS
boilerplate with Node.js version19.16.1
(also in16.15.1
) - Use
web3
package with version4.0.2
(maybe recent version) - MacOS (M1 ChipSet)
Hi there, thank you for submitting this issue. https://docs.web3js.org/guides/smart_contracts/infer_contract_types_guide/
When you define your abi make sure to define it as const
like in the example above.
So in your case it would be
const abiFile = .... as const;
.
This will fix your methods and allow parameters. Let me know if you need more help :)
Thank you for your quick answer. Unfortunately, I read the link, and follow some guides, however, it did not work.
As your answer, I tried:
However, the error occurs that "const" assertion can be applied to ...
Then, I tried with the link's answer like:
This does not occur any errors on it, however, the "no parameter" problem still occurs.
I think with your comment, the error may occur because the type did not set from contract ABI. However, my ABI file was extracted by "Remix" and it is saved in .json
file well. Here is a log to print of ABI file in the variable abiFile
. (The object is wrapped with array like other ABI files.)
By the way, the problem is still bothering me.
Interesting case. The problem is you read the file (not import) and then convert it to const. I will investigate it.
@hubts So the main problem is the Typescript can't recognize a type when you use a dynamic import. My vision to solve the problem: 1 option: convert json file to a typescript file like this one and then use it in your contract initialization.
2 option: create ABI type and assign to your imported json
type MyAbi = readonly [{
inputs: [
{
internalType: 'address';
name: 'to';
type: 'address';
},
{
internalType: 'uint256';
name: 'amount';
type: 'uint256';
},
];
name: 'transfer';
outputs: [
{
internalType: 'bool';
name: '';
type: 'bool';
},
];
stateMutability: 'nonpayable';
type: 'function';
}];
const abi = JSON.parse(fs.readFileSync('./ERC20Token.json', 'utf-8')).abi as unknown as MyAbi;
const contract = new Contract(abi);
contract.methods.transfer('0xe4beef667408b99053dc147ed19592ada0d77f59', 12);
I encountered the same problem
Hello @rickiey ,
We will look more into this.
However, in the mean time as a fast fix you can try:
(contract.methods.transfer as any)('0xe4beef667408b99053dc147ed19592ada0d77f59', 12);
it is ugly we know. And for this will try to improve.
Hello, @avkos Thank you for your detailed reply. First of all, the type problem you told me seems to be correct. Below are the results of my own experience with your solutions.
Option 1. Declaring a JSON file as a variable doesn't seem to work.
Like the link, it was declared as a const
variable and used as a parameter for Contract
. (Web3Contract
is my alias for Contract
)
Unfortunately, still not accepting argument.
Option 2. Creating an ABI type works for now.
I declared the const
variable in Option 1 as type. I used the type to parse JSON file. Then, Contract.methods
finds the type and allows argument!
Thank you for solving my problem. However, there are still questions left.
Option 1 did not work by declaring a const
variable, but it is working after declaring as type in Option 2. In my thinking, the exact contract function name and arguments cannot be recognized by the type found with the variable (abi) of Contract
(as Option 1). In other words, I should specify the function name and arguments using the type (as Option 2).
One thing I'm curious about is that if I do this, after I implement a contract, I will not only make the ABI json, but also copy to declare as a type. There is no exact value from type, so I should read the JSON file to get value. This means that I need to manage and match the two files, ABI json file (value) and ABI typescript file (type).
Is this the right way?
Anyway, this problem has been solved and I can continue the project!
For Angular and React typescript projects the issue is still active, with a workaround as outlined above.
Additional steps still required - to extract the abi from a contract JSON artefact and manually assign as const fooAbi = [ xxx ] as const within your code.
Would be great if we could find a more seamless solution for typescript frameworks to pull directly from the full JSON contract file and avoid the extra manual work per contract. Just to recap - extracting the abi from the full JSON artefact using either import or require , encapsulating with [] as const, will result in lost method arguments.
Same problem, fixed it by using 'as const' at the abi. const nonceAbi = [ { inputs: [{ internalType: 'address', name: '', type: 'address' }], name: 'nonces', outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], stateMutability: 'view', type: 'function', }, ] as const;