github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/account/manager.go (about) 1 package account 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "path/filepath" 8 "sync" 9 10 acct "github.com/sixexorg/magnetic-ring/account/keystore" 11 "github.com/sixexorg/magnetic-ring/common" 12 "github.com/sixexorg/magnetic-ring/config" 13 "github.com/sixexorg/magnetic-ring/crypto" 14 "github.com/sixexorg/magnetic-ring/crypto/cipher" 15 "github.com/sixexorg/magnetic-ring/errors" 16 "github.com/sixexorg/magnetic-ring/log" 17 ) 18 19 type NormalAccountImpl struct { 20 PrivKey crypto.PrivateKey 21 Addr common.Address 22 } 23 24 func (acct *NormalAccountImpl) Sign(hash []byte) (sig []byte, err error) { 25 priv := acct.PrivKey 26 return priv.Sign(hash[:]) 27 } 28 29 func (acct *NormalAccountImpl) Verify(hash, sig []byte) (bool, error) { 30 pub := acct.PublicKey() 31 return pub.Verify(hash, sig) 32 } 33 34 func (acct *NormalAccountImpl) Address() common.Address { 35 return acct.Addr 36 } 37 38 func (acct *NormalAccountImpl) PublicKey() crypto.PublicKey { 39 return acct.PrivKey.Public() 40 } 41 42 type MultipleAccountImpl struct { 43 Addr *common.Address 44 Maus MultiAccountUnits 45 } 46 47 func (mai *MultipleAccountImpl) PublicKey() crypto.PublicKey { 48 return nil 49 } 50 51 func (mai *MultipleAccountImpl) ExistPubkey(pubKey crypto.PublicKey) bool { 52 53 for _, arr := range mai.Maus { 54 for _, ele := range arr.Pubkeys { 55 if bytes.Compare(pubKey.Bytes(), ele.Bytes()) == 0 { 56 return true 57 } 58 } 59 } 60 61 return false 62 } 63 64 func (mai *MultipleAccountImpl) OnlyPubkey() crypto.PublicKey { 65 if len(mai.Maus) != 1 { 66 return nil 67 } 68 if len(mai.Maus[0].Pubkeys) != 1 { 69 return nil 70 } 71 return mai.Maus[0].Pubkeys[0] 72 } 73 74 func (acct *MultipleAccountImpl) Address() common.Address { 75 return *acct.Addr 76 } 77 78 func (acct *MultipleAccountImpl) Sign(hash []byte) (sig []byte, err error) { 79 return nil, errors.SIG_ERR_NOT_SUPPORT 80 } 81 82 func (acct *MultipleAccountImpl) Verify(hash, sig []byte) (bool, error) { 83 84 return false, errors.SIG_ERR_NOT_SUPPORT 85 } 86 87 type AccountManagerImpl struct { 88 // keystore 89 ks *acct.Keystore 90 91 // key save path 92 keydir string 93 94 //multi addr save path 95 multiAddrDir string 96 97 // account slice 98 accounts []*account 99 100 mutex sync.Mutex 101 102 acctMulMap map[string]MultiMap 103 accMulMutex sync.Mutex 104 } 105 106 type MultiMap map[string]MultipleAccountImpl 107 108 func NewManager() (*AccountManagerImpl, error) { 109 m := new(AccountManagerImpl) 110 m.ks = acct.DefaultKS 111 tmpKeyDir, err := filepath.Abs(config.DefaultKeyDir) 112 if err != nil { 113 return nil, err 114 } 115 m.keydir = tmpKeyDir 116 117 mulTmpDir, err := filepath.Abs(config.DefaultMultiAddrDir) 118 if err != nil { 119 return nil, err 120 } 121 m.multiAddrDir = mulTmpDir 122 m.acctMulMap = make(map[string]MultiMap) 123 if err := m.refreshAccounts(); err != nil { 124 return nil, err 125 } 126 if err := m.refreshMulTmplts(); err != nil { 127 return nil, err 128 } 129 return m, nil 130 } 131 132 func (am *AccountManagerImpl) GenerateNormalAccount(password string) (NormalAccount, error) { 133 134 privk, err := crypto.GenerateKey() 135 136 if err != nil { 137 log.Error("generate key err", err) 138 return nil, err 139 } 140 na := new(NormalAccountImpl) 141 na.PrivKey = privk 142 143 bytes := na.PublicKey().Bytes() 144 hash := common.Sha256Ripemd160(bytes) 145 na.Addr = common.BytesToAddress(hash, common.NormalAddress) 146 147 passphrase := []byte(password) 148 addr, err := am.setKeyStore(privk, passphrase, common.NormalAddress) 149 if err != nil { 150 return nil, err 151 } 152 153 path, err := am.exportFile(addr, passphrase, false) 154 if err != nil { 155 return nil, err 156 } 157 158 am.updateAccount(addr, path) 159 160 return na, nil 161 } 162 163 func (am *AccountManagerImpl) CreateTraAccount(password string) (NormalAccount, error) { 164 165 privk, err := crypto.GenerateKey() 166 167 if err != nil { 168 log.Error("generate key err", err) 169 return nil, err 170 } 171 na := new(NormalAccountImpl) 172 na.PrivKey = privk 173 174 bytes := na.PublicKey().Bytes() 175 hash := common.Sha256Ripemd160(bytes) 176 na.Addr = common.BytesToAddress(hash, common.NormalAddress) 177 178 passphrase := []byte(password) 179 addr, err := am.setKeyStore(privk, passphrase, common.NormalAddress) 180 if err != nil { 181 return nil, err 182 } 183 184 path, err := am.exportFile(addr, passphrase, false) 185 if err != nil { 186 return nil, err 187 } 188 189 am.updateAccount(addr, path) 190 191 return na, nil 192 } 193 194 func (am *AccountManagerImpl) OneKeyToAddress(pubk crypto.PublicKey) (common.Address, error) { 195 mult := MultiAccountUnit{1, []crypto.PublicKey{pubk}} 196 197 muls := make(MultiAccountUnits, 1) 198 muls[0] = mult 199 200 return muls.Address() 201 } 202 203 func (am *AccountManagerImpl) ImportKeyNormal(prvk, password string) (NormalAccount, error) { 204 privk, err := crypto.HexToPrivateKey(prvk) 205 206 if err != nil { 207 log.Error("Hex To Private Key err", "error", err) 208 return nil, err 209 } 210 na := new(NormalAccountImpl) 211 na.PrivKey = privk 212 213 214 mult := MultiAccountUnit{1, []crypto.PublicKey{privk.Public()}} 215 216 muls := make(MultiAccountUnits, 1) 217 muls[0] = mult 218 219 muladdr, err := muls.Address() 220 221 if err != nil { 222 log.Error("create multiple account err", "units.Address", err) 223 return nil, err 224 } 225 muladdrstr := muladdr.ToString() 226 fmt.Printf("muladdrstr=%s\n", muladdrstr) 227 228 paswphrase := []byte(password) 229 err = am.setOneKeyStore(privk, paswphrase, muladdr) 230 if err != nil { 231 return nil, err 232 } 233 234 path, err := am.exportFile(muladdr, paswphrase, false) 235 if err != nil { 236 return nil, err 237 } 238 239 am.updateAccount(muladdr, path) 240 241 mulpath := filepath.Join(am.multiAddrDir, muladdr.ToString(), muladdr.ToString()) 242 243 mulac := new(MultipleAccountImpl) 244 mulac.Addr = &muladdr 245 mulac.Maus = muls 246 247 am.accMulMutex.Lock() 248 249 if mulmap, ok := am.acctMulMap[muladdr.ToString()]; !ok { 250 mulmap = make(MultiMap) 251 } else { 252 mulmap[muladdr.ToString()] = *mulac 253 } 254 255 am.accMulMutex.Unlock() 256 257 //rawbuf := new(bytes.Buffer) 258 259 mpk := new(MulPack) 260 mpk.Mulstr = muladdr.ToString() 261 mpk.Tmplt = muls.ToObj() 262 263 rawbuf, err := json.Marshal(mpk) 264 //err = rlp.Encode(rawbuf,mpk) 265 266 if err != nil { 267 return nil, err 268 } 269 270 if err := common.FileWrite(mulpath, rawbuf, false); err != nil { 271 log.Error("create multiple account err", "common.FileWrite", err) 272 return nil, err 273 } 274 275 return na, nil 276 } 277 278 func (am *AccountManagerImpl) ImportKeyNode(prvk, password string) (NormalAccount, error) { 279 privk, err := crypto.HexToPrivateKey(prvk) 280 281 if err != nil { 282 log.Error("Hex To Private Key err", "error", err) 283 return nil, err 284 } 285 na := new(NodeAccountImpl) 286 na.PrivKey = privk 287 288 bytes := na.PublicKey().Bytes() 289 hash := common.Sha256Ripemd160(bytes) 290 na.Addr = common.BytesToAddress(hash, common.NodeAddress) 291 292 passphrase := []byte(password) 293 addr, err := am.setKeyStore(privk, passphrase, common.NodeAddress) 294 if err != nil { 295 return nil, err 296 } 297 298 path, err := am.exportFile(addr, passphrase, false) 299 if err != nil { 300 return nil, err 301 } 302 303 am.updateAccount(addr, path) 304 305 return na, nil 306 } 307 308 func (am *AccountManagerImpl) GenerateNodeAccount(password string) (NodeAccount, error) { 309 310 privk, err := crypto.GenerateKey() 311 312 if err != nil { 313 log.Error("generate key err", err) 314 return nil, err 315 } 316 na := new(NodeAccountImpl) 317 na.PrivKey = privk 318 319 bytes := na.PublicKey().Bytes() 320 hash := common.Sha256Ripemd160(bytes) 321 na.Addr = common.BytesToAddress(hash, common.NodeAddress) 322 323 passphrase := []byte(password) 324 addr, err := am.setKeyStore(privk, passphrase, common.NodeAddress) 325 if err != nil { 326 return nil, err 327 } 328 329 path, err := am.exportFile(addr, passphrase, false) 330 if err != nil { 331 return nil, err 332 } 333 334 am.updateAccount(addr, path) 335 336 return na, nil 337 } 338 339 func (am *AccountManagerImpl) CreateMultipleAccount(addr common.Address, units MultiAccountUnits) (MultipleAccount, error) { 340 341 muladdr, err := units.Address() 342 343 if err != nil { 344 log.Error("create multiple account err", "units.Address", err) 345 return nil, err 346 } 347 348 mulpath := filepath.Join(am.multiAddrDir, addr.ToString(), muladdr.ToString()) 349 350 mulac := new(MultipleAccountImpl) 351 mulac.Addr = &muladdr 352 mulac.Maus = units 353 354 am.accMulMutex.Lock() 355 356 if mulmap, ok := am.acctMulMap[addr.ToString()]; !ok { 357 mulmap = make(MultiMap) 358 } else { 359 mulmap[muladdr.ToString()] = *mulac 360 } 361 362 am.accMulMutex.Unlock() 363 364 //rawbuf := new(bytes.Buffer) 365 366 mpk := new(MulPack) 367 mpk.Mulstr = muladdr.ToString() 368 mpk.Tmplt = units.ToObj() 369 370 rawbuf, err := json.Marshal(mpk) 371 //err = rlp.Encode(rawbuf,mpk) 372 373 if err != nil { 374 return nil, err 375 } 376 377 if err := common.FileWrite(mulpath, rawbuf, false); err != nil { 378 log.Error("create multiple account err", "common.FileWrite", err) 379 return nil, err 380 } 381 382 return mulac, err 383 } 384 385 func (am *AccountManagerImpl) GetNormalAccount(addr common.Address, password string) (NormalAccount, error) { 386 passphrase := []byte(password) 387 388 addrstr := addr.ToString() 389 res, err := am.ks.ContainsAlias(addrstr) 390 if err != nil || res == false { 391 err = am.loadFile(addr, passphrase) 392 if err != nil { 393 fmt.Printf("👠fu ck\n") 394 return nil, err 395 } 396 } 397 398 privk, err := am.ks.GetKey(addr.ToString(), passphrase) 399 if err != nil { 400 fmt.Printf("👠fu2ck,address=%s\n",addr.ToString()) 401 return nil, err 402 } 403 404 na := new(NormalAccountImpl) 405 na.PrivKey = privk 406 bytes := na.PublicKey().Bytes() 407 hash := common.Sha256Ripemd160(bytes) 408 na.Addr = common.BytesToAddress(hash, common.NormalAddress) 409 return na, err 410 } 411 412 //func (am *AccountManagerImpl) GetMultipleAccount(addr, multiAddr common.Address, selfPass string) (MultipleAccount, error) { 413 // 414 // //fmt.Printf("watch addr=%s\n", addr.ToString()) 415 // //fmt.Printf("watch mult=%s\n", multiAddr.ToString()) 416 // passphrase := []byte(selfPass) 417 // 418 // res, err := am.ks.ContainsAlias(addr.ToString()) 419 // if err != nil || res == false { 420 // err = am.loadFile(addr, passphrase) 421 // if err != nil { 422 // return nil, err 423 // } 424 // } 425 // 426 // _, err = am.ks.GetKey(addr.ToString(), passphrase) 427 // 428 // if err != nil { 429 // log.Info("GetMultipleAccount err", "AccountManagerImpl.ks.GetKey", err) 430 // return nil, err 431 // } 432 // 433 // addrstr := addr.ToString() 434 // multstr := multiAddr.ToString() 435 // 436 // am.accMulMutex.Lock() 437 // defer am.accMulMutex.Unlock() 438 // 439 // rt, ok := am.acctMulMap[addrstr] 440 // 441 // if !ok { 442 // return nil, errors.ERR_ACCT_MULADDR_NOT_FOUND 443 // } 444 // 445 // fnrt, ok := rt[multstr] 446 // 447 // if !ok { 448 // return nil, errors.ERR_ACCT_MULADDR_NOT_FOUND 449 // 450 // } 451 // return &fnrt, nil 452 //} 453 454 func (am *AccountManagerImpl) GetMultipleAccount(addr, multiAddr common.Address) (MultipleAccount, error) { 455 addrstr := addr.ToString() 456 multstr := multiAddr.ToString() 457 458 am.accMulMutex.Lock() 459 defer am.accMulMutex.Unlock() 460 461 rt, ok := am.acctMulMap[addrstr] 462 463 if !ok { 464 return nil, errors.ERR_ACCT_MULADDR_NOT_FOUND 465 } 466 467 fnrt, ok := rt[multstr] 468 469 if !ok { 470 return nil, errors.ERR_ACCT_MULADDR_NOT_FOUND 471 472 } 473 return &fnrt, nil 474 } 475 476 func (am *AccountManagerImpl) DeleteNormalAccount(addr common.Address, password string) error { 477 passphrase := []byte(password) 478 err := am.ks.Delete(addr.ToString(), passphrase) 479 return err 480 } 481 482 func (am *AccountManagerImpl) DeleteMultipleAccount(addr, multiAddr common.Address, selfPass string) error { 483 _, err := am.ks.GetKey(addr.ToString(), []byte(selfPass)) 484 if err != nil { 485 return err 486 } 487 488 am.accMulMutex.Lock() 489 490 delete(am.acctMulMap[addr.ToString()], multiAddr.ToString()) 491 492 am.accMulMutex.Unlock() 493 494 return nil 495 } 496 497 func (m *AccountManagerImpl) Load(keyjson, passphrase []byte) (common.Address, error) { 498 //var account account 499 empty := common.Address{} 500 cipher := cipher.NewCipher() 501 data, err := cipher.DecryptKey(keyjson, passphrase) 502 if err != nil { 503 return empty, err 504 } 505 defer common.ZeroBytes(data) 506 507 priv, err := crypto.ToPrivateKey(data) 508 if err != nil { 509 return empty, err 510 } 511 //defer priv.Clear() 512 513 addr, err := m.setKeyStore(priv, passphrase, common.NormalAddress) 514 if err != nil { 515 return empty, err 516 } 517 518 if _, err := m.getAccount(addr); err != nil { 519 m.mutex.Lock() 520 acc := &account{addr: addr} 521 m.accounts = append(m.accounts, acc) 522 m.mutex.Unlock() 523 } 524 return addr, nil 525 } 526 527 func (m *AccountManagerImpl) setKeyStore(priv crypto.PrivateKey, passphrase []byte, addrType common.AddressType) (common.Address, error) { 528 empty := common.Address{} 529 //pub := priv.Public().Bytes() 530 531 //hash := common.Sha256Ripemd160(pub) 532 // 533 //addr := common.BytesToAddress(hash, addrType) 534 535 addr,err := m.OneKeyToAddress(priv.Public()) 536 if err != nil { 537 return addr,err 538 } 539 540 // set key to keystore 541 err = m.ks.SetKey(addr.ToString(), priv, passphrase) 542 if err != nil { 543 return empty, err 544 } 545 546 return addr, nil 547 } 548 549 func (m *AccountManagerImpl) setOneKeyStore(priv crypto.PrivateKey, passphrase []byte, addr common.Address) error { 550 //empty := common.Address{} 551 //pub := priv.Public().Bytes() 552 553 //hash := common.Sha256Ripemd160(pub) 554 555 //addr := common.BytesToAddress(hash, addrType) 556 557 // set key to keystore 558 err := m.ks.SetKey(addr.ToString(), priv, passphrase) 559 if err != nil { 560 return err 561 } 562 563 return nil 564 } 565 566 func (m *AccountManagerImpl) Export(addr common.Address, passphrase []byte) ([]byte, error) { 567 key, err := m.ks.GetKey(addr.ToString(), passphrase) 568 if err != nil { 569 return nil, err 570 } 571 //defer key.Clear() 572 573 data := key.Bytes() 574 defer common.ZeroBytes(data) 575 576 cipher := cipher.NewCipher() 577 if err != nil { 578 return nil, err 579 } 580 581 out, err := cipher.EncryptKey(addr.ToString(), data, passphrase) 582 if err != nil { 583 return nil, err 584 } 585 return out, nil 586 } 587 588 type LeagueAccountImpl struct { 589 Addr common.Address 590 } 591 592 func (la *LeagueAccountImpl) Address() common.Address { 593 return la.Addr 594 } 595 596 func (am *AccountManagerImpl) CreateOneKeyAccount(password []byte) (MultipleAccount, error) { 597 privk, err := crypto.GenerateKey() 598 599 if err != nil { 600 log.Error("generate key err", err) 601 return nil, err 602 } 603 604 mult := MultiAccountUnit{1, []crypto.PublicKey{privk.Public()}} 605 606 muls := make(MultiAccountUnits, 1) 607 muls[0] = mult 608 609 muladdr, err := muls.Address() 610 611 if err != nil { 612 log.Error("create multiple account err", "units.Address", err) 613 return nil, err 614 } 615 616 err = am.setOneKeyStore(privk, password, muladdr) 617 if err != nil { 618 return nil, err 619 } 620 621 path, err := am.exportFile(muladdr, password, false) 622 if err != nil { 623 return nil, err 624 } 625 626 am.updateAccount(muladdr, path) 627 628 mulpath := filepath.Join(am.multiAddrDir, muladdr.ToString(), muladdr.ToString()) 629 630 mulac := new(MultipleAccountImpl) 631 mulac.Addr = &muladdr 632 mulac.Maus = muls 633 634 am.accMulMutex.Lock() 635 636 if mulmap, ok := am.acctMulMap[muladdr.ToString()]; !ok { 637 mulmap = make(MultiMap) 638 } else { 639 mulmap[muladdr.ToString()] = *mulac 640 } 641 642 am.accMulMutex.Unlock() 643 644 //rawbuf := new(bytes.Buffer) 645 646 mpk := new(MulPack) 647 mpk.Mulstr = muladdr.ToString() 648 mpk.Tmplt = muls.ToObj() 649 650 rawbuf, err := json.Marshal(mpk) 651 //err = rlp.Encode(rawbuf,mpk) 652 653 if err != nil { 654 return nil, err 655 } 656 657 if err := common.FileWrite(mulpath, rawbuf, false); err != nil { 658 log.Error("create multiple account err", "common.FileWrite", err) 659 return nil, err 660 } 661 662 return mulac, err 663 } 664 665 666 func (am *AccountManagerImpl) CreateBoxAccount(password []byte,privKeyHex string) (MultipleAccount, error) { 667 privk, err := crypto.HexToPrivateKey(privKeyHex) 668 669 if err != nil { 670 log.Error("generate key err", err) 671 return nil, err 672 } 673 674 fmt.Printf("private key for test:%s\n", privk.Hex()) 675 676 mult := MultiAccountUnit{1, []crypto.PublicKey{privk.Public()}} 677 678 muls := make(MultiAccountUnits, 1) 679 muls[0] = mult 680 681 muladdr, err := muls.Address() 682 683 if err != nil { 684 log.Error("create multiple account err", "units.Address", err) 685 return nil, err 686 } 687 688 err = am.setOneKeyStore(privk, password, muladdr) 689 if err != nil { 690 return nil, err 691 } 692 693 path, err := am.exportFile(muladdr, password, false) 694 if err != nil { 695 return nil, err 696 } 697 698 am.updateAccount(muladdr, path) 699 700 mulpath := filepath.Join(am.multiAddrDir, muladdr.ToString(), muladdr.ToString()) 701 702 mulac := new(MultipleAccountImpl) 703 mulac.Addr = &muladdr 704 mulac.Maus = muls 705 706 am.accMulMutex.Lock() 707 708 if mulmap, ok := am.acctMulMap[muladdr.ToString()]; !ok { 709 mulmap = make(MultiMap) 710 } else { 711 mulmap[muladdr.ToString()] = *mulac 712 } 713 714 am.accMulMutex.Unlock() 715 716 //rawbuf := new(bytes.Buffer) 717 718 mpk := new(MulPack) 719 mpk.Mulstr = muladdr.ToString() 720 mpk.Tmplt = muls.ToObj() 721 722 rawbuf, err := json.Marshal(mpk) 723 //err = rlp.Encode(rawbuf,mpk) 724 725 if err != nil { 726 return nil, err 727 } 728 729 if err := common.FileWrite(mulpath, rawbuf, false); err != nil { 730 log.Error("create multiple account err", "common.FileWrite", err) 731 return nil, err 732 } 733 734 return mulac, err 735 }