github.com/0chain/gosdk@v1.17.11/zcncore/transactionauth_base.go (about)

     1  package zcncore
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/0chain/errors"
     7  	"github.com/0chain/gosdk/core/node"
     8  	"github.com/0chain/gosdk/core/sys"
     9  	"github.com/0chain/gosdk/core/transaction"
    10  	"github.com/0chain/gosdk/core/zcncrypto"
    11  	"github.com/0chain/gosdk/zboxcore/client"
    12  )
    13  
    14  type TransactionWithAuth struct {
    15  	t *Transaction
    16  }
    17  
    18  func (ta *TransactionWithAuth) Hash() string {
    19  	return ta.t.txnHash
    20  }
    21  
    22  func (ta *TransactionWithAuth) SetTransactionNonce(txnNonce int64) error {
    23  	return ta.t.SetTransactionNonce(txnNonce)
    24  }
    25  
    26  func (ta *TransactionWithAuth) getAuthorize() (*transaction.Transaction, error) {
    27  	ta.t.txn.PublicKey = _config.wallet.ClientKey
    28  	err := ta.t.txn.ComputeHashAndSign(SignFn)
    29  	if err != nil {
    30  		return nil, errors.Wrap(err, "signing error.")
    31  	}
    32  
    33  	jsonByte, err := json.Marshal(ta.t.txn)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	if sys.Authorize == nil {
    39  		return nil, errors.New("not_initialized", "no authorize func is set, define it in native code and set in sys")
    40  	}
    41  	authorize, err := sys.Authorize(string(jsonByte))
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	var txnResp transaction.Transaction
    47  	err = json.Unmarshal([]byte(authorize), &txnResp)
    48  	if err != nil {
    49  		return nil, errors.Wrap(err, "invalid json on auth response.")
    50  	}
    51  	// Verify the split key signed signature
    52  	ok, err := txnResp.VerifySigWith(client.GetClientPublicKey(), sys.VerifyWith)
    53  	if err != nil {
    54  		logging.Error("verification failed for txn from auth", err.Error())
    55  		return nil, errAuthVerifyFailed
    56  	}
    57  	if !ok {
    58  		return nil, errAuthVerifyFailed
    59  	}
    60  	return &txnResp, nil
    61  }
    62  
    63  func (ta *TransactionWithAuth) completeTxn(status int, out string, err error) {
    64  	// do error code translation
    65  	if status != StatusSuccess {
    66  		switch err {
    67  		case errNetwork:
    68  			status = StatusNetworkError
    69  		case errUserRejected:
    70  			status = StatusRejectedByUser
    71  		case errAuthVerifyFailed:
    72  			status = StatusAuthVerifyFailed
    73  		case errAuthTimeout:
    74  			status = StatusAuthTimeout
    75  		}
    76  	}
    77  	ta.t.completeTxn(status, out, err) //nolint
    78  }
    79  
    80  func verifyFn(signature, msgHash, publicKey string) (bool, error) {
    81  	v := zcncrypto.NewSignatureScheme(_config.chain.SignatureScheme)
    82  	err := v.SetPublicKey(publicKey)
    83  	if err != nil {
    84  		return false, err
    85  	}
    86  
    87  	ok, err := v.Verify(signature, msgHash)
    88  	if err != nil || !ok {
    89  		return false, errors.New("", `{"error": "signature_mismatch"}`)
    90  	}
    91  	return true, nil
    92  }
    93  
    94  func (ta *TransactionWithAuth) sign(otherSig string) error {
    95  	ta.t.txn.ComputeHashData()
    96  
    97  	sig, err := AddSignature(_config.wallet.Keys[0].PrivateKey, otherSig, ta.t.txn.Hash)
    98  	if err != nil {
    99  		return err
   100  	}
   101  	ta.t.txn.Signature = sig
   102  	return nil
   103  }
   104  
   105  func (ta *TransactionWithAuth) submitTxn() {
   106  	nonce := ta.t.txn.TransactionNonce
   107  	if nonce < 1 {
   108  		nonce = node.Cache.GetNextNonce(ta.t.txn.ClientID)
   109  	} else {
   110  		node.Cache.Set(ta.t.txn.ClientID, nonce)
   111  	}
   112  	ta.t.txn.TransactionNonce = nonce
   113  	authTxn, err := ta.getAuthorize()
   114  	if err != nil {
   115  		logging.Error("get auth error for send, err: ", err.Error())
   116  		ta.completeTxn(StatusAuthError, "", err)
   117  		return
   118  	}
   119  
   120  	// Use the timestamp from auth and sign
   121  	ta.t.txn.CreationDate = authTxn.CreationDate
   122  	ta.t.txn.Signature = authTxn.Signature
   123  	ta.t.submitTxn()
   124  }
   125  
   126  func (ta *TransactionWithAuth) StoreData(data string) error {
   127  	go func() {
   128  		ta.t.txn.TransactionType = transaction.TxnTypeData
   129  		ta.t.txn.TransactionData = data
   130  		ta.submitTxn()
   131  	}()
   132  	return nil
   133  }
   134  
   135  // ExecuteFaucetSCWallet impements the Faucet Smart contract for a given wallet
   136  func (ta *TransactionWithAuth) ExecuteFaucetSCWallet(walletStr string, methodName string, input []byte) error {
   137  	w, err := ta.t.createFaucetSCWallet(walletStr, methodName, input)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	go func() {
   142  		nonce := ta.t.txn.TransactionNonce
   143  		if nonce < 1 {
   144  			nonce = node.Cache.GetNextNonce(ta.t.txn.ClientID)
   145  		} else {
   146  			node.Cache.Set(ta.t.txn.ClientID, nonce)
   147  		}
   148  		ta.t.txn.TransactionNonce = nonce
   149  		err = ta.t.txn.ComputeHashAndSignWithWallet(signWithWallet, w)
   150  		if err != nil {
   151  			return
   152  		}
   153  		ta.submitTxn()
   154  	}()
   155  	return nil
   156  }
   157  
   158  func (ta *TransactionWithAuth) SetTransactionCallback(cb TransactionCallback) error {
   159  	return ta.t.SetTransactionCallback(cb)
   160  }
   161  
   162  func (ta *TransactionWithAuth) SetTransactionHash(hash string) error {
   163  	return ta.t.SetTransactionHash(hash)
   164  }
   165  
   166  func (ta *TransactionWithAuth) GetTransactionHash() string {
   167  	return ta.t.GetTransactionHash()
   168  }
   169  
   170  func (ta *TransactionWithAuth) Verify() error {
   171  	return ta.t.Verify()
   172  }
   173  
   174  func (ta *TransactionWithAuth) GetVerifyOutput() string {
   175  	return ta.t.GetVerifyOutput()
   176  }
   177  
   178  func (ta *TransactionWithAuth) GetTransactionError() string {
   179  	return ta.t.GetTransactionError()
   180  }
   181  
   182  func (ta *TransactionWithAuth) GetVerifyError() string {
   183  	return ta.t.GetVerifyError()
   184  }
   185  
   186  func (ta *TransactionWithAuth) Output() []byte {
   187  	return []byte(ta.t.txnOut)
   188  }
   189  
   190  // GetTransactionNonce returns nonce
   191  func (ta *TransactionWithAuth) GetTransactionNonce() int64 {
   192  	return ta.t.txn.TransactionNonce
   193  }
   194  
   195  //
   196  // miner sc
   197  //
   198  
   199  // RegisterMultiSig register a multisig wallet with the SC.
   200  func (ta *TransactionWithAuth) RegisterMultiSig(walletstr string, mswallet string) error {
   201  	return errors.New("", "not implemented")
   202  }
   203  
   204  //
   205  // Storage SC
   206  //