2017-09-12 18:02:30 +02:00
|
|
|
package address
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
2017-11-20 19:44:19 +01:00
|
|
|
"errors"
|
2017-09-12 18:02:30 +02:00
|
|
|
)
|
|
|
|
|
2017-11-20 19:44:19 +01:00
|
|
|
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)
|
|
|
|
|
2017-09-12 18:02:30 +02:00
|
|
|
const prefix_length = 1
|
|
|
|
const pubkey_length = 20
|
|
|
|
const checksum_length = 4
|
|
|
|
const address_length = prefix_length + pubkey_length + checksum_length
|
2017-11-20 19:44:19 +01:00
|
|
|
const lbrycrd_main = "lbrycrd_main"
|
|
|
|
const lbrycrd_testnet = "lbrycrd_testnet"
|
|
|
|
const lbrycrd_regtest = "lbrycrd_regtest"
|
2017-09-12 18:02:30 +02:00
|
|
|
|
2017-11-20 19:44:19 +01:00
|
|
|
var address_prefixes = map[string][2]byte{}
|
2017-09-12 18:02:30 +02:00
|
|
|
|
2017-11-20 19:44:19 +01:00
|
|
|
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()
|
2017-09-12 18:02:30 +02:00
|
|
|
prefix := address[0]
|
2017-11-20 19:44:19 +01:00
|
|
|
for _, addr_prefix := range address_prefixes[blockchainName] {
|
2017-09-12 18:02:30 +02:00
|
|
|
if addr_prefix == prefix {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func PubKeyIsValid(address [address_length]byte) bool {
|
2017-11-20 19:44:19 +01:00
|
|
|
pubkey := address[prefix_length : pubkey_length+prefix_length]
|
2017-09-12 18:02:30 +02:00
|
|
|
// 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{}
|
2017-11-20 19:44:19 +01:00
|
|
|
for i := range checksum {
|
|
|
|
checksum[i] = address[prefix_length+pubkey_length+i]
|
|
|
|
}
|
2017-09-12 18:02:30 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-11-20 19:44:19 +01:00
|
|
|
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) {
|
2017-09-12 18:02:30 +02:00
|
|
|
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
|
|
|
|
}
|