github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/transaction.go (about)

     1  //go:build !mobile
     2  // +build !mobile
     3  
     4  package sdk
     5  
     6  import (
     7  	"fmt"
     8  	"sync"
     9  
    10  	"errors"
    11  
    12  	"github.com/0chain/gosdk/core/transaction"
    13  	l "github.com/0chain/gosdk/zboxcore/logger"
    14  	"github.com/0chain/gosdk/zcncore"
    15  )
    16  
    17  type transactionCallback struct {
    18  	wg      *sync.WaitGroup
    19  	success bool
    20  	errMsg  string
    21  
    22  	txn *zcncore.Transaction
    23  }
    24  
    25  func (cb *transactionCallback) OnTransactionComplete(t *zcncore.Transaction, status int) {
    26  	defer cb.wg.Done()
    27  	cb.txn = t
    28  	if status == zcncore.StatusSuccess {
    29  		cb.success = true
    30  	} else {
    31  		cb.errMsg = t.GetTransactionError()
    32  	}
    33  }
    34  
    35  func (cb *transactionCallback) OnVerifyComplete(t *zcncore.Transaction, status int) {
    36  	defer cb.wg.Done()
    37  	cb.txn = t
    38  	if status == zcncore.StatusSuccess {
    39  		cb.success = true
    40  	} else {
    41  		cb.errMsg = t.GetVerifyError()
    42  	}
    43  }
    44  
    45  func (cb *transactionCallback) OnAuthComplete(t *zcncore.Transaction, status int) {
    46  	cb.txn = t
    47  	fmt.Println("Authorization complete on zauth.", status)
    48  }
    49  
    50  // ExecuteSmartContract executes the smart contract
    51  func ExecuteSmartContract(address string, sn transaction.SmartContractTxnData, value, fee uint64) (*transaction.Transaction, error) {
    52  	wg := &sync.WaitGroup{}
    53  	cb := &transactionCallback{wg: wg}
    54  	txn, err := zcncore.NewTransaction(cb, fee, 0)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	wg.Add(1)
    60  	t, err := txn.ExecuteSmartContract(address, sn.Name, sn.InputArgs, value)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	msg := fmt.Sprintf("Executing transaction '%s' with hash %s ", sn.Name, t.Hash)
    66  	l.Logger.Info(msg)
    67  	l.Logger.Info("estimated txn fee: ", t.TransactionFee)
    68  
    69  	wg.Wait()
    70  
    71  	if !cb.success {
    72  		return nil, fmt.Errorf("smartcontract: %s", cb.errMsg)
    73  	}
    74  
    75  	cb.success = false
    76  	wg.Add(1)
    77  	err = txn.Verify()
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	wg.Wait()
    83  
    84  	if !cb.success {
    85  		return nil, fmt.Errorf("smartcontract: %s", cb.errMsg)
    86  	}
    87  
    88  	switch txn.GetVerifyConfirmationStatus() {
    89  	case zcncore.ChargeableError:
    90  		return t, errors.New(txn.GetVerifyOutput())
    91  	case zcncore.Success:
    92  		return t, nil
    93  	}
    94  
    95  	return nil, fmt.Errorf("smartcontract: %v", txn.GetVerifyConfirmationStatus())
    96  }
    97  
    98  // ExecuteSmartContractSend create send transaction to transfer tokens from the caller to target address
    99  func ExecuteSmartContractSend(to string, tokens, fee uint64, desc string) (string, error) {
   100  	wg := &sync.WaitGroup{}
   101  	cb := &transactionCallback{wg: wg}
   102  	txn, err := zcncore.NewTransaction(cb, fee, 0)
   103  	if err != nil {
   104  		return "", err
   105  	}
   106  
   107  	wg.Add(1)
   108  	err = txn.Send(to, tokens, desc)
   109  	if err == nil {
   110  		wg.Wait()
   111  	} else {
   112  		return "", err
   113  	}
   114  
   115  	if cb.success {
   116  		cb.success = false
   117  		wg.Add(1)
   118  		err := txn.Verify()
   119  		if err == nil {
   120  			wg.Wait()
   121  		} else {
   122  			return "", err
   123  		}
   124  		if cb.success {
   125  			return txn.GetVerifyOutput(), nil
   126  		}
   127  	}
   128  
   129  	return "", errors.New(cb.errMsg)
   130  }