On Bitcoin the gateway is implemented as an TSS MPC account. The private key securing the account is split into fragments and distributed among ZetaChain observer-signer validators.
Bitcoin gateway supports:
- depositing BTC to a universal app or an account on ZetaChain
- depositing BTC and calling a universal app
Overview
To deposit BTC into ZetaChain's Universal EVM (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 ZetaChain's EVM 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 ZetaChain's EVM, 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 ZetaChain's EVM, 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] = [ZetaChain's EVM contract address (20B)] - [arbitrary binary message]
Example 1: Deposit BTC into an account on ZetaChain's EVM
Here's (opens in a new tab) 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 ZetaChain's EVM (0x)6a146da30bfa65e85a16b05bce3846339ed2bc746316.
- change sent back to the user.
If you're using ZetaChain's Hardhat smart contract
template (opens in a new tab), 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 ZetaChain's EVM.
Example 2: Deposit BTC and call a smart contract on ZetaChain's EVM
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 ZetaChain's EVM BTC transaction would look like this:
- A user sends 1 BTC on Bitcoin network to the Bitcoin TSS
address , 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 holds the BTC, where ownerships are tracked inside this BTC ZRC-20 contract.
Deposit Fee
Unlike EVM-based chains, each deposited Bitcoin output incurs a fee when it is spent. To address this, both the depositor and the withdrawer share the cost of the spend. This fee is charged in advance as a deposit fee.
The Bitcoin deposit fee is calculated with the following formula:
depositFee == (txFee / txVsize) * 68vB * 2
txFee
is the deposit transaction's fee. This can be calculated by formula:totalInputValue - totalOutputValue
txVsize
is the deposit transaction's size in vByte. This can be retrieved from RPCGetRawTransaction
(ZetaChain's implementation).