Skip to content

Commit

Permalink
multi: add support for ZCash
Browse files Browse the repository at this point in the history
Implement block deserialization, tx deserialization/serialization
and input signing for ZCash and generalize those functions in the
client and server btc packages.

Implementation notes
  1. zcashd does not support encrypted wallets. No passwords allowed.
  2. After starting the harness, it takes a few minutes for beta to
     get caught up.
  3. zcashd can take a very long time to get it's fee estimates primed.

All txs we create and sign must be version 5. Use new SIGHASH
algos from ZIP-244. Move SIGHASH stuff to methods of dexzec.Tx.

Add live test to scan testnet blocks looking for deserialization
errors.
  • Loading branch information
buck54321 committed Jun 13, 2022
1 parent 74114ac commit f6cccaa
Show file tree
Hide file tree
Showing 51 changed files with 3,844 additions and 329 deletions.
26 changes: 7 additions & 19 deletions client/asset/bch/bch.go
Expand Up @@ -170,41 +170,29 @@ func NewWallet(cfg *asset.WalletConfig, logger dex.Logger, network dex.Network)
// https://gist.github.com/markblundeberg/a3aba3c9d610e59c3c49199f697bc38b#making-unmalleable-smart-contracts
// https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
NonSegwitSigner: rawTxInSigner,
// The old allowHighFees bool argument to sendrawtransaction.
ArglessChangeAddrRPC: true,
OmitAddressType: true,
// Bitcoin Cash uses estimatefee instead of estimatesmartfee, and even
// then, they modified it from the old Bitcoin Core estimatefee by
// removing the confirmation target argument.
FeeEstimator: estimateFee,
}

xcWallet, err := btc.BTCCloneWallet(cloneCFG)
if err != nil {
return nil, err
}

return &BCHWallet{
ExchangeWalletFullNode: xcWallet,
}, nil
}

// BCHWallet embeds btc.ExchangeWalletFullNode, but re-implements a couple of
// methods to perform on-the-fly address translation.
type BCHWallet struct {
*btc.ExchangeWalletFullNode
return btc.BTCCloneWallet(cloneCFG)
}

// rawTxSigner signs the transaction using Bitcoin Cash's custom signature
// hash and signing algorithm.
func rawTxInSigner(btcTx *wire.MsgTx, idx int, subScript []byte, hashType txscript.SigHashType, btcKey *btcec.PrivateKey, val uint64) ([]byte, error) {
func rawTxInSigner(btcTx *wire.MsgTx, idx int, subScript []byte, hashType txscript.SigHashType,
btcKey *btcec.PrivateKey, vals []int64, _ [][]byte) ([]byte, error) {

bchTx, err := translateTx(btcTx)
if err != nil {
return nil, fmt.Errorf("btc->bch wire.MsgTx translation error: %v", err)
}

bchKey, _ := bchec.PrivKeyFromBytes(bchec.S256(), btcKey.Serialize())

return bchscript.RawTxInECDSASignature(bchTx, idx, subScript, bchscript.SigHashType(uint32(hashType)), bchKey, int64(val))
return bchscript.RawTxInECDSASignature(bchTx, idx, subScript, bchscript.SigHashType(uint32(hashType)), bchKey, vals[idx])
}

// serializeBtcTx serializes the wire.MsgTx.
Expand Down Expand Up @@ -242,7 +230,7 @@ func translateTx(btcTx *wire.MsgTx) (*bchwire.MsgTx, error) {
return nil, err
}

bchTx := bchwire.NewMsgTx(bchwire.TxVersion)
bchTx := new(bchwire.MsgTx)
err = bchTx.Deserialize(bytes.NewBuffer(txB))
if err != nil {
return nil, err
Expand Down

0 comments on commit f6cccaa

Please sign in to comment.