From 71eec95c5b5a156ff0e9b5c05cc755c2740df434 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Mon, 26 Mar 2018 11:41:32 +0200 Subject: [PATCH] ZCash uses decoded address as AddrID --- bchain/coins/btc/bitcoinparser.go | 2 ++ bchain/coins/zec/address.go | 41 +++++++++++++++++++++++++++++++ bchain/coins/zec/zcashparser.go | 12 +++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 bchain/coins/zec/address.go diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index 45f6b17a..6918c980 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -33,10 +33,12 @@ func GetChainParams(chain string) *chaincfg.Params { return &chaincfg.MainNetParams } +// GetAddrIDFromAddress returns internal address representation of given transaction output func (p *BitcoinBlockParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) { return hex.DecodeString(output.ScriptPubKey.Hex) } +// GetAddrIDFromAddress returns internal address representation of given address func (p *BitcoinBlockParser) GetAddrIDFromAddress(address string) ([]byte, error) { return p.AddressToOutputScript(address) } diff --git a/bchain/coins/zec/address.go b/bchain/coins/zec/address.go new file mode 100644 index 00000000..be69c4a3 --- /dev/null +++ b/bchain/coins/zec/address.go @@ -0,0 +1,41 @@ +package zec + +import ( + "crypto/sha256" + "errors" + "github.com/btcsuite/btcutil/base58" +) + +var ( + // ErrChecksumMismatch describes an error where decoding failed due + // to a bad checksum. + ErrChecksumMismatch = errors.New("checksum mismatch") + + // ErrInvalidFormat describes an error where decoding failed due to invalid version + ErrInvalidFormat = errors.New("invalid format: version and/or checksum bytes missing") +) + +// checksum: first four bytes of sha256^2 +func checksum(input []byte) (cksum [4]byte) { + h := sha256.Sum256(input) + h2 := sha256.Sum256(h[:]) + copy(cksum[:], h2[:4]) + return +} + +// CheckDecode decodes a string that was encoded with CheckEncode and verifies the checksum. +func CheckDecode(input string) (result []byte, version []byte, err error) { + decoded := base58.Decode(input) + if len(decoded) < 5 { + return nil, nil, ErrInvalidFormat + } + version = append(version, decoded[0:2]...) + var cksum [4]byte + copy(cksum[:], decoded[len(decoded)-4:]) + if checksum(decoded[:len(decoded)-4]) != cksum { + return nil, nil, ErrChecksumMismatch + } + payload := decoded[2 : len(decoded)-4] + result = append(result, payload...) + return +} diff --git a/bchain/coins/zec/zcashparser.go b/bchain/coins/zec/zcashparser.go index 758f9e48..66a80a69 100644 --- a/bchain/coins/zec/zcashparser.go +++ b/bchain/coins/zec/zcashparser.go @@ -10,15 +10,19 @@ import ( type ZCashBlockParser struct{} +// GetAddrIDFromAddress returns internal address representation of given transaction output func (p *ZCashBlockParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) { if len(output.ScriptPubKey.Addresses) != 1 { return nil, nil } - return []byte(output.ScriptPubKey.Addresses[0]), nil + hash, _, err := CheckDecode(output.ScriptPubKey.Addresses[0]) + return hash, err } +// GetAddrIDFromAddress returns internal address representation of given address func (p *ZCashBlockParser) GetAddrIDFromAddress(address string) ([]byte, error) { - return []byte(address), nil + hash, _, err := CheckDecode(address) + return hash, err } // PackTx packs transaction to byte array @@ -74,3 +78,7 @@ func (p *ZCashBlockParser) ParseBlock(b []byte) (*bchain.Block, error) { func (p *ZCashBlockParser) ParseTx(b []byte) (*bchain.Tx, error) { return nil, errors.New("ParseTx: not implemented") } + +func (p *ZCashBlockParser) IsUTXOChain() bool { + return true +}