-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Show warning for ambiguous Solidity method call (#6942)
* show warning for ambiguous function calls + add tests * add guide for Smart Contracts Tips and Tricks * update CHANGELOG.md file
- Loading branch information
1 parent
526c6f5
commit 5341c3a
Showing
5 changed files
with
170 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
--- | ||
sidebar_position: 4 | ||
sidebar_label: 'Tips and Tricks' | ||
--- | ||
|
||
# Smart Contracts Tips and Tricks | ||
|
||
:::tip | ||
📝 This article offers insights into **Smart Contracts** with helpful tips and tricks. If you have suggestions or questions, feel free to open an issue. We also welcome contributions through PRs. | ||
::: | ||
|
||
## Calling Smart Contracts Methods with Parameter Overloading | ||
|
||
### Overview of Function Overloading | ||
|
||
Parameter overloading enables smart contracts to define multiple functions bearing the same name, differentiated only by their parameters. While this enhances legibility and organization, it complicates calls due to the need for precise method identification. | ||
|
||
### Example Code | ||
|
||
Below is a demonstration of invoking two versions of the `funcWithParamsOverloading` function in a smart contract, differentiated by their parameter types: `uint256` versus `address`. | ||
|
||
The Solidity code: | ||
|
||
```solidity | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity >=0.8.20 <0.9.0; | ||
contract TestOverlading { | ||
function funcWithParamsOverloading(uint256 userId) public pure returns (string memory) { | ||
return "called for the parameter with the type 'uint256'"; | ||
} | ||
function funcWithParamsOverloading(address userAddress) public pure returns (string memory) { | ||
return "called for the parameter with the type 'address'"; | ||
} | ||
} | ||
``` | ||
|
||
The TypeScript: | ||
```typescript | ||
import { Web3 } from 'web3'; | ||
|
||
const ABI = [ | ||
{ | ||
inputs: [ | ||
{ | ||
internalType: 'uint256', | ||
name: 'userId', | ||
type: 'uint256', | ||
}, | ||
], | ||
name: 'funcWithParamsOverloading', | ||
outputs: [ | ||
{ | ||
internalType: 'string', | ||
name: '', | ||
type: 'string', | ||
}, | ||
], | ||
stateMutability: 'pure', | ||
type: 'function', | ||
}, | ||
{ | ||
inputs: [ | ||
{ | ||
internalType: 'address', | ||
name: 'userAddress', | ||
type: 'address', | ||
}, | ||
], | ||
name: 'funcWithParamsOverloading', | ||
outputs: [ | ||
{ | ||
internalType: 'string', | ||
name: '', | ||
type: 'string', | ||
}, | ||
], | ||
stateMutability: 'pure', | ||
type: 'function', | ||
} | ||
] as const; | ||
|
||
(async function () { | ||
const web3 = new Web3(provider); | ||
|
||
const contract = new web3.eth.Contract(ABI, contractAddress); | ||
|
||
// Calling the function that accepts an address | ||
const res1 = await contract.methods['funcWithParamsOverloading(address)'](userAddress).call(); | ||
|
||
// Calling the function that accepts a uint256 | ||
const res2 = await contract.methods['funcWithParamsOverloading(uint256)'](userId).call(); | ||
|
||
})(); | ||
``` | ||
|
||
### Handling Ambiguity in Overloaded Methods | ||
|
||
Omitting the explicit specification for overloading, as highlighted earlier, results in the default selection of the first method match in the ABI, along with a warning. Future web3.js releases will address this with an error to enforce stricter specification. | ||
|
||
#### Demonstrating the Importance of Specificity | ||
|
||
To underline specificity's value, here's a scenario of invoking an overloaded function without specifying the parameter type: | ||
|
||
```typescript | ||
// Assuming a contract with overloaded methods: funcWithParamsOverloading(uint256) and funcWithParamsOverloading(string)... | ||
|
||
(async function () { | ||
try { | ||
// A call without specifying overloading results in a warning and choosing the first matched overload | ||
const ambiguousResult = await contract.methods.funcWithParamsOverloading('0x0123').call(); | ||
})(); | ||
``` | ||
This generates a console warning on the ambiguity and auto-selects the first matching function overload found in the ABI: | ||
``` | ||
Multiple methods found that are compatible with the given inputs. Found 2 compatible methods: ["funcWithParamsOverloading(uint256) (signature: 0x...)", "funcWithParamsOverloading(string) (signature: 0x...)"] The first one will be used: funcWithParamsOverloading(uint256) | ||
``` | ||
### Future Considerations | ||
Future releases of web3.js, specifically version 5.x, will replace the warning with an error whenever multiple methods match a call without explicit overloading. This aims to foster greater precision in method invocation. | ||
### Key Takeaway for function overlading: Method Specification | ||
When working with overloaded smart contract methods, it's imperative to specify the intended method by appending its parameter types within parentheses, such as `funcWithParamsOverloading(address)` versus `funcWithParamsOverloading(uint256)`. This ensures the accuracy of method invocation, leading to more efficient and clearer contract interactions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5341c3a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark
processingTx
9545
ops/sec (±3.40%
)9301
ops/sec (±4.81%
)0.97
processingContractDeploy
39000
ops/sec (±7.84%
)39129
ops/sec (±7.62%
)1.00
processingContractMethodSend
19926
ops/sec (±6.38%
)19443
ops/sec (±5.19%
)0.98
processingContractMethodCall
39237
ops/sec (±6.01%
)38971
ops/sec (±6.34%
)0.99
abiEncode
43504
ops/sec (±6.81%
)44252
ops/sec (±6.92%
)1.02
abiDecode
29729
ops/sec (±7.44%
)30419
ops/sec (±8.89%
)1.02
sign
1597
ops/sec (±0.66%
)1656
ops/sec (±4.08%
)1.04
verify
364
ops/sec (±2.51%
)373
ops/sec (±0.78%
)1.02
This comment was automatically generated by workflow using github-action-benchmark.