2017-09-12 18:02:30 +02:00
|
|
|
package address
|
|
|
|
|
|
|
|
import (
|
2021-10-06 20:00:59 +02:00
|
|
|
"github.com/cockroachdb/errors"
|
|
|
|
"github.com/lbryio/lbry.go/v3/schema/address/base58"
|
2017-09-12 18:02:30 +02:00
|
|
|
)
|
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
const lbrycrdMainPubkeyPrefix = byte(85)
|
|
|
|
const lbrycrdMainScriptPrefix = byte(122)
|
2019-04-07 06:29:12 +02:00
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
const lbrycrdTestnetPubkeyPrefix = byte(111)
|
|
|
|
const lbrycrdTestnetScriptPrefix = byte(196)
|
2019-04-07 06:29:12 +02:00
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
const lbrycrdRegtestPubkeyPrefix = byte(111)
|
|
|
|
const lbrycrdRegtestScriptPrefix = byte(196)
|
2017-11-20 19:44:19 +01:00
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
const prefixLength = 1
|
|
|
|
const pubkeyLength = 20
|
|
|
|
const checksumLength = 4
|
|
|
|
const addressLength = prefixLength + pubkeyLength + checksumLength
|
2019-04-07 06:29:12 +02:00
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
const lbrycrdMain = "lbrycrd_main"
|
|
|
|
const lbrycrdTestnet = "lbrycrd_testnet"
|
|
|
|
const lbrycrdRegtest = "lbrycrd_regtest"
|
2017-09-12 18:02:30 +02:00
|
|
|
|
2018-05-15 19:12:56 +02:00
|
|
|
var addressPrefixes = map[string][2]byte{
|
2021-02-16 12:38:34 +01:00
|
|
|
lbrycrdMain: {lbrycrdMainPubkeyPrefix, lbrycrdMainScriptPrefix},
|
|
|
|
lbrycrdTestnet: {lbrycrdTestnetPubkeyPrefix, lbrycrdTestnetScriptPrefix},
|
|
|
|
lbrycrdRegtest: {lbrycrdRegtestPubkeyPrefix, lbrycrdRegtestScriptPrefix},
|
2017-11-20 19:44:19 +01:00
|
|
|
}
|
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
func PrefixIsValid(address [addressLength]byte, blockchainName string) bool {
|
2017-09-12 18:02:30 +02:00
|
|
|
prefix := address[0]
|
2018-02-15 20:51:51 +01:00
|
|
|
for _, addrPrefix := range addressPrefixes[blockchainName] {
|
|
|
|
if addrPrefix == prefix {
|
2017-09-12 18:02:30 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
func PubKeyIsValid(address [addressLength]byte) bool {
|
|
|
|
pubkey := address[prefixLength : pubkeyLength+prefixLength]
|
2017-09-12 18:02:30 +02:00
|
|
|
// TODO: validate this for real
|
2018-02-15 20:51:51 +01:00
|
|
|
if len(pubkey) != pubkeyLength {
|
2017-09-12 18:02:30 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
func ChecksumIsValid(address [addressLength]byte) bool {
|
2017-11-27 16:24:10 +01:00
|
|
|
return base58.VerifyBase58Checksum(address[:])
|
2017-09-12 18:02:30 +02:00
|
|
|
}
|
|
|
|
|
2018-02-15 20:51:51 +01:00
|
|
|
func ValidateAddress(address [addressLength]byte, blockchainName string) ([addressLength]byte, error) {
|
|
|
|
if blockchainName != lbrycrdMain && blockchainName != lbrycrdTestnet && blockchainName != lbrycrdRegtest {
|
2021-10-06 20:00:59 +02:00
|
|
|
return address, errors.WithStack(errors.New("invalid blockchain name"))
|
2017-11-20 19:44:19 +01:00
|
|
|
}
|
|
|
|
if !PrefixIsValid(address, blockchainName) {
|
2021-10-06 20:00:59 +02:00
|
|
|
return address, errors.WithStack(errors.New("invalid prefix"))
|
2017-09-12 18:02:30 +02:00
|
|
|
}
|
|
|
|
if !PubKeyIsValid(address) {
|
2021-10-06 20:00:59 +02:00
|
|
|
return address, errors.WithStack(errors.New("invalid pubkey"))
|
2017-09-12 18:02:30 +02:00
|
|
|
}
|
2018-02-15 20:51:51 +01:00
|
|
|
if !ChecksumIsValid(address) {
|
2021-10-06 20:00:59 +02:00
|
|
|
return address, errors.WithStack(errors.New("invalid address checksum"))
|
2017-09-12 18:02:30 +02:00
|
|
|
}
|
|
|
|
return address, nil
|
|
|
|
}
|