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 +}