web3.js
web3.js copied to clipboard
An issue when calling a method on diamonds proxy contract
description
There is an issue specifically with diamonds proxy contract. Probably some or all other proxy contracts work. When calling the proxy contract address an error is throw:
ContractExecutionError: Error happened while trying to execute a function inside a smart contract
455 | // However, more processing will happen at a higher level to decode the error data,
456 | // according to the Error ABI, if it was available as of EIP-838.
> 457 | if (error?.message.includes('revert')) throw new ContractExecutionError(error);
| ^
458 |
459 | return false;
460 | }
at Function._isReverted (../../../web3v4.x/packages/web3-core/src/web3_request_manager.ts:457:48)
at Web3RequestManager._processJsonRpcResponse (../../../web3v4.x/packages/web3-core/src/web3_request_manager.ts:396:35)
at Web3RequestManager.<anonymous> (../../../web3v4.x/packages/web3-core/src/web3_request_manager.ts:226:16)
at fulfilled (../../../web3v4.x/packages/web3-core/lib/commonjs/web3_request_manager.js:21:58)
Cause:
Note: As shown above the Cause: is empty and no text after it.
The diamonds proxy standard is defined in the EIP 2535: https://eips.ethereum.org/EIPS/eip-2535
Fixing this is needed for the zkSync plugin. Kindly check: https://github.com/ChainSafe/web3-plugin-zksync/commit/37b161514ce78b8b7f4f230a82ee2d09f409626c
Steps to reproduce the behavior
import { Contract, Web3 } from 'web3';
describe('diamonds proxy tests', () => {
const ABI = [
{
inputs: [],
name: 'getName',
outputs: [
{
internalType: 'string',
name: '',
type: 'string',
},
],
stateMutability: 'view',
type: 'function',
},
] as const;
it('using direct contract', async () => {
const web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/VCOFgnRGJF_vdAY2ZjgSksL6-6pYvRkz');
const contract = new Contract(ABI, '0x550cf73F4b50aA0DF0257f2D07630D48fA00f73a', web3);
const contractName = await contract.methods.getName().call();
expect(contractName).toBe('MailboxFacet');
});
// This currently throws! ContractExecutionError: Error happened while trying to execute a function inside a smart contract
it('using diamonds proxy contract', async () => {
const web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/VCOFgnRGJF_vdAY2ZjgSksL6-6pYvRkz');
const contract = new Contract(ABI, '0x9A6DE0f62Aa270A8bCB1e2610078650D539B1Ef9', web3);
const contractName = await contract.methods.getName().call();
expect(contractName).toBe('MailboxFacet');
});
});
It turns out only registered facets functions of a diamonds proxy would be callable. And getName is not available in the proxy contract. So, no issues with web3.js.
Calling methods in a diamonds proxy contract works well and here is an example:
it('using diamonds proxy contract', async () => {
const web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/VCOFgnRGJF_vdAY2ZjgSksL6-6pYvRkz');
const contract = new Contract(ABI, '0x9A6DE0f62Aa270A8bCB1e2610078650D539B1Ef9', web3);
const l2TransactionBaseCost = await contract.methods
.l2TransactionBaseCost(BigInt(18556727650), BigInt(14414298), 800)
.call();
expect(l2TransactionBaseCost).toBeGreaterThan(BigInt(0));
});
However, the error parsing in web3.js would better to be able to handle Error(string) and Panic(uint256). So, an MR will be opened for this.