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 10, 2022
1 parent b44030f commit e999610
Show file tree
Hide file tree
Showing 37 changed files with 2,940 additions and 226 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 e999610

Please sign in to comment.