Skip to content

Latest commit

 

History

History
196 lines (159 loc) · 7.93 KB

05.md

File metadata and controls

196 lines (159 loc) · 7.93 KB
title actions requireLogin material
Deposit assets to zkSync
checkAnswer
hints
false
editor
language startingCode answer
JavaScript
src/utils.js
async function getZkSyncProvider (zksync, networkName) { let zkSyncProvider try { zkSyncProvider = await zksync.getDefaultProvider(networkName) } catch (error) { console.log('Unable to connect to zkSync.') console.log(error) } return zkSyncProvider } async function getEthereumProvider (ethers, networkName) { let ethersProvider try { // eslint-disable-next-line new-cap ethersProvider = new ethers.getDefaultProvider(networkName) } catch (error) { console.log('Could not connect to Rinkeby') console.log(error) } return ethersProvider } async function initAccount (rinkebyWallet, zkSyncProvider, zksync) { const zkSyncWallet = await zksync.Wallet.fromEthSigner(rinkebyWallet, zkSyncProvider) return zkSyncWallet } async function registerAccount (wallet) { console.log(`Registering the ${wallet.address()} account on zkSync`) if (!await wallet.isSigningKeySet()) { if (await wallet.getAccountId() === undefined) { throw new Error('Unknown account') } const changePubkey = await wallet.setSigningKey() await changePubkey.awaitReceipt() } console.log(`Account ${wallet.address()} registered`) } // Start here
async function getZkSyncProvider (zksync, networkName) { let zkSyncProvider try { zkSyncProvider = await zksync.getDefaultProvider(networkName) } catch (error) { console.log('Unable to connect to zkSync.') console.log(error) } return zkSyncProvider } async function getEthereumProvider (ethers, networkName) { let ethersProvider try { // eslint-disable-next-line new-cap ethersProvider = new ethers.getDefaultProvider(networkName) } catch (error) { console.log('Could not connect to Rinkeby') console.log(error) } return ethersProvider } async function initAccount (rinkebyWallet, zkSyncProvider, zksync) { const zkSyncWallet = await zksync.Wallet.fromEthSigner(rinkebyWallet, zkSyncProvider) return zkSyncWallet } async function registerAccount (wallet) { console.log(`Registering the ${wallet.address()} account on zkSync`) if (!await wallet.isSigningKeySet()) { if (await wallet.getAccountId() === undefined) { throw new Error('Unknown account') } const changePubkey = await wallet.setSigningKey() await changePubkey.awaitReceipt() } console.log(`Account ${wallet.address()} registered`) } async function depositToZkSync (zkSyncWallet, token, amountToDeposit, ethers) { const deposit = await zkSyncWallet.depositToSyncFromEthereum({ depositTo: zkSyncWallet.address(), token: token, amount: ethers.utils.parseEther(amountToDeposit) }) try { await deposit.awaitReceipt() } catch (error) { console.log('Error while awaiting confirmation from the zkSync operators.') console.log(error) } }

In this chapter, you're going to learn about the two types of operations a user can perform on zkSync:

  • Priority operations. These are actions users initiate on the Ethereum network. Can you think of an example? Yup, deposits are priority operations.👏🏻👏🏻👏🏻

  • Transactions. These are actions users initiate on zkSync. An example of a transaction is when Alice makes a payment on zkSync.

    Note the following about zkSync transactions:

    • When you submit a transaction to zkSync, it's instantly confirmed by the protocol. That's nice, but you should know that an instant confirmation is just a promise the operators make that they'll add the transaction to the next block. If you trust the operators then you don't need to wait for the transaction to be finalized.

    • A zkSync transaction is final after the SNARK proof is accepted by the Ethereum smart contract. This takes around 10 minutes.

In this chapter, we'll look into how you can deposit assets to zkSync.

Deposit assets to zkSync

Depositing assets to zkSync is as simple as calling the depositToSyncFromEthereum as follows:

const deposit = await zkSyncWallet.depositToSyncFromEthereum({
    depositTo: recipient,
    token: token,
    amount: amountInWei
  })

The parameters of this function are self-explanatory, so we won't spend time explaining them.

But what happens after you call this function?

First, the transaction gets mined on the Ethereum network. At this stage, the transaction is not yet reflected on zkSync. However, if you don't want your users to stare at a blank screen for too long and you trust this is secure enough, you can use the awaitEthereumTxCommit function to await for the deposit transaction to be mined:

await deposit.awaitEthereumTxCommit()

Second, the transaction is committed to zkSync. When this happens, your balance gets updated accordingly. To check when that happens, you can use the awaitReceipt function.

await deposit.awaitReceipt()

Lastly, once a specific number of blocks get confirmed on Ethereum, the transaction is considered finalized or verified. You can check this by calling the awaitVerifyReceipt function.

await deposit.awaitVerifyReceipt()

Note: You can only verify a single condition, not all. In this lesson, we'll use the deposit.awaitReceipt function. For our purposes, it's a good enough bargain between security and user experience.

Put it to the test

  1. Create an async function called depositToZkSync. It expects the following parameters: zkSyncWallet, token, amountToDeposit, and ethers.

  2. The first line of this function should call the depositToSyncFromEthereum function. Copy and paste the deposit example code at the start of this chapter, adjusting the following:

  • The depositTo should be set to the recipient's address. You can retrieve it by calling the zkSyncWallet.address function.
  • The protocol expects you to provide the amountToDeposit in wei. That's inconvenient because wei is the smallest sub-unit of Ether — there are 10^18 wei in one ether. To deposit 0.5 ETH, you'd have to declare the amountToDeposit variable as follows:
const amountToDeposit = '500000000000000000'

Luckily ethers provides a function named parseEther that does all the heavy lifting for you. The following example converts 0.5 ETH to wei, and prints the result to the console:

const amountToDeposit = '0.5'
const amountToDepositInWei = ethers.utils.parseEther(amountToDeposit)
console.log(amountToDepositInWei)

Let's replace amountInWei with ethers.utils.parseEther(amountToDeposit).

  1. Now, you would want to call the deposit.awaitReceipt() function to check whether your transaction is committed to zkSync. But just in case things go south with your deposit, let's wrap the line of code that calls this function inside of a try/catch statement. In JavaScript, a try/catch statement looks something like this:
try {
    doSomething()
  } catch (error) {
    doSomethingElse()
  }
  1. Inside of the try block, just call the deposit.awaitReceipt() function and await for the promise to resolve.

  2. Inside of the catch block, paste the following:

console.log('Error while awaiting confirmation from the zkSync operators.')
console.log(error)