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  }