Skip to content

Commit

Permalink
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.

Implemenation 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.
  • Loading branch information
buck54321 committed Apr 7, 2022
1 parent b44030f commit 0d2d75b
Show file tree
Hide file tree
Showing 36 changed files with 2,945 additions and 225 deletions.
48 changes: 7 additions & 41 deletions client/asset/bch/bch.go
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/gcash/bchd/bchec"
bchscript "github.com/gcash/bchd/txscript"
bchwire "github.com/gcash/bchd/wire"
Expand Down Expand Up @@ -162,59 +163,24 @@ func NewWallet(cfg *asset.WalletConfig, logger dex.Logger, network dex.Network)
// Bitcoin Cash uses the Cash Address encoding, which is Bech32, but
// not indicative of segwit. We provide a custom encoder.
AddressDecoder: dexbch.DecodeCashAddress,
AddressStringer: func(addr btcutil.Address) string {
a, _ := dexbch.RecodeCashAddress(addr.String(), params)
return a
},
// Bitcoin Cash has a custom signature hash algorithm. Since they don't
// have segwit, Bitcoin Cash implemented a variation of the withdrawn
// BIP0062 that utilizes Shnorr signatures.
// 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
}

// Address converts the Bitcoin base58-encoded address returned by the embedded
// ExchangeWallet into a Cash Address.
func (bch *BCHWallet) Address() (string, error) {
btcAddrStr, err := bch.ExchangeWalletFullNode.Address()
if err != nil {
return "", err
}
return dexbch.RecodeCashAddress(btcAddrStr, bch.Net())
}

// AuditContract modifies the *asset.Contract returned by the ExchangeWallet
// AuditContract method by converting the Recipient to the Cash Address
// encoding.
func (bch *BCHWallet) AuditContract(coinID, contract, txData dex.Bytes, rebroadcast bool) (*asset.AuditInfo, error) { // AuditInfo has address
ai, err := bch.ExchangeWalletFullNode.AuditContract(coinID, contract, txData, rebroadcast)
if err != nil {
return nil, err
}
ai.Recipient, err = dexbch.RecodeCashAddress(ai.Recipient, bch.Net())
if err != nil {
return nil, err
}
return ai, nil
return btc.BTCCloneWallet(cloneCFG)
}

// rawTxSigner signs the transaction using Bitcoin Cash's custom signature
Expand Down

0 comments on commit 0d2d75b

Please sign in to comment.