今天將會透過 Lession 18 - Advanced zkSync Concept 來了解
透過 zkSync 如何做到 ERC20 token 交換。
假設要透過 zkSync 做 ERC20 Token 做交換
這邊會以 USDT 作為範例
首先需要先取得 Rinkeby 鏈上的 USDT token
取得流程如下
首先比需要先設定好 src/alice.js 來操作 USDT
更新如下
(async () => {
const ethers = require('ethers')
const zksync = require('zksync')
const utils = require('./utils')
const token = 'USDT' // Update this line
const amountToDeposit = '6.0' // Update this line
const amountToTransfer = '2.0' // Update this line
const amountToWithdraw = '2.0' // Update this line
const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME)
const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME)
console.log('Creating a new Rinkeby wallet for Alice')
const aliceRinkebyWallet = new ethers.Wallet(process.env.ALICE_PRIVATE_KEY, ethersProvider)
console.log(`Alice's Rinkeby address is: ${aliceRinkebyWallet.address}`)
const aliceInitialRinkebyBalance = await aliceRinkebyWallet.getBalance()
console.log(`Alice's initial balance on Rinkeby is: ${ethers.utils.formatEther(aliceInitialRinkebyBalance)}`)
console.log('Creating a zkSync wallet for Alice')
const aliceZkSyncWallet = await utils.initAccount(aliceRinkebyWallet, zkSyncProvider, zksync)
console.log('Depositing')
await utils.depositToZkSync(aliceZkSyncWallet, token, amountToDeposit, ethers)
await utils.displayZkSyncBalance(aliceZkSyncWallet, ethers)
await utils.registerAccount(aliceZkSyncWallet)
console.log('Transferring')
const transferFee = await utils.getFee('Transfer', aliceRinkebyWallet.address, token, zkSyncProvider, ethers)
await utils.transfer(aliceZkSyncWallet, process.env.BOB_ADDRESS, amountToTransfer, transferFee, token, zksync, ethers)
console.log('Withdrawing')
const withdrawalFee = await utils.getFee('Withdraw', aliceRinkebyWallet.address, token, zkSyncProvider, ethers)
await utils.withdrawToEthereum(aliceZkSyncWallet, amountToWithdraw, withdrawalFee, token, zksync, ethers)
})()
之前使用 ethers.util.formatEther 來對 ETH 單位做處理
但這邊需要使用 TokenSet 來做這件事
zkSync 提供 TokenSet 這個類別來做單位轉換的功能
為了方便使用會使用以下語法把 zkSyncProvider.tokenSet 重新存入 const tokenSet
const tokenSet = zkSyncProvider.tokenSet
可以使用以下語法把一般表示式轉為 BigNumber
const amountAsBigNumber = tokenSet.parseToken(token, amountInHumanReadableForm)
可以使用以下語法把 BigNumber 轉為一般單位
const amountInHumanReadableForm = tokenSet.formatToken(token, amountAsBigNumber)
需要使用 zksync.Wallet 物件的 getEthereumBalance 來取得 USDT balance
語法如下
const yourUSDTBalance = await yourZkSyncWallet.getEthereumBalance(token)
更新如下
(async () => {
const ethers = require('ethers')
const zksync = require('zksync')
const utils = require('./utils')
const token = 'USDT'
const amountToDeposit = '6.0'
const amountToTransfer = '2.0'
const amountToWithdraw = '2.0'
const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME)
const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME)
console.log('Creating a new Rinkeby wallet for Alice')
const aliceRinkebyWallet = new ethers.Wallet(process.env.ALICE_PRIVATE_KEY, ethersProvider)
console.log(`Alice's Rinkeby address is: ${aliceRinkebyWallet.address}`)
// 2. Cut this line
console.log('Creating a zkSync wallet for Alice')
const aliceZkSyncWallet = await utils.initAccount(aliceRinkebyWallet, zkSyncProvider, zksync)
// 3. Instantiate the `tokenSet` class
const tokenSet = zkSyncProvider.tokenSet
// 4. Retrieve Alice's initial USDT balance on Rinkeby
const aliceInitialRinkebyBalance = await aliceZkSyncWallet.getEthereumBalance(token)
// 5. Display Alice's balance
console.log(`Alice's initial balance on Rinkeby is: ${tokenSet.formatToken(token, aliceInitialRinkebyBalance)}`)
console.log('Depositing')
await utils.depositToZkSync(aliceZkSyncWallet, token, amountToDeposit, ethers)
await utils.displayZkSyncBalance(aliceZkSyncWallet, ethers)
await utils.registerAccount(aliceZkSyncWallet)
console.log('Transferring')
const transferFee = await utils.getFee('Transfer', aliceRinkebyWallet.address, token, zkSyncProvider, ethers)
await utils.transfer(aliceZkSyncWallet, process.env.BOB_ADDRESS, amountToTransfer, transferFee, token, zksync, ethers)
console.log('Withdrawing')
const withdrawalFee = await utils.getFee('Withdraw', aliceRinkebyWallet.address, token, zkSyncProvider, ethers)
await utils.withdrawToEthereum(aliceZkSyncWallet, amountToWithdraw, withdrawalFee, token, zksync, ethers)
})()
更新如下
(async () => {
const ethers = require('ethers')
const zksync = require('zksync')
const utils = require('./utils')
const token = 'USDT'
const amountToDeposit = '6.0'
const amountToTransfer = '2.0'
const amountToWithdraw = '2.0'
const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME)
const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME)
console.log('Creating a new Rinkeby wallet for Alice')
const aliceRinkebyWallet = new ethers.Wallet(process.env.ALICE_PRIVATE_KEY, ethersProvider)
console.log(`Alice's Rinkeby address is: ${aliceRinkebyWallet.address}`)
console.log('Creating a zkSync wallet for Alice')
const aliceZkSyncWallet = await utils.initAccount(aliceRinkebyWallet, zkSyncProvider, zksync)
const tokenSet = zkSyncProvider.tokenSet
const aliceInitialRinkebyBalance = await aliceZkSyncWallet.getEthereumBalance(token)
console.log(`Alice's initial balance on Rinkeby is: ${tokenSet.formatToken(token, aliceInitialRinkebyBalance)}`)
// Start here
await aliceZkSyncWallet.approveERC20TokenDeposits(token)
console.log('Depositing')
await utils.depositToZkSync(aliceZkSyncWallet, token, amountToDeposit, ethers)
await utils.displayZkSyncBalance(aliceZkSyncWallet, ethers)
await utils.registerAccount(aliceZkSyncWallet)
console.log('Transferring')
const transferFee = await utils.getFee('Transfer', aliceRinkebyWallet.address, token, zkSyncProvider, ethers)
await utils.transfer(aliceZkSyncWallet, process.env.BOB_ADDRESS, amountToTransfer, transferFee, token, zksync, ethers)
console.log('Withdrawing')
const withdrawalFee = await utils.getFee('Withdraw', aliceRinkebyWallet.address, token, zkSyncProvider, ethers)
await utils.withdrawToEthereum(aliceZkSyncWallet, amountToWithdraw, withdrawalFee, token, zksync, ethers)
})()
更新如下
(async () => {
const ethers = require('ethers')
const zksync = require('zksync')
const utils = require('./utils')
const token = 'USDT'
const amountToDeposit = '6.0'
const amountToTransfer = '2.0'
const amountToWithdraw = '2.0'
const zkSyncProvider = await utils.getZkSyncProvider(zksync, process.env.NETWORK_NAME)
const ethersProvider = await utils.getEthereumProvider(ethers, process.env.NETWORK_NAME)
console.log('Creating a new Rinkeby wallet for Alice')
const aliceRinkebyWallet = new ethers.Wallet(process.env.ALICE_PRIVATE_KEY, ethersProvider)
console.log(`Alice's Rinkeby address is: ${aliceRinkebyWallet.address}`)
console.log('Creating a zkSync wallet for Alice')
const aliceZkSyncWallet = await utils.initAccount(aliceRinkebyWallet, zkSyncProvider, zksync)
const tokenSet = zkSyncProvider.tokenSet
const aliceInitialRinkebyBalance = await aliceZkSyncWallet.getEthereumBalance(token)
console.log(`Alice's initial balance on Rinkeby is: ${tokenSet.formatToken(token, aliceInitialRinkebyBalance)}`)
await aliceZkSyncWallet.approveERC20TokenDeposits(token)
console.log('Depositing')
await utils.depositToZkSync(aliceZkSyncWallet, token, amountToDeposit, tokenSet) // Update this line
await utils.displayZkSyncBalance(aliceZkSyncWallet, tokenSet) // Update this line
await utils.registerAccount(aliceZkSyncWallet)
console.log('Transferring')
const transferFee = await utils.getFee('Transfer', aliceRinkebyWallet.address, token, zkSyncProvider, tokenSet) // Update this line
await utils.transfer(aliceZkSyncWallet, process.env.BOB_ADDRESS, amountToTransfer, transferFee, token, zksync, tokenSet) // Update this line
console.log('Withdrawing')
const withdrawalFee = await utils.getFee('Withdraw', aliceRinkebyWallet.address, token, zkSyncProvider, tokenSet) // Update this line
await utils.withdrawToEthereum(aliceZkSyncWallet, amountToWithdraw, withdrawalFee, token, zksync, tokenSet) // Update this line
})()
更新如下
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`)
}
//1. On the next line, replace the last parameter (`ethers`) with `tokenSet`
async function depositToZkSync (zkSyncWallet, token, amountToDeposit, tokenSet ) {
const deposit = await zkSyncWallet.depositToSyncFromEthereum({
depositTo: zkSyncWallet.address(),
token: token,
amount: tokenSet.parseToken(token, amountToDeposit) //2. Call the `tokenSet.parseToken` function
})
try {
await deposit.awaitReceipt()
} catch (error) {
console.log('Error while awaiting confirmation from the zkSync operators.')
console.log(error)
}
}
async function transfer (from, toAddress, amountToTransfer, transferFee, token, zksync, ethers) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(
ethers.utils.parseEther(amountToTransfer))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(
ethers.utils.parseEther(transferFee))
const transfer = await from.syncTransfer({
to: toAddress,
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
const transferReceipt = await transfer.awaitReceipt()
console.log('Got transfer receipt.')
console.log(transferReceipt)
}
async function getFee(transactionType, address, token, zkSyncProvider, ethers) {
const feeInWei = await zkSyncProvider.getTransactionFee(transactionType, address, token)
return ethers.utils.formatEther(feeInWei.totalFee.toString())
}
async function withdrawToEthereum (wallet, amountToWithdraw, withdrawalFee, token, zksync, ethers) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(ethers.utils.parseEther(amountToWithdraw))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(ethers.utils.parseEther(withdrawalFee))
const withdraw = await wallet.withdrawFromSyncToEthereum({
ethAddress: wallet.address(),
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
await withdraw.awaitVerifyReceipt()
console.log('ZKP verification is complete')
}
async function displayZkSyncBalance (wallet, ethers) {
const state = await wallet.getAccountState()
if (state.committed.balances.ETH) {
console.log(`Commited ETH balance for ${wallet.address()}: ${ethers.utils.formatEther(state.committed.balances.ETH)}`)
} else {
console.log(`Commited ETH balance for ${wallet.address()}: 0`)
}
if (state.verified.balances.ETH) {
console.log(`Verified ETH balance for ${wallet.address()}: ${ethers.utils.formatEther(state.verified.balances.ETH)}`)
} else {
console.log(`Verified ETH balance for ${wallet.address()}: 0`)
}
}
module.exports = {
getZkSyncProvider,
getEthereumProvider,
depositToZkSync,
registerAccount,
displayZkSyncBalance,
transfer,
withdrawToEthereum,
getFee,
initAccount
}
透過 wallet.getAccountState 可以讀取到 state 物件
語法如下
const state = await wallet.getAccountState()
假設把 state 列印出來會發現結果如下
{ address: '0xc26f2adeeebbad73f25329ffa12cd3889429b5b6',
committed:
{ balances: { ETH: '99891300000000000', USDT: '241896200' },
nonce: 5,
pubKeyHash: 'sync:de9de11bdad08aa1cdc2beb5b2b7c7f29c10f079' },
depositing: { balances: {} },
id: 83,
verified:
{ balances: { ETH: '99891300000000000', USDT: '235896200' },
nonce: 5,
pubKeyHash: 'sync:de9de11bdad08aa1cdc2beb5b2b7c7f29c10f079' }
}
for (const property in committedBalances) {
console.log(`Committed ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, committedBalances[property])}`)
}
for (const property in verifiedBalances) {
console.log(`Committed ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, verifiedBalances[property])}`)
}
更新如下
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, tokenSet) {
const deposit = await zkSyncWallet.depositToSyncFromEthereum({
depositTo: zkSyncWallet.address(),
token: token,
amount: tokenSet.parseToken(token, amountToDeposit)
})
try {
await deposit.awaitReceipt()
} catch (error) {
console.log('Error while awaiting confirmation from the zkSync operators.')
console.log(error)
}
}
async function transfer (from, toAddress, amountToTransfer, transferFee, token, zksync, ethers) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(
ethers.utils.parseEther(amountToTransfer))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(
ethers.utils.parseEther(transferFee))
const transfer = await from.syncTransfer({
to: toAddress,
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
const transferReceipt = await transfer.awaitReceipt()
console.log('Got transfer receipt.')
console.log(transferReceipt)
}
async function getFee(transactionType, address, token, zkSyncProvider, ethers) {
const feeInWei = await zkSyncProvider.getTransactionFee(transactionType, address, token)
return ethers.utils.formatEther(feeInWei.totalFee.toString())
}
async function withdrawToEthereum (wallet, amountToWithdraw, withdrawalFee, token, zksync, ethers) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(ethers.utils.parseEther(amountToWithdraw))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(ethers.utils.parseEther(withdrawalFee))
const withdraw = await wallet.withdrawFromSyncToEthereum({
ethAddress: wallet.address(),
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
await withdraw.awaitVerifyReceipt()
console.log('ZKP verification is complete')
}
// 1. On the next line, replace the last parameter (`ethers`) with `tokenSet`
async function displayZkSyncBalance (wallet, tokenSet) {
const state = await wallet.getAccountState()
// 2. Continue here
const committedBalances = state.committed.balances
const verifiedBalances = state.verified.balances
for (const property in committedBalances) {
console.log(`Commited ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, committedBalances[property])}`)
}
for (const property in verifiedBalances) {
console.log(`Verified ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, verifiedBalances[property])}`)
}
}
module.exports = {
getZkSyncProvider,
getEthereumProvider,
depositToZkSync,
registerAccount,
displayZkSyncBalance,
transfer,
withdrawToEthereum,
getFee,
initAccount
}
更新如下
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, tokenSet) {
const deposit = await zkSyncWallet.depositToSyncFromEthereum({
depositTo: zkSyncWallet.address(),
token: token,
amount: tokenSet.parseToken(token, amountToDeposit)
})
try {
await deposit.awaitReceipt()
} catch (error) {
console.log('Error while awaiting confirmation from the zkSync operators.')
console.log(error)
}
}
// 1. On the next line, replace the last parameter (`ethers`) with `tokenSet`
async function transfer (from, toAddress, amountToTransfer, transferFee, token, zksync, tokenSet) {
// 2. Update the following two lines of code
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(
tokenSet.parseToken(token, amountToTransfer))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(
tokenSet.parseToken(token, transferFee))
const transfer = await from.syncTransfer({
to: toAddress,
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
const transferReceipt = await transfer.awaitReceipt()
console.log('Got transfer receipt.')
console.log(transferReceipt)
}
async function getFee(transactionType, address, token, zkSyncProvider, ethers) {
const feeInWei = await zkSyncProvider.getTransactionFee(transactionType, address, token)
return ethers.utils.formatEther(feeInWei.totalFee.toString())
}
async function withdrawToEthereum (wallet, amountToWithdraw, withdrawalFee, token, zksync, ethers) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(ethers.utils.parseEther(amountToWithdraw))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(ethers.utils.parseEther(withdrawalFee))
const withdraw = await wallet.withdrawFromSyncToEthereum({
ethAddress: wallet.address(),
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
await withdraw.awaitVerifyReceipt()
console.log('ZKP verification is complete')
}
async function displayZkSyncBalance (wallet, tokenSet) {
const state = await wallet.getAccountState()
const commitedBbalances = state.committed.balances
const verifiedBalances = state.verified.balances
for (const property in commitedBbalances) {
console.log(`Commited ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, commitedBbalances[property])}`)
}
for (const property in verifiedBalances) {
console.log(`Verified ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, verifiedBalances[property])}`)
}
}
module.exports = {
getZkSyncProvider,
getEthereumProvider,
depositToZkSync,
registerAccount,
displayZkSyncBalance,
transfer,
withdrawToEthereum,
getFee,
initAccount
}
更新如下
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, tokenSet) {
const deposit = await zkSyncWallet.depositToSyncFromEthereum({
depositTo: zkSyncWallet.address(),
token: token,
amount: tokenSet.parseToken(token, amountToDeposit)
})
try {
await deposit.awaitReceipt()
} catch (error) {
console.log('Error while awaiting confirmation from the zkSync operators.')
console.log(error)
}
}
async function transfer (from, toAddress, amountToTransfer, transferFee, token, zksync, tokenSet) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(tokenSet.parseToken(token, amountToTransfer))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(tokenSet.parseToken(token, transferFee))
const transfer = await from.syncTransfer({
to: toAddress,
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
const transferReceipt = await transfer.awaitReceipt()
console.log('Got transfer receipt.')
console.log(transferReceipt)
}
async function getFee(transactionType, address, token, zkSyncProvider, ethers) {
const feeInWei = await zkSyncProvider.getTransactionFee(transactionType, address, token)
return ethers.utils.formatEther(feeInWei.totalFee.toString())
}
// 1. On the next line, replace the last parameter (`ethers`) with `tokenSet`
async function withdrawToEthereum (wallet, amountToWithdraw, withdrawalFee, token, zksync, tokenSet) {
// 2. Update the following two lines of code
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(tokenSet.parseToken(token, amountToWithdraw))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(tokenSet.parseToken(token, withdrawalFee))
const withdraw = await wallet.withdrawFromSyncToEthereum({
ethAddress: wallet.address(),
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
await withdraw.awaitVerifyReceipt()
console.log('ZKP verification is complete')
}
async function displayZkSyncBalance (wallet, tokenSet) {
const state = await wallet.getAccountState()
const commitedBbalances = state.committed.balances
const verifiedBalances = state.verified.balances
for (const property in commitedBbalances) {
console.log(`Commited ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, commitedBbalances[property])}`)
}
for (const property in verifiedBalances) {
console.log(`Verified ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, verifiedBalances[property])}`)
}
}
module.exports = {
getZkSyncProvider,
getEthereumProvider,
depositToZkSync,
registerAccount,
displayZkSyncBalance,
transfer,
withdrawToEthereum,
getFee,
initAccount
}
更新如下
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, tokenSet) {
const deposit = await zkSyncWallet.depositToSyncFromEthereum({
depositTo: zkSyncWallet.address(),
token: token,
amount: tokenSet.parseToken(token, amountToDeposit)
})
try {
await deposit.awaitReceipt()
} catch (error) {
console.log('Error while awaiting confirmation from the zkSync operators.')
console.log(error)
}
}
async function transfer (from, toAddress, amountToTransfer, transferFee, token, zksync, tokenSet) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(tokenSet.parseToken(token, amountToTransfer))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(tokenSet.parseToken(token, transferFee))
const transfer = await from.syncTransfer({
to: toAddress,
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
const transferReceipt = await transfer.awaitReceipt()
console.log('Got transfer receipt.')
console.log(transferReceipt)
}
// 1. On the next line, replace the last parameter (`ethers`) with `tokenSet`
async function getFee(transactionType, address, token, zkSyncProvider, tokenSet) {
const fee = await zkSyncProvider.getTransactionFee(transactionType, address, token)
// 2. On the next line, use the `tokenSet` object instead of `ethers.utils.formatEther`
return tokenSet.formatToken(token, fee.totalFee)
}
async function withdrawToEthereum (wallet, amountToWithdraw, withdrawalFee, token, zksync, tokenSet) {
const closestPackableAmount = zksync.utils.closestPackableTransactionAmount(tokenSet.parseToken(token, amountToWithdraw))
const closestPackableFee = zksync.utils.closestPackableTransactionFee(tokenSet.parseToken(token, withdrawalFee))
const withdraw = await wallet.withdrawFromSyncToEthereum({
ethAddress: wallet.address(),
token: token,
amount: closestPackableAmount,
fee: closestPackableFee
})
await withdraw.awaitVerifyReceipt()
console.log('ZKP verification is complete')
}
async function displayZkSyncBalance (wallet, tokenSet) {
const state = await wallet.getAccountState()
const commitedBbalances = state.committed.balances
const verifiedBalances = state.verified.balances
for (const property in commitedBbalances) {
console.log(`Commited ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, commitedBbalances[property])}`)
}
for (const property in verifiedBalances) {
console.log(`Verified ${property} balance for ${wallet.address()}: ${tokenSet.formatToken(property, verifiedBalances[property])}`)
}
}
module.exports = {
getZkSyncProvider,
getEthereumProvider,
depositToZkSync,
registerAccount,
displayZkSyncBalance,
transfer,
withdrawToEthereum,
getFee,
initAccount
}