Deposit and call zEVM contracts from Bitcoin
This section is important for wallet and app developers.
All inputs and outputs of Bitcoin transactions sent to TSS address must be a P2WPKH address (SegWit bech32 address, such as bc1xxx on Bitcoin mainnet). Otherwise the transactions will not be observed and there will be no refund, and may cause irreversible user fund loss.
To deposit BTC into zEVM ZRC-20 contract (and optionally call a smart contract), the Bitcoin transaction must conform to this specifications:
- The Bitcoin transaction must have at least 2 outputs.
- The first output must be addressed to the TSS Bitcoin address.
- The second output must be a memo output, i.e.
OP_RETURN PUSH_x [DATA]
. This output must be less than 80 bytes. - The memo
[DATA]
is an array of bytes that encodes the recipient address of this deposit into ZRC-20 or the smart contract on zEVM that will be invoked by this transaction. - If the purpose of this Bitcoin transaction is to only deposit BTC into the
BTC ZRC-20 on zEVM, then the
[DATA]
should be exactly 20 bytes long, consists of an Ethereum-style address. - If the purpose of this Bitcoin transaction is to deposit BTC and also use the
deposited amount to call a smart contract on zEVM, then the
[DATA]
field must consists of a smart contract address, and a binary message that will be forwarded to the said smart contract:[DATA] = [zEVM contract address (20B)] + [arbitrary binary message]
Example 1: Deposit BTC into an account in zEVM
Here's an example Bitcoin transaction on Bitcoin Testnet that deposits 0.0005 tBTC (50000 sats) into the address (0x)6da30bfa65e85a16b05bce3846339ed2bc746316.
Note the three outputs:
- sending the intended amount (50000sats) to the current TSS Bitcoin address tb1qy9pqmk2pd9sv63g27jt8r657wy0d9ueeh0nqur.
- the memo output, encoding the recipient address on zEVM (0x)6a146da30bfa65e85a16b05bce3846339ed2bc746316.
- change sent back to the user.
If you're using ZetaChain's Hardhat
smart contract template, you can use
the send-btc
task to transfer BTC:
npx hardhat send-btc --recipient tb1qy9pqmk2pd9sv63g27jt8r657wy0d9ueeh0nqur --amount 0.0005 --memo 6a146da30bfa65e85a16b05bce3846339ed2bc746316
Where recipient
is the TSS Bitcoin address, amount
is the amount of tBTC to
transfer, and memo
is the recipient address on zEVM.
Example 2: Deposit BTC and call a smart contract in zEVM
In order to test with Bitcoin, you will need to use a wallet that allows setting
an OP_RETURN
and memos in a binary format. Please see our wallet suggestions
here.
If invalid information is sent (i. e. invalid address), the assets may be lost and not recoverable.
In summary, a zEVM BTC transaction would look like this:
- A user sends 1 BTC on Bitcoin network to the Bitcoin TSS address
(Testnet, Mainnet), adding a memo
(via
OP_RETURN
) in the tx saying (colloquially) “deposit to 0x1337”. - Upon receiving this tx, the ZetaCore state machine calls the deposit (0x1337, 1e8) to mint and credit 0x1337 with 1 zBTC minus fees.
- If 0x1337 is an Externally Owned Account (EOA), that's it. If it's a
contract, ZetaCore will call the
onCrossChainMessage
function sending the message that was specified in theOP_RETURN
memo.
The TSS address (Testnet, Mainnet) holds the BTC, where ownerships are tracked inside this BTC ZRC-20 contract.