diff --git a/src/main/java/io/zksync/abi/ZkTypeEncoder.java b/src/main/java/io/zksync/abi/ZkTypeEncoder.java index 3362f81..52965e8 100644 --- a/src/main/java/io/zksync/abi/ZkTypeEncoder.java +++ b/src/main/java/io/zksync/abi/ZkTypeEncoder.java @@ -188,17 +188,15 @@ static String encodeBytes(BytesType bytesType) { byte[] value = bytesType.getValue(); int length = value.length; int mod = length % MAX_BYTE_LENGTH; - String val = Numeric.toHexString(value); byte[] dest; if (mod != 0) { int padding = MAX_BYTE_LENGTH - mod; dest = new byte[padding]; - return Numeric.toHexStringNoPrefix(dest) + Numeric.toHexStringNoPrefix(value); + return Numeric.toHexStringNoPrefix(value) + Numeric.toHexStringNoPrefix(dest); } else { dest = value; } - String x = Numeric.toHexString(value); return Numeric.toHexStringNoPrefix(dest); } diff --git a/src/main/java/io/zksync/protocol/account/WalletL1.java b/src/main/java/io/zksync/protocol/account/WalletL1.java index f90eb5e..410191f 100644 --- a/src/main/java/io/zksync/protocol/account/WalletL1.java +++ b/src/main/java/io/zksync/protocol/account/WalletL1.java @@ -943,7 +943,7 @@ public CompletableFuture isWithdrawalFinalized(String txHash, int index return sharedBridge.isWithdrawalFinalized(chainId.join().getChainId(), receipt.getL1BatchNumber(), BigInteger.valueOf(proof.join().getId())).sendAsync(); } - public RemoteFunctionCall finalizeWithdraw(String txHash, int index) throws Exception { + public CompletableFuture finalizeWithdraw(String txHash, int index) throws Exception { ZkTransactionReceipt receipt = providerL2.zksGetTransactionReceipt(txHash).sendAsync().join().getResult(); int logIndex = getWithdrawalLogIndex(receipt.getLogs(), index); @@ -962,9 +962,21 @@ public RemoteFunctionCall finalizeWithdraw(String txHash, in merkle_proof.add(Numeric.hexStringToByteArray(l2ToL1MessageProof.getProof().get(i))); } - IL1Bridge il1Bridge = IL1Bridge.load(getL1BridgeContracts().sharedL1Bridge.getContractAddress(), providerL1, transactionManager, gasProvider); + String il1BridgeAddress = getL1BridgeContracts().sharedL1Bridge.getContractAddress(); - return il1Bridge.finalizeWithdrawal(providerL2.ethChainId().sendAsync().join().getChainId(), l1BatchNumber, BigInteger.valueOf(l2ToL1MessageProof.getId()), receipt.getL1BatchTxIndex(), bytes_data, merkle_proof); + String calldata = IL1SharedBridge.encodeFinalizeWithdrawal( + providerL2.ethChainId().sendAsync().join().getChainId(), + l1BatchNumber, + BigInteger.valueOf(l2ToL1MessageProof.getId()), + receipt.getL1BatchTxIndex(), + bytes_data, + merkle_proof + ); + + Transaction tx = Transaction.createEthCallTransaction(credentials.getAddress(), il1BridgeAddress, calldata); + BigInteger gas = providerL1.ethEstimateGas(tx).sendAsync().join().getAmountUsed(); + + return providerL1.ethSendRawTransaction(Numeric.toHexStringNoPrefix(TransactionEncoder.signMessage(RawTransaction.createTransaction(providerL1.ethGetTransactionCount(signer.getAddress(), DefaultBlockParameterName.LATEST).sendAsync().join().getTransactionCount(), providerL1.ethGasPrice().sendAsync().join().getGasPrice(), gas, il1BridgeAddress, calldata), credentials))).sendAsync(); } public int getWithdrawalLogIndex(List logs, int index){ diff --git a/src/main/java/io/zksync/wrappers/IL1SharedBridge.java b/src/main/java/io/zksync/wrappers/IL1SharedBridge.java index 838befb..25e6ccd 100644 --- a/src/main/java/io/zksync/wrappers/IL1SharedBridge.java +++ b/src/main/java/io/zksync/wrappers/IL1SharedBridge.java @@ -7,7 +7,10 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; + +import io.zksync.abi.ZkFunctionEncoder; import org.web3j.abi.EventEncoder; +import org.web3j.abi.FunctionEncoder; import org.web3j.abi.TypeReference; import org.web3j.abi.datatypes.Address; import org.web3j.abi.datatypes.Bool; @@ -447,6 +450,21 @@ public RemoteFunctionCall depositLegacyErc20Bridge(String _m return executeRemoteCallTransaction(function, weiValue); } + public static String encodeFinalizeWithdrawal(BigInteger _chainId, BigInteger _l2BatchNumber, BigInteger _l2MessageIndex, BigInteger _l2TxNumberInBatch, byte[] _message, List _merkleProof) { + final Function function = new Function( + FUNC_FINALIZEWITHDRAWAL, + Arrays.asList(new Uint256(_chainId), + new Uint256(_l2BatchNumber), + new Uint256(_l2MessageIndex), + new org.web3j.abi.datatypes.generated.Uint16(_l2TxNumberInBatch), + new DynamicBytes(_message), + new DynamicArray( + Bytes32.class, + org.web3j.abi.Utils.typeMap(_merkleProof, Bytes32.class))), + Collections.>emptyList()); + return ZkFunctionEncoder.encode(function); + } + public RemoteFunctionCall finalizeWithdrawal(BigInteger _chainId, BigInteger _l2BatchNumber, BigInteger _l2MessageIndex, BigInteger _l2TxNumberInBatch, byte[] _message, List _merkleProof) { final Function function = new Function( FUNC_FINALIZEWITHDRAWAL, diff --git a/src/test/java/io/zksync/integration/account/WalletTest.java b/src/test/java/io/zksync/integration/account/WalletTest.java index 895f326..2a29679 100644 --- a/src/test/java/io/zksync/integration/account/WalletTest.java +++ b/src/test/java/io/zksync/integration/account/WalletTest.java @@ -434,8 +434,9 @@ public void testWithdrawEth() throws Exception { TransactionReceipt result = testWallet.withdraw(transaction).sendAsync().join(); TransactionReceipt receipt = testWallet.getTransactionReceiptProcessor().waitFinalized(result.getTransactionHash()); - TransactionReceipt finalizeWithdraw = testWallet.finalizeWithdraw(receipt.getTransactionHash(), 0).sendAsync().join(); - + assertFalse(testWallet.isWithdrawalFinalized(receipt.getTransactionHash(), 0).join()); + EthSendTransaction finalizeWithdraw = testWallet.finalizeWithdraw(receipt.getTransactionHash(), 0).join(); + assertNotNull(finalizeWithdraw.getResult()); BigInteger senderAfter = testWallet.getBalance().sendAsync().join(); assertNotNull(receipt); @@ -476,7 +477,8 @@ public void testWithdrawErc20() throws Exception { TransactionReceipt result = testWallet.withdraw(transaction).sendAsync().join(); TransactionReceipt receipt = testWallet.getTransactionReceiptProcessor().waitFinalized(result.getTransactionHash()); - TransactionReceipt finalizeWithdraw = testWallet.finalizeWithdraw(receipt.getTransactionHash(), 0).sendAsync().join(); + EthSendTransaction finalizeWithdraw = testWallet.finalizeWithdraw(receipt.getTransactionHash(), 0).join(); + assertNotNull(finalizeWithdraw.getResult()); BigInteger senderAfter = testWallet.getBalance(l2DAI).sendAsync().join(); assertNotNull(receipt);