matter-labs/zksync

Documentation is bad

Opened this issue · 0 comments

I started from the beginning. Got to the example I can try in my IDE:

Welcome to ZKsync 101
Alright cool. I set up a project. Installed zksync-cli, ran zksync-cli create zksync-101 --template zksync-101.. run complie, test. All works, great. Created my own contract, deployed to in memory chain. Works. Now lets call:

zksync-cli contract read \
--chain in-memory-node \
--contract <0xYOUR_CONTRACT_ADDRESS> \
--abi artifacts-zk/contracts/1-hello-zksync/CrowdfundingCampaign.sol/CrowdfundingCampaign.json

Works, great!

Now what? I want to call the same APIs from typescript with typesafety. How? No clue. I go to SDK section, choose javascript. It has:

  • Ethers
  • Web3.js

I have no idea what I utilized before when I explored the project generated with zksync-cli. Okay, lets try Ethers->Guides. What is all about? How does it correlate with what was generated? Seeing 2 code examples -- something completely different. It turns out the generated project uses hardhat and all the connections from Ethers should be established manually. Okay, trying to do that. new Provider('http://127.0.0.1:8011'); works. How do I communicate with the existing contract?

Each and every example I see in the documentation shows something like this:

// construct a contract class
// deploy the contract
// interact with the contract

How do I suppose to interact with the existing contract? Are you suggesting I need to create and deploy a new contract each time I want to get a reference to it? Seems like pretty rare use case.

Finally I found the example Interact with an existing smart contract in Web3.js SDK documentation. Hence to answer my original question I needed to go through all the generated project code, to look at zksync-cli source code to figure out that for write and read APIs it implements it's own logic, to go through documentation examples suggesting to deploy contracts to communicate with them and finally to see the example in Web3.js SDK realizing that I need to use this particular SDK to achieve my goal.

Finally at the end of the day I successfully executed so much needed example:

import dotenv from 'dotenv';
import fs from 'fs';
import { Contract, ContractAbi, Web3 } from 'web3';
import { types, Web3ZKsyncL2, ZKsyncPlugin, ZKsyncWallet } from 'web3-plugin-zksync';

dotenv.config();
async function main() {
  const web3: Web3 = new Web3();
  web3.registerPlugin(new ZKsyncPlugin(Web3ZKsyncL2.initWithDefaultProvider(types.Network.Localhost)));
  const zksync: ZKsyncPlugin = web3.ZKsync;

  const PRIVATE_KEY: string = process.env.WALLET_PRIVATE_KEY!;
  const wallet: ZKsyncWallet = new zksync.Wallet(PRIVATE_KEY);

  const metaPath = 'artifacts-zk/contracts/1-hello-zksync/CrowdfundingCampaign.sol/CrowdfundingCampaign.json';
  const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
  const contractAbi: ContractAbi = meta.abi;
  const contractAddress: string = '0x26b368C3Ed16313eBd6660b72d8e4439a697Cb0B';

  // use the wallet and its provider to instantiate the contract
  const contract: Contract<ContractAbi> = new wallet.provider!.eth.Contract(contractAbi, contractAddress);

  const returnValue = await contract.methods.contractMethod(/* method parameters, if any */).call();
}

main()
  .then(() => console.log('✅ Script executed successfully'))
  .catch((error) => console.error(`❌ Error executing script: ${error}`));

this is the output:

/Users/user/Projects/p/apps/zksync/zksync-101/node_modules/web3-utils/lib/utils.js:243
if (!isFinite(value) && !isHexStrict(value)) {
^

  TypeError: Cannot convert a BigInt value to a number
  at isFinite (<anonymous>)
  at numberToHex (/Users/user/Projects/p/apps/zksync/zksync-101/node_modules/web3-utils/lib/utils.js:243:10)
  at toHex (/Users/user/Projects/p/apps/zksync/zksync-101/node_modules/web3-utils/lib/utils.js:323:62)
  at Object.<anonymous> (/Users/user/Projects/p/apps/zksync/zksync-101/node_modules/web3-plugin-zksync/lib/TypedDataEncoder.js:43:66)
  at Module._compile (node:internal/modules/cjs/loader:1546:14)
  at Object..js (node:internal/modules/cjs/loader:1689:10)
  at Module.load (node:internal/modules/cjs/loader:1318:32)
  at Function._load (node:internal/modules/cjs/loader:1128:12)
  at TracingChannel.traceSync (node:diagnostics_channel:315:14)
  at wrapModuleLoad (node:internal/modules/cjs/loader:218:24)

I call it a day