如何创建 ZkSync 帐户?

How to create a ZkSync account?

ZkSync documentation 声明必须从现有的以太坊账户向不存在的 ZkSync 账户反事实地存入资金才能创建新账户。

但是,用于充值的method已经将ZkSync账户地址作为参数指定收款人:

/// @notice Deposit ETH to Layer 2 - transfer ether from user into contract, validate it, register deposit
/// @param _zkSyncAddress The receiver Layer 2 address
function depositETH(address _zkSyncAddress) external payable {
    require(_zkSyncAddress != SPECIAL_ACCOUNT_ADDRESS, "P");
    require(msg.value > 0, "M"); // Zero-value deposits are forbidden by zkSync rollup logic
    requireActive();
    registerDeposit(0, SafeCast.toUint128(msg.value), _zkSyncAddress);
}

如果这正是我们想要实现的目标,我们如何传递 ZkSync 帐户地址?

如果您查看 one of examples ZkSync 团队为 Swift SDK 提供的内容:

let ethereumProvider = try self.wallet.createEthereumProvider(web3: Web3.InfuraRinkebyWeb3())

firstly {
    ethereumProvider.deposit(token: .ETH,
                             amount: amount,
                             userAddress: wallet.address) /// Ethereum wallet address is provided
}.done { (_) in
    self.present(UIAlertController.for(message: "Successfully deposited"), animated: true, completion: nil)
}.catch { (error) in
    self.present(UIAlertController.for(error: error), animated: true, completion: nil)
}

存款参数是发送方的地址,即以太坊网络上的账户,而不是ZkSync。

Source

func depositETH(address: EthereumAddress, value: BigUInt) -> Promise<TransactionSendingResult> {
    guard let tx = self.contract.write("depositETH",
                                       parameters: [address] as [AnyObject], // here the parameter passed for the depositETH method of the smart contract is the address of the sender's account, which is the Ethereum account.
                                       transactionOptions: createOptions(value: value)) else {
        return Promise(error: ZkSyncContractError.invalidParameters)
    }

    return tx.sendPromise()
}

如果执行上面的代码,会出现以下错误:

根据 web3swift 源代码,这个神秘的错误似乎表明连接错误,因为它似乎说错误 1。

public enum Web3Error: Error {
    case transactionSerializationError
    case connectionError
    case dataError
    case walletError
    case inputError(desc:String)
    case nodeError(desc:String)
    case processingError(desc:String)
    case keystoreError(err:AbstractKeystoreError)
    case generalError(err:Error)
    case unknownError

那么,为了创建一个新的 ZkSync 帐户,您必须将什么地址传递给存款方法?通过传递以太坊帐户的发件人地址,Swift SDK 示例是否正确?如果是这样,错误的来源是什么?

更新

Swift SDK 示例代码中的存款流程顺序如下:

  1. 创建了一个wallet
guard let wallet = try? DefaultWallet<ChangePubKeyECDSA, DefaultEthSigner>(ethSigner: ethSigner,
                                                                           zkSigner: zkSigner,
                                                                           provider: provider) else {
    fatalError()
}
  1. 钱包被传递给存款视图控制器并用于send a deposit
let ethereumProvider = try self.wallet.createEthereumProvider(web3: Web3.InfuraRinkebyWeb3())

firstly {
    ethereumProvider.deposit(token: .ETH,
                             amount: amount,
                             userAddress: wallet.address)
}.done { (_) in
    self.present(UIAlertController.for(message: "Successfully deposited"), animated: true, completion: nil)
}.catch { (error) in
    self.present(UIAlertController.for(error: error), animated: true, completion: nil)
}

但是,如果我的理解正确的话,存款方法中的 userAddress 参数应该是收件人的地址。然而,wallet.addressaddress of the sender.

public var address: String {
    self.ethSigner.address
}

在调用存款方法之前,我生成了一个新的以太坊地址来发送资金,希望它能在Zksync中生成一个新的账户,但仍然出现同样的错误。

KeysService().getWalletPrivateKey(password: password, completion: { [weak self] privateKey, error in
    if let error = error {
        print(error)
    }
    
    if let privateKey = privateKey {
        do {

            guard let newWallet = self?.createZKWallet(.rinkeby, privateKey: privateKey) else { return }
            let ethereumProvider = try newWallet.createEthereumProvider(web3: Web3.InfuraRinkebyWeb3())

            firstly {
                ethereumProvider.deposit(token: .ETH,
                                         amount: amount,
                                         userAddress: newWallet.address)
            }.done { (_) in
                self?.present(UIAlertController.for(message: "Successfully deposited"), animated: true, completion: nil)
            }.catch { (error) in
                self?.present(UIAlertController.for(error: error), animated: true, completion: nil)
            }
        } catch {
            self?.present(UIAlertController.for(error: error), animated: true, completion: nil)
        }
    }
})

您需要传递一个新地址(收件人地址)。无法从您所说的 'non-existing' 地址发送。

您可以 'create' 通过从私钥随机生成地址,或者如果您已经知道地址,可以复制它。

与您的问题相关,示例应用使用的帐户目前在 Ethereum (0x46a23e25df9a0f6c18729dda9ad1af3b6a131160) 上没有任何资金(见屏幕截图)。我已经发送了少量,现在可以使用了。

要创建一个 zkSync 帐户,我们需要以某种方式与我们的钱包进行交互:f.e.: 我们可以从任何去中心化钱包 L1→L2 存款,这意味着该帐户已创建或进行转账到现有地址l2→l2,它也是可行的。但是要使用这笔资金,我们需要激活我们的 L2 - 制作 CPK,支付一些费用。否则我们将需要进行替代取款。