github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/common/address.go (about) 1 package common 2 3 import ( 4 "bytes" 5 "fmt" 6 "strings" 7 8 "github.com/sixexorg/magnetic-ring/errors" 9 10 "io" 11 "sort" 12 ) 13 14 //address type 15 type AddressType byte 16 17 const ( 18 AddrPrefix = "bx" 19 AddrLength = 21 20 HashLength = 32 21 PubkHashLength = 65 22 ) 23 24 // address type enum 25 const ( 26 27 NormalAddress AddressType = iota 28 29 MultiAddress 30 31 OrganizationAddress 32 33 ContractAddress 34 35 NodeAddress 36 37 NoneAddress 38 ) 39 40 type Address [AddrLength]byte 41 42 // SetBytes sets the address to the value of b. 43 // If b is larger than len(a) it will panic. 44 func (addr *Address) SetBytes(hash []byte, addrType AddressType) { 45 if len(hash) > AddrLength-1 { 46 hash = hash[len(hash)-AddrLength-1:] 47 } 48 49 copy(addr[AddrLength-len(hash)-1:], hash) 50 addr[AddrLength-1] = addrType.ToByte() 51 } 52 53 func (addr Address) Equals(ag Address) bool { 54 return bytes.Compare(addr[:], ag[:]) == 0 55 56 } 57 58 func (addr Address) ToString() string { 59 data := checksum(addr[:20], ToBase32(addr[:20])) 60 return fmt.Sprintf("%s%d%s", AddrPrefix, addr[20], data) 61 } 62 63 func (h Address) MarshalText() ([]byte, error) { 64 return []byte(h.ToString()), nil 65 } 66 67 func checksum(hash []byte, base32 string) string { 68 digest := Sha256(hash) 69 result := []byte(base32) 70 for i := 0; i < len(result); i++ { 71 hashByte := digest[i/8] 72 73 if i%2 == 0 { 74 hashByte &= 0xf 75 } else { 76 hashByte = hashByte >> 4 77 } 78 79 if result[i] > '9' && hashByte > 7 { 80 result[i] -= 32 81 } 82 } 83 84 return string(result) 85 } 86 87 // BytesToAddress returns Address with value b. 88 // If b is larger than len(h), b will be cropped from the left. 89 func BytesToAddress(b []byte, addrType AddressType) Address { 90 var a Address 91 a.SetBytes(b, addrType) 92 return a 93 } 94 95 func Bytes2Address(b []byte) Address { 96 97 var a Address = Address{} 98 copy(a[:], b[:]) 99 return a 100 } 101 102 103 func ToAddress(str string) (address Address, err error) { 104 if len(str) <= 3 { 105 return address, errors.ERR_ACCT_FMT1 106 } 107 108 if strings.ToLower(str[0:2]) != AddrPrefix { 109 return address, errors.ERR_ACCT_FMT2 110 } 111 112 addrType := GetAddressType(str[2]) 113 if addrType == NoneAddress { 114 return address, errors.ERR_ACCT_FMT3 115 } 116 117 data, err := FromBase32(strings.ToLower(str[3:])) 118 if err != nil { 119 return address, errors.ERR_ACCT_FMT4 120 } 121 122 address.SetBytes(data, addrType) 123 return address, nil 124 } 125 126 func (addrType AddressType) ToByte() byte { 127 return byte(addrType) 128 } 129 130 func GetAddressType(bit uint8) AddressType { 131 switch bit { 132 case 48: 133 return NormalAddress 134 case 49: 135 return MultiAddress 136 case 50: 137 return OrganizationAddress 138 case 51: 139 return ContractAddress 140 case 52: 141 return NodeAddress 142 default: 143 return NoneAddress 144 } 145 } 146 147 type Hash [HashLength]byte 148 type PubHash [PubkHashLength]byte 149 150 func StringToHash(hashStr string) (Hash, error) { 151 buf, err := Hex2Bytes(hashStr) 152 if err != nil { 153 return Hash{}, err 154 } 155 ha := Hash{} 156 copy(ha[:], buf) 157 return ha, nil 158 } 159 func (hash Hash) ToBytes() []byte { 160 return hash[:] 161 } 162 func (hash Hash) String() string { 163 return Bytes2Hex(hash[:]) 164 } 165 func (hash *Hash) Serialize(w io.Writer) error { 166 _, err := w.Write(hash[:]) 167 return err 168 } 169 func (hash *Hash) Deserialize(r io.Reader) error { 170 _, err := io.ReadFull(r, hash[:]) 171 return err 172 } 173 174 func (h Hash) MarshalText() ([]byte, error) { 175 return []byte(h.String()), nil 176 } 177 178 type SigBuf [][]byte 179 180 type HashArray []Hash 181 182 func (s HashArray) Len() int { return len(s) } 183 func (s HashArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 184 func (s HashArray) Less(i, j int) bool { return s[i].String() < s[j].String() } 185 func (s HashArray) GetHashRoot() Hash { 186 sort.Sort(s) 187 return ComputeMerkleRoot(s) 188 } 189 190 func CreateLeagueAddress(leagueBuf []byte) (Address, error) { 191 192 hash := Sha256Ripemd160(leagueBuf) 193 leagueAddr := BytesToAddress(hash, OrganizationAddress) 194 195 return leagueAddr, nil 196 } 197 198 type SigMap []*SigMapItem 199 type SigMapItem struct { 200 Key Address 201 Val []byte 202 } 203 204 type SigTmplt struct { 205 SigData []*Maus 206 } 207 208 func NewSigTmplt() *SigTmplt { 209 tmplt := new(SigTmplt) 210 tmplt.SigData = make([]*Maus, 0) 211 return tmplt 212 } 213 214 type SigPack struct { 215 SigData []*SigMap 216 } 217 218 func (s *SigPack) ToBytes() []byte { 219 return nil 220 } 221 222 type Maus []Mau 223 type Mau struct { 224 M uint8 225 Pubks []PubHash 226 }