lbry.go/address/validate.go
2017-11-20 13:44:19 -05:00

80 lines
2.4 KiB
Go

package address
import (
"crypto/sha256"
"errors"
)
const lbrycrd_main_pubkey_prefix = byte(85)
const lbrycrd_main_script_prefix = byte(122)
const lbrycrd_testnet_pubkey_prefix = byte(111)
const lbrycrd_testnet_script_prefix = byte(196)
const lbrycrd_regtest_pubkey_prefix = byte(111)
const lbrycrd_regtest_script_prefix = byte(196)
const prefix_length = 1
const pubkey_length = 20
const checksum_length = 4
const address_length = prefix_length + pubkey_length + checksum_length
const lbrycrd_main = "lbrycrd_main"
const lbrycrd_testnet = "lbrycrd_testnet"
const lbrycrd_regtest = "lbrycrd_regtest"
var address_prefixes = map[string][2]byte{}
func SetPrefixes() {
address_prefixes[lbrycrd_main] = [2]byte{lbrycrd_main_pubkey_prefix, lbrycrd_main_script_prefix}
address_prefixes[lbrycrd_testnet] = [2]byte{lbrycrd_testnet_pubkey_prefix, lbrycrd_testnet_script_prefix}
address_prefixes[lbrycrd_regtest] = [2]byte{lbrycrd_regtest_pubkey_prefix, lbrycrd_regtest_script_prefix}
}
func PrefixIsValid(address [address_length]byte, blockchainName string) bool {
SetPrefixes()
prefix := address[0]
for _, addr_prefix := range address_prefixes[blockchainName] {
if addr_prefix == prefix {
return true
}
}
return false
}
func PubKeyIsValid(address [address_length]byte) bool {
pubkey := address[prefix_length : pubkey_length+prefix_length]
// TODO: validate this for real
if len(pubkey) != pubkey_length {
return false
}
return true
}
func ChecksumIsValid(address [address_length]byte) bool {
checksum := [checksum_length]byte{}
for i := range checksum {
checksum[i] = address[prefix_length+pubkey_length+i]
}
real_checksum := sha256.Sum256(address[:prefix_length+pubkey_length])
real_checksum = sha256.Sum256(real_checksum[:])
for i, c := range checksum {
if c != real_checksum[i] {
return false
}
}
return true
}
func ValidateAddress(address [address_length]byte, blockchainName string) ([address_length]byte, error) {
if blockchainName != lbrycrd_main && blockchainName != lbrycrd_testnet && blockchainName != lbrycrd_regtest {
return address, errors.New("invalid blockchain name")
}
if !PrefixIsValid(address, blockchainName) {
return address, errors.New("invalid prefix")
}
if !PubKeyIsValid(address) {
return address, errors.New("invalid pubkey")
}
if !ChecksumIsValid(address) {
return address, errors.New("invalid address checksum")
}
return address, nil
}