Accounts: L1->L2 transactions


Accounts: L1->L2 transactions

This section explores the methods which allow the account classes to send transactions from L1 to L2.

If you want to get some background on how L1->L2 interaction works on zkSync Era, go through the introduction.

The zkSync Python SDK account is compatible with the eth_account package, and in most cases users can have their private key and get account instances by using it.

Example


from eth_account import Account
from eth_account.signers.local import LocalAccount
...
account: LocalAccount = Account.from_key("PRIVATE_KEY")

The base property that is used directly with account is: Account.address.

Depositing tokens to zkSync Era

Returns the transaction receipt of the deposit.


def deposit(self, l2_receiver: HexStr, l1_token: HexStr, amount: int) -> txn_receipt

Arguments

NameDescription
l2_receiverThe address that will receive the deposited tokens on L2.
l1_tokenThe address of the deposited L1 ERC20 token.
amountThe amount of the token to be deposited.

Example


def deposit(self, l2_receiver: HexStr, l1_token: HexStr, amount: int):
        tx = self.contract.functions.deposit(l2_receiver,
                                             l1_token,
                                             amount).build_transaction(
            {
                "chainId": self.web3.eth.chain_id,
                "from": self.account.address,
                "nonce": self._get_nonce(),
                "gas": self.gas_provider.gas_limit(),
                "gasPrice": self.gas_provider.gas_price(),
                "value": amount
            })
        signed_tx = self.account.sign_transaction(tx)
        txn_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
        txn_receipt = self.web3.eth.wait_for_transaction_receipt(txn_hash)
        return txn_receipt

Claim failed deposit

The claimFailedDeposit method withdraws funds from the initiated deposit, which failed when finalizing on L2.
If the deposit L2 transaction has failed, it sends an L1 transaction calling claimFailedDeposit method of the L1 bridge, which results in returning L1 tokens back to the depositor, otherwise throws the error.


 def claim_failed_deposit(self, deposit_sender: HexStr,
                             l1_token: HexStr,
                             l2tx_hash,
                             l2_block_number: int,
                             l2_msg_index: int,
                             merkle_proof: List[bytes]) -> TxReceipt

Arguments

NameDescription
deposit_senderThe address of the deposit initiator.
l2tx_hashThe L2 transaction hash of the failed deposit finalization.
l1_tokenThe address of the deposited L1 ERC20 token.
l2_block_numberThe L2 block number where the deposit finalization was processed.
l2_msg_indexThe position in the L2 logs Merkle tree of the l2Log that was sent with the message.
merkle_proofThe Merkle proof of the processing L1 -> L2 transaction with deposit finalization

Finalizing withdrawals

Withdrawals are executed in 2 steps - initiated on L2 and finalized on L1, this method returns the transaction receipt of the withdrawals.


def finalize_withdrawal(self,
                            l2_block_number: int,
                            l2_msg_index: int,
                            msg: bytes,
                            merkle_proof: List[bytes]) -> txn_receipt

Arguments

NameDescription
l2_block_numberThe L2 block number where the deposit finalization was processed.
l2_msg_indexThe position in the L2 logs Merkle tree of the l2Log that was sent with the message.
l2_msg_indexThe position in the L2 logs Merkle tree of the l2Log that was sent with the message.
merkle_proofThe Merkle proof of the processing L1 -> L2 transaction with deposit finalization

Example


def finalize_withdrawal(self,
                        l2_block_number: int,
                        l2_msg_index: int,
                        msg: bytes,
                        merkle_proof: List[bytes]):
    tx = self.contract.functions.finalizeWithdrawal(l2_block_number,
                                                    l2_msg_index,
                                                    msg,
                                                    merkle_proof).build_transaction(
        {
            "chainId": self.web3.eth.chain_id,
            "from": self.account.address,
            "nonce": self._get_nonce(),
            "gas": self.gas_provider.gas_limit(),
            "gasPrice": self.gas_provider.gas_price()
        })
    signed_tx = self.account.sign_transaction(tx)
    txn_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
    txn_receipt = self.web3.eth.wait_for_transaction_receipt(txn_hash)
    return txn_receipt