github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/signer/orgchain/signature/signature.go (about) 1 package signature 2 3 import ( 4 "fmt" 5 "github.com/sixexorg/magnetic-ring/account" 6 "github.com/sixexorg/magnetic-ring/common" 7 "github.com/sixexorg/magnetic-ring/core/orgchain/types" 8 errors2 "github.com/sixexorg/magnetic-ring/errors" 9 ) 10 11 /* 12 check signature postion and state 13 */ 14 func CheckSignState(sp common.SigPack, units account.MultiAccountUnits) (apprlvlIndex int, enough bool, err error) { 15 sigdata := sp.SigData 16 17 if sigdata == nil { 18 sp.SigData = make([]*common.SigMap, len(units)) 19 } 20 sigdatalen := len(sigdata) 21 22 if sigdatalen > len(units) { 23 apprlvlIndex = -1 24 err = errors2.SIG_ERR_SIZE 25 return 26 } 27 28 if sigdatalen < 1 { 29 return 0, false, nil 30 } 31 32 index := 0 33 34 for index, sigmap := range sigdata { 35 if len(*sigmap) < int(units[index].Threshold) { 36 apprlvlIndex = index 37 return 38 } 39 } 40 apprlvlIndex = index 41 enough = true 42 return 43 } 44 45 func CheckAddressCanSign(units account.MultiAccountUnits, apprlvlIndex int, address common.Address) (bool, error) { 46 if apprlvlIndex > (len(units)-1) || apprlvlIndex < 0 { 47 fmt.Printf("fuckhere001\n") 48 return false, errors2.SIG_ERR_APPR_LVL 49 } 50 51 muldddaddr, err := units.Address() 52 if err != nil { 53 return false, err 54 } 55 56 if muldddaddr.ToString() == address.ToString() { 57 return true, nil 58 } 59 return false, errors2.SIG_ERR_UNSIGN 60 61 } 62 63 func SignTransaction(m *account.AccountManagerImpl, address common.Address, tx *types.Transaction, pasw string) error { 64 //fmt.Printf("sign transaction address=%s\n",address.ToString()) 65 mulacct, err := m.GetMultipleAccount(address, address) 66 if err != nil { 67 return err 68 } 69 70 impl := mulacct.(*account.MultipleAccountImpl) 71 72 key, err := m.GetNormalAccount(address, pasw) 73 if err != nil { 74 return err 75 } 76 77 b := impl.ExistPubkey(key.PublicKey()) 78 79 if !b { 80 return errors2.SIG_ERR_WRONGOWNER 81 } 82 83 tx.Sigs = new(common.SigPack) 84 err = tx.ToRaw() 85 if err != nil { 86 return err 87 } 88 89 sha256buf := common.Sha256(tx.Raw) 90 sigbuf, err := key.Sign(sha256buf) 91 if err != nil { 92 return err 93 } 94 95 apprindex, _, err := CheckSignState(*tx.Sigs, impl.Maus) 96 97 can, err := CheckAddressCanSign(impl.Maus, apprindex, address) 98 99 if err != nil { 100 return err 101 } 102 103 if !can { 104 return errors2.SIG_ERR_CANOT 105 } 106 sd := tx.Sigs.SigData 107 108 if sd == nil || len(sd) == 0 { 109 sd = make([]*common.SigMap, 0) 110 sm := make(common.SigMap, 0) 111 itm := common.SigMapItem{address, sigbuf} 112 //sm[*address] = sigbuf 113 sm = append(sm, &itm) 114 sd = append(sd, &sm) 115 tx.Sigs.SigData = sd 116 } else { 117 fmt.Printf("sd=%v,apprindex=%d\n", sd, apprindex) 118 apprlvl := sd[apprindex] 119 if apprlvl == nil || len(*apprlvl) == 0 { 120 temp := make(common.SigMap, 0) 121 itm := common.SigMapItem{address, sigbuf} 122 temp = append(temp, &itm) 123 sd[apprindex] = &temp 124 } else { 125 itm := common.SigMapItem{address, sigbuf} 126 *apprlvl = append(*apprlvl, &itm) 127 } 128 } 129 130 return nil 131 } 132 133 func VerifyTransaction(unis account.MultiAccountUnits, tx *types.Transaction) (bool, error) { 134 135 if unis == nil || len(unis) == 0 { 136 return false, errors2.SIG_ERR_NULL_UNITS 137 } 138 139 if tx.Sigs.SigData == nil || len(tx.Sigs.SigData) < 1 { 140 return false, errors2.SIG_ERR_NOSIG 141 } 142 143 if len(tx.Sigs.SigData) != len(unis) { 144 return false, errors2.SIG_ERR_SIGS_NOTENOUGH 145 } 146 147 for index, unit := range unis { 148 sigmaparr := tx.Sigs.SigData 149 150 sigmp := sigmaparr[index] 151 152 if len(*sigmp) < int(unit.Threshold) { 153 return false, errors2.SIG_ERR_APPROVE_NOT_ENOUGH 154 } 155 156 for _, sigitm := range *sigmp { 157 158 for _, pubk := range unit.Pubkeys { 159 160 addrhash := common.Sha256Ripemd160(pubk.Bytes()) 161 162 tmpaddress := common.BytesToAddress(addrhash, common.NormalAddress) 163 164 if tmpaddress.Equals(sigitm.Key) { 165 bsign, err := pubk.Verify(tx.Raw, sigitm.Val) 166 if err != nil { 167 return false, err 168 } 169 170 if !bsign { 171 return false, errors2.SIG_ERR_INVALID_SIG 172 } 173 } 174 } 175 } 176 177 } 178 179 return true, nil 180 }