github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/account/account.go (about)

     1  package account
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/sixexorg/magnetic-ring/common"
     6  	"github.com/sixexorg/magnetic-ring/crypto"
     7  	errors2 "github.com/sixexorg/magnetic-ring/errors"
     8  )
     9  
    10  type Account interface {
    11  	Sign(hash []byte) (sig []byte, err error)
    12  	Verify(hash, sig []byte) (bool, error)
    13  	Address() common.Address
    14  }
    15  
    16  type LeagueAccount interface {
    17  	Address() common.Address
    18  }
    19  
    20  type NormalAccount interface {
    21  	Account
    22  	PublicKey() crypto.PublicKey
    23  }
    24  
    25  type NodeAccount interface {
    26  	Account
    27  	PublicKey() crypto.PublicKey
    28  }
    29  
    30  type MultipleAccount interface {
    31  	Account
    32  	ExistPubkey(pubKey crypto.PublicKey) bool
    33  }
    34  
    35  type AccountsManager interface {
    36  	GenerateNormalAccount(password string) (NormalAccount, error)
    37  
    38  	ImportNormalAccount(filePath, password string) (*common.Address, error)
    39  	ExportNormalAccount(acc NormalAccount, filePath, password string, overide bool) error
    40  
    41  	CreateMultipleAccount(addr common.Address, units MultiAccountUnits) (MultipleAccount, error)
    42  
    43  	GetNormalAccount(addr common.Address, password string) (NormalAccount, error)
    44  	GetMultipleAccount(addr, multiAddr common.Address, selfPass string) (MultipleAccount, error)
    45  	DeleteNormalAccount(addr common.Address, password string) error
    46  	DeleteMultipleAccount(addr, multiAddr common.Address, selfPass string) error
    47  }
    48  
    49  type MultiAccountUnit struct {
    50  	Threshold uint8
    51  	Pubkeys   []crypto.PublicKey
    52  }
    53  
    54  type MultiEle struct {
    55  	Threshold uint8    `json:"m"`
    56  	Pubkeys   []string `json:"pbks"`
    57  }
    58  
    59  type MultiAccObj []MultiEle
    60  
    61  type MulPack struct {
    62  	Tmplt  MultiAccObj
    63  	Mulstr string
    64  }
    65  
    66  type MultiAccountUnits []MultiAccountUnit
    67  
    68  func (maus MultiAccountUnits) ToObj() MultiAccObj {
    69  	obj := make(MultiAccObj, len(maus))
    70  
    71  	for i, unit := range maus {
    72  		me := MultiEle{}
    73  		me.Threshold = unit.Threshold
    74  		me.Pubkeys = make([]string, len(unit.Pubkeys))
    75  		for j, item := range unit.Pubkeys {
    76  			str := common.Bytes2Hex(item.Bytes())
    77  			me.Pubkeys[j] = str
    78  		}
    79  		obj[i] = me
    80  	}
    81  	return obj
    82  }
    83  
    84  func (maos MultiAccObj) ToMultiAccUnits() (MultiAccountUnits, error) {
    85  	units := make(MultiAccountUnits, len(maos))
    86  
    87  	for i, unit := range maos {
    88  		me := MultiAccountUnit{}
    89  		me.Threshold = unit.Threshold
    90  		me.Pubkeys = make([]crypto.PublicKey, len(unit.Pubkeys))
    91  		for j, item := range unit.Pubkeys {
    92  			buf, err := common.Hex2Bytes(item)
    93  			if err != nil {
    94  				return nil, err
    95  			}
    96  
    97  			pubk, err := crypto.UnmarshalPubkey(buf)
    98  			if err != nil {
    99  				return nil, err
   100  			}
   101  
   102  			me.Pubkeys[j] = pubk
   103  		}
   104  		units[i] = me
   105  	}
   106  	return units, nil
   107  }
   108  
   109  func (units MultiAccountUnits) Address() (addr common.Address, err error) {
   110  	buf, err := units.ToBytes()
   111  	if err != nil {
   112  		return addr, err
   113  	}
   114  
   115  	hash := common.Sha256Ripemd160(buf)
   116  	addr.SetBytes(hash, common.MultiAddress)
   117  	return addr, nil
   118  }
   119  
   120  func (units MultiAccountUnits) ToBytes() ([]byte, error) {
   121  	buf := bytes.NewBuffer(nil)
   122  	for _, unit := range units {
   123  		if len(unit.Pubkeys) < int(unit.Threshold) {
   124  			return nil, errors2.ERR_ACCT_CRT_MULADDR
   125  		}
   126  
   127  		_, err := buf.Write([]byte{unit.Threshold})
   128  		if err != nil {
   129  			return nil, err
   130  		}
   131  
   132  		for _, pubKey := range unit.Pubkeys {
   133  			_, err = buf.Write(pubKey.Bytes())
   134  		}
   135  	}
   136  
   137  	return buf.Bytes(), nil
   138  }
   139  
   140  func PubkToAddress(pubk crypto.PublicKey) (common.Address, error) {
   141  	mult := MultiAccountUnit{1, []crypto.PublicKey{pubk}}
   142  
   143  	muls := make(MultiAccountUnits, 1)
   144  	muls[0] = mult
   145  
   146  	return muls.Address()
   147  }