github.com/0chain/gosdk@v1.17.11/zboxcore/client/entity.go (about) 1 // Methods and types for client and wallet operations. 2 package client 3 4 import ( 5 "encoding/json" 6 "fmt" 7 8 "github.com/0chain/gosdk/core/sys" 9 "github.com/0chain/gosdk/core/zcncrypto" 10 ) 11 12 type SignFunc func(hash string) (string, error) 13 14 // Client represents client information 15 type Client struct { 16 *zcncrypto.Wallet 17 SignatureScheme string 18 txnFee uint64 19 } 20 21 var ( 22 client *Client 23 clients []*Client 24 25 // Sign is a function to sign a hash 26 Sign SignFunc 27 sigC = make(chan struct{}, 1) 28 ) 29 30 func init() { 31 client = &Client{ 32 Wallet: &zcncrypto.Wallet{}, 33 } 34 35 sigC <- struct{}{} 36 37 sys.Sign = signHash 38 sys.SignWithAuth = signHash 39 40 // initialize SignFunc as default implementation 41 Sign = func(hash string) (string, error) { 42 if client.PeerPublicKey == "" { 43 return sys.Sign(hash, client.SignatureScheme, GetClientSysKeys()) 44 } 45 46 // get sign lock 47 <-sigC 48 fmt.Println("Sign: with sys.SignWithAuth:", sys.SignWithAuth, "sysKeys:", GetClientSysKeys()) 49 sig, err := sys.SignWithAuth(hash, client.SignatureScheme, GetClientSysKeys()) 50 sigC <- struct{}{} 51 return sig, err 52 } 53 54 sys.Verify = VerifySignature 55 sys.VerifyWith = VerifySignatureWith 56 } 57 58 func SetClient(w *zcncrypto.Wallet, signatureScheme string, txnFee uint64) { 59 client.Wallet = w 60 client.SignatureScheme = signatureScheme 61 client.txnFee = txnFee 62 } 63 64 // PopulateClient populates single client 65 // - clientjson: client json string 66 // - signatureScheme: signature scheme 67 func PopulateClient(clientjson string, signatureScheme string) error { 68 err := json.Unmarshal([]byte(clientjson), &client) 69 client.SignatureScheme = signatureScheme 70 return err 71 } 72 73 // SetClientNonce sets client nonce 74 func SetClientNonce(nonce int64) { 75 client.Nonce = nonce 76 } 77 78 // SetTxnFee sets general transaction fee 79 func SetTxnFee(fee uint64) { 80 client.txnFee = fee 81 } 82 83 // TxnFee gets general txn fee 84 func TxnFee() uint64 { 85 return client.txnFee 86 } 87 88 // PopulateClients This is a workaround for blobber tests that requires multiple clients to test authticket functionality 89 // - clientJsons: array of client json strings 90 // - signatureScheme: signature scheme 91 func PopulateClients(clientJsons []string, signatureScheme string) error { 92 for _, clientJson := range clientJsons { 93 c := new(Client) 94 if err := json.Unmarshal([]byte(clientJson), c); err != nil { 95 return err 96 } 97 c.SignatureScheme = signatureScheme 98 clients = append(clients, c) 99 } 100 return nil 101 } 102 103 // GetClient returns client instance 104 func GetClient() *Client { 105 return client 106 } 107 108 // GetClients returns all clients 109 func GetClients() []*Client { 110 return clients 111 } 112 113 // GetClientID returns client id 114 func GetClientID() string { 115 return client.ClientID 116 } 117 118 // GetClientPublicKey returns client public key 119 func GetClientPublicKey() string { 120 return client.ClientKey 121 } 122 123 func GetClientPeerPublicKey() string { 124 return client.PeerPublicKey 125 126 } 127 128 // GetClientPrivateKey returns client private key 129 func GetClientPrivateKey() string { 130 for _, kv := range client.Keys { 131 return kv.PrivateKey 132 } 133 134 return "" 135 } 136 137 // GetClientSysKeys convert client.KeyPair to sys.KeyPair 138 func GetClientSysKeys() []sys.KeyPair { 139 var keys []sys.KeyPair 140 if client != nil { 141 for _, kv := range client.Keys { 142 keys = append(keys, sys.KeyPair{ 143 PrivateKey: kv.PrivateKey, 144 PublicKey: kv.PublicKey, 145 }) 146 } 147 } 148 149 return keys 150 } 151 152 func signHash(hash string, signatureScheme string, keys []sys.KeyPair) (string, error) { 153 retSignature := "" 154 for _, kv := range keys { 155 ss := zcncrypto.NewSignatureScheme(signatureScheme) 156 err := ss.SetPrivateKey(kv.PrivateKey) 157 if err != nil { 158 return "", err 159 } 160 161 if len(retSignature) == 0 { 162 retSignature, err = ss.Sign(hash) 163 } else { 164 retSignature, err = ss.Add(retSignature, hash) 165 } 166 if err != nil { 167 return "", err 168 } 169 } 170 return retSignature, nil 171 } 172 173 // VerifySignature verifies signature of a message with client public key and signature scheme 174 // - signature: signature to use for verification 175 // - msg: message to verify 176 func VerifySignature(signature string, msg string) (bool, error) { 177 ss := zcncrypto.NewSignatureScheme(client.SignatureScheme) 178 if err := ss.SetPublicKey(client.ClientKey); err != nil { 179 return false, err 180 } 181 182 return ss.Verify(signature, msg) 183 } 184 185 // VerifySignatureWith verifies signature of a message with a given public key, and the client's signature scheme 186 // - pubKey: public key to use for verification 187 // - signature: signature to use for verification 188 // - hash: message to verify 189 func VerifySignatureWith(pubKey, signature, hash string) (bool, error) { 190 sch := zcncrypto.NewSignatureScheme(client.SignatureScheme) 191 err := sch.SetPublicKey(pubKey) 192 if err != nil { 193 return false, err 194 } 195 return sch.Verify(signature, hash) 196 }