github.com/aergoio/aergo@v1.3.1/account/key/address.go (about)

     1  package key
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/ecdsa"
     6  	"encoding/binary"
     7  	"errors"
     8  
     9  	"github.com/aergoio/aergo/types"
    10  )
    11  
    12  type Address = []byte
    13  
    14  var addresses = []byte("ADDRESSES")
    15  
    16  func GenerateAddress(pubkey *ecdsa.PublicKey) []byte {
    17  	if pubkey == nil {
    18  		return nil
    19  	}
    20  	addr := new(bytes.Buffer)
    21  	// Compressed pubkey
    22  	binary.Write(addr, binary.LittleEndian, uint8(0x2+pubkey.Y.Bit(0))) // 0x2 for even, 0x3 for odd Y
    23  	keyLength := len(pubkey.X.Bytes())
    24  	if keyLength < 32 { //add padding
    25  		for i := 1; i < types.AddressLength-keyLength; i++ {
    26  			binary.Write(addr, binary.LittleEndian, uint8(0))
    27  		}
    28  	}
    29  	binary.Write(addr, binary.LittleEndian, pubkey.X.Bytes())
    30  	return addr.Bytes() // 33 bytes
    31  }
    32  
    33  func (ks *Store) SaveAddress(addr Address) error {
    34  	if len(addr) != types.AddressLength {
    35  		return errors.New("invalid address length")
    36  	}
    37  
    38  	ks.RWMutex.Lock()
    39  	defer ks.RWMutex.Unlock()
    40  
    41  	addrs := append(ks.storage.Get(addresses), addr...)
    42  	ks.storage.Set(addresses, addrs)
    43  	return nil
    44  }
    45  
    46  func (ks *Store) GetAddresses() ([]Address, error) {
    47  	ks.RWMutex.RLock()
    48  	defer ks.RWMutex.RUnlock()
    49  
    50  	b := ks.storage.Get(addresses)
    51  	var ret []Address
    52  	for i := 0; i < len(b); i += types.AddressLength {
    53  		ret = append(ret, b[i:i+types.AddressLength])
    54  	}
    55  	return ret, nil
    56  }