zksync-sdk / zksync2-js Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
We need the shared bridge contracts on L1 for hyperscaling. Messages, deposits and withdrawals will go to all hyperchains via a shared Bridgehub contract, and the assets will be locked in shared bridges. This means the contracts change, so this repo also has to change.
The main difference is we will have to specify the chainId of the hyperchain we are depositing to, this is in src/adapters.ts . For backwards compatibility I think we can preserve the old methods and point them to Era.
After installing this package from NPM with npm i @matterlabs/[email protected]
, no dist
folder is found in the node_modules
install
Description: When using the zkWallet.deposit
method in the deployment script and then executing the deploy command, an unexpected error is thrown indicating a transaction revert without a reason string.
Steps to Reproduce:
npx zksync-cli create-project hello-world
.cd hello-world
.deploy-greeter.ts
) with the provided script (adds back depositing funds to L2).import { Wallet, utils } from "zksync-web3";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
// load env file
import dotenv from "dotenv";
dotenv.config();
// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";
if (!PRIVATE_KEY)
throw "โ๏ธ Private key not detected! Add it to the .env file!";
// An example of a deploy script that will deploy and call a simple contract.
export default async function (hre: HardhatRuntimeEnvironment) {
console.log(`Running deploy script for the Greeter contract`);
// Initialize the wallet.
const wallet = new Wallet(PRIVATE_KEY);
// Create deployer object and load the artifact of the contract you want to deploy.
const deployer = new Deployer(hre, wallet);
const artifact = await deployer.loadArtifact("Greeter");
// Estimate contract deployment fee
const greeting = "Hi there!";
const deploymentFee = await deployer.estimateDeployFee(artifact, [greeting]);
console.log("before");
// โ ๏ธ OPTIONAL: You can skip this block if your account already has funds in L2
// Deposit funds to L2
const depositHandle = await deployer.zkWallet.deposit({
token: utils.ETH_ADDRESS,
amount: deploymentFee.mul(2),
});
// Wait until the deposit is processed on zkSync
await depositHandle.wait();
// Deploy this contract. The returned object will be of a `Contract` type, similarly to ones in `ethers`.
// `greeting` is an argument for contract constructor.
const parsedFee = ethers.utils.formatEther(deploymentFee.toString());
console.log(`The deployment is estimated to cost ${parsedFee} ETH`);
const greeterContract = await deployer.deploy(artifact, [greeting]);
//obtain the Constructor Arguments
console.log(
"Constructor args:" + greeterContract.interface.encodeDeploy([greeting])
);
// Show the contract info.
const contractAddress = greeterContract.address;
console.log(`${artifact.contractName} was deployed to ${contractAddress}`);
// verify contract for tesnet & mainnet
if (process.env.NODE_ENV != "test") {
// Contract MUST be fully qualified name (e.g. path/sourceName:contractName)
const contractFullyQualifedName = "contracts/Greeter.sol:Greeter";
// Verify contract programmatically
const verificationId = await hre.run("verify:verify", {
address: contractAddress,
contract: contractFullyQualifedName,
constructorArguments: [greeting],
bytecode: artifact.bytecode,
});
} else {
console.log(`Contract not verified, deployed locally.`);
}
}
yarn hardhat compile
.yarn deploy
.Expected Result: Deposit should be processed successfully and move on to the subsequent steps in the deploy script.
Actual Result: An error is thrown stating "missing revert data in call exception; Transaction reverted without a reason string".
An unexpected error occurred:
Error: missing revert data in call exception; Transaction reverted without a reason string [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (transaction={"from":"0x42baB21bB7c1E236D67B264685E28fbbeF49C19F","to":"0x1908e2BF4a88F91E4eF0DC72f02b8Ea36BEa2319","data":"0xb473318e0000000000000000000000000000000000000000000000000000000059682f1500000000000000000000000000000000000000000000000000000000001136600000000000000000000000000000000000000000000000000000000000000320","accessList":null}, code=CALL_EXCEPTION, version=providers/5.7.2)
at Logger.makeError (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
at /Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/src.ts/fallback-provider.ts:632:24
at Array.forEach (<anonymous>)
at /Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/src.ts/fallback-provider.ts:614:33
at step (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/lib/fallback-provider.js:48:23)
at Object.next (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/lib/fallback-provider.js:29:53)
at step (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/lib/fallback-provider.js:33:139)
at Object.next (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/lib/fallback-provider.js:29:53)
at fulfilled (/Users/dustinbrickwood/Documents/dev/zk/temp/hello-world/node_modules/@ethersproject/providers/lib/fallback-provider.js:20:58) {
reason: 'missing revert data in call exception; Transaction reverted without a reason string',
code: 'CALL_EXCEPTION',
transaction: {
from: '0x42baB21bB7c1E236D67B264685E28fbbeF49C19F',
to: '0x1908e2BF4a88F91E4eF0DC72f02b8Ea36BEa2319',
data: '0xb473318e0000000000000000000000000000000000000000000000000000000059682f1500000000000000000000000000000000000000000000000000000000001136600000000000000000000000000000000000000000000000000000000000000320',
accessList: null
}
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
Provide a clear and concise description of the bug.
When I create a wallet, and try to get the balance of my zkwallet, it throws "Error: an ENS name used for a contract target must be correctly configured (value="", code=UNCONFIGURED_NAME, version=6.8.1)".
import { ethers } from 'ethers';
import { Provider, Wallet } from 'zksync2-js';
const ethProvider = new ethers.JsonRpcProvider(ETH_ENDPOINT);
const zkProvider = new Provider('https://mainnet.era.zksync.io');
const zkWallet = await new Wallet(
privateKey,
this.zksyncProvider,
this.ethersProvider,
);
// it is this line where the error was thrown.
await zkWallet.getBalance(utils.ETH_ADDRESS);
To get the ETH balance of my zkWallet
Throws Error: an ENS name used for a contract target must be correctly configured (value="", code=UNCONFIGURED_NAME, version=6.8.1)
I'd like to see support for instantiating a Wallet
that is backed by a ledger device. This could be done using a new static constructor like
static fromHardwareWallet(pubKey: string, provider?: ethers.Provider): Wallet
In regular hardhat projects we can use @nomicfoundation/hardhat-ledger
to add support for ledger devices and use it using the high level interface using ethers.getSigners()
with something like this:
const [_, deployer] = await ethers.getSigners();
const MyContract = await ethers.getContractFactory('MyContract');
const myContract = await MyContract.connect(deployer).deploy();
await myContract.waitForDeployment();
Since we can't use this high level interface in zkSync deployments we rely on the Deployer
class from this repo which is basically a nice wrapper around the Wallet
class which by now only supports directly supplied key material.
Having an option to use a ledger here would be very appreciated
It would be nice if this here would work (the code is referencing the default deploy script from the project template used by zksync-dev create project foobar
)
import { Wallet } from "zksync-web3";
import { deployContract } from "./utils";
export default async function () {
const wallet = Wallet.fromHardwareWallet('0xdeadbeefdeadbeef')
const contractArtifactName = "Greeter";
const constructorArguments = ["Hi there!"];
await deployContract(contractArtifactName, constructorArguments, { wallet });
}
Both createAddress
and create2Address
provide incorrect addresses.
zksync-web3
provide the correct addresses
createAddress
from zksync-web3
createAddress
from zksync2-js
Functions predict addresses as network deploys
Functions produce valid, but inccorrect addresses
zksync2-js
: 0.3.0
The current latest
tagged version of hardhat-zksync-zksync2js
has a broken build on npm
since the dist
folder is missing in the uploaded package and thus you can't access any hre.zksync2js
objects. If you upgrade to the latest beta version 0.0.1-beta.2
, it will fix the issue but this version doesn't have the latest
tag and thus people using the default npm
install will face issues.
Current release notes are missing information on New Features, Fixes, and Breaking Changes. An overview of these changes would help developers understand changes in the repo without running through the commit history or compare releases/tags.
A suggested format:
New Features
Fixes
Breaking Changes
Implement a new method like wallet.getDeployNonce()
that returns the deployment nounce.
To get the deployment nounce for a deploy transaction now, you need to ask for the rawNonce
for an account (the param is uint256, you need to pad the address with zeroes to the left) https://github.com/matter-labs/era-system-contracts/blob/3e954a629ad8e01616174bde2218241b360fda0a/contracts/NonceHolder.sol#L35
After you get the value it will be of form 2^128 * deploymentNonce + normalNonce
. You then need to do the floored division (BigNumber.div(..)
).
When using the zksync-web3
SDK to deposit or bridge funds using ERC-20 tokens, the transaction hangs and fails to execute.
mkdir deposit-erc20-script && cd deposit-erc20-script
npm init -y
npm i typescript ts-node ethers@^5.7.2 zksync-web3 dotenv
.env
file at the project rootCreate a .env file in the project root containing your private key and the L1 RPC endpoint.
WALLET_PRIV_KEY=<YOUR_PRIVATE_KEY>
L1_RPC_ENDPOINT=<RPC_URL>
import { Wallet, Provider, utils } from "zksync-web3";
import * as ethers from "ethers";
// load env file
import dotenv from "dotenv";
dotenv.config();
// HTTP RPC endpoints
const L1_RPC_ENDPOINT = process.env.L1_RPC_ENDPOINT || ""; // or an RPC endpoint from Infura/Chainstack/QuickNode/etc.
const L2_RPC_ENDPOINT = process.env.L2_RPC_ENDPOINT || "https://testnet.era.zksync.dev"; // or the zkSync Era mainnet
// ERC-20 Token address in L1
const TOKEN_ADDRESS = "<TOKEN_ADDRESS>";
// Amount of tokens
const AMOUNT = "5";
const WALLET_PRIV_KEY = process.env.WALLET_PRIV_KEY || "";
if (!WALLET_PRIV_KEY ) {
throw new Error("Wallet private key is not configured in env file");
}
if (!L1_RPC_ENDPOINT) {
throw new Error(
"Missing L1 RPC endpoint. Check chainlist.org or an RPC node provider"
);
}
if (!TOKEN_ADDRESS ) {
throw new Error("Missing address of the ERC-20 token in L1");
}
async function main() {
console.log(`Running script to bridge ERC-20 to L2`);
// Initialize the wallet.
const l1provider = new Provider(L1_RPC_ENDPOINT);
const l2provider = new Provider(L2_RPC_ENDPOINT);
const wallet = new Wallet(WALLET_PRIV_KEY, l2provider, l1provider);
console.log(`L1 Balance is ${await wallet.getBalanceL1()}`);
console.log(`L2 Balance is ${await wallet.getBalance()}`);
// Deposit token to L2
const depositHandle = await wallet.deposit({
to: wallet.address, // can bridge to a different address in L2
token: TOKEN_ADDRESS,
amount: ethers.utils.parseEther(AMOUNT), // assumes ERC-20 has 18 decimals
// performs the ERC-20 approve action
approveERC20: true,
});
console.log(`Deposit transaction sent ${depositHandle.hash}`);
console.log(`Please wait a few minutes for the deposit to be processed in L2`);
}
main().then().catch((error) => {
console.error(error);
process.exitCode = 1;
});
npx ts-node deposit-erc20.ts
Running script to bridge ERC-20 to L2
L1 Balance is 19500035772482145
L2 Balance is 2969807401250000000
Deposit transaction sent 0xffb8e302430b0584e2e0104dd6295a03688c98ba7b6e9279b01dba65188cc444
Running script to bridge ERC-20 to L2
L1 Balance is 8513092747259571425
L2 Balance is 983733765214875035
l2TokenAddress
call fails during deposit operationThe call to retrieve l2TokenAddress
seems to be failing, and this call is made in a few places when we call wallet.deposit
.
Example:
const l2WethToken = await bridgeContracts.weth.l2TokenAddress(transaction.token);
This call consistently fails with a CALL_EXCEPTION
error.
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="l2TokenAddress(address)", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.7.0)
at Logger.makeError (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
at Interface.decodeFunctionResult (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/abi/src.ts/interface.ts:427:23)
at Contract.<anonymous> (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/contracts/src.ts/index.ts:400:44)
at step (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/contracts/lib/index.js:48:23)
at Object.next (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/contracts/lib/index.js:29:53)
at fulfilled (/Users/dustinbrickwood/Documents/dev/zk/zksync-era/node_modules/@ethersproject/contracts/lib/index.js:20:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: null,
code: 'CALL_EXCEPTION',
method: 'l2TokenAddress(address)',
data: '0x',
errorArgs: null,
errorName: null,
errorSignature: null,
address: '0x0000000000000000000000000000000000000000',
args: [ '0x07865c6E87B9F70255377e024ace6630C1Eaa37F' ],
transaction: {
data: '0xf5f1516800000000000000000000000007865c6e87b9f70255377e024ace6630c1eaa37f',
to: '0x0000000000000000000000000000000000000000',
from: '0x42baB21bB7c1E236D67B264685E28fbbeF49C19F'
}
}
When executing the deposit call from the script:
const depositHandle = await wallet.deposit({
to: wallet.address,
token: TOKEN_ADDRESS,
amount: ethers.utils.parseEther(AMOUNT),
approveERC20: true,
});
The function internally references l2TokenAddress
in a few places:
By commenting out the lines that invoke l2TokenAddress
in the above-referenced locations, the deposit transaction executes as expected and successfully completes. This workaround suggests that the issue may be specifically related to how l2TokenAddress
is being called or handled.
To close out this issue:
l2TokenAddress
Description:
The current default provider in the example code connects to the Goerli testnet, which gonna be deprecated. The zkSync Era is using the Sepolia network, and the example should reflect this change.
Steps to Reproduce:
Use the provided example code.
Observe that it connects to the Goerli testnet instead of Sepolia.
Expected Behavior:
The example code should connect to the Sepolia network, which is the zkSync Era testnet.
Actual Behavior:
The code connects to the Goerli testnet.
Code Snippet:
import { Provider, types } from "zksync-ethers";
import { ethers } from "ethers";
async function getLatestBlockNumber() {
try {
const provider = Provider.getDefaultProvider(types.Network.Goerli); // Incorrect: connects to Goerli
const ethProvider = ethers.getDefaultProvider("goerli"); // Incorrect: connects to Goerli
// Get the latest block number
const blockNumber = await provider.getBlockNumber();
console.log("Latest block number:", blockNumber);
} catch (error) {
console.error("Error:", error.message);
}
}
// Call the function
getLatestBlockNumber();
Proposed Solution:
Update the default providers in the example code to connect to the Sepolia network.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.