github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/transaction_mobile.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 string) (*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  
    61  	inputRaw, ok := sn.InputArgs.(string)
    62  	if !ok {
    63  		return nil, fmt.Errorf("failed to convert input args")
    64  	}
    65  
    66  	err = txn.ExecuteSmartContract(address, sn.Name, inputRaw, value)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	t := txn.GetDetails()
    72  
    73  	msg := fmt.Sprintf("Executing transaction '%s' with hash %s ", sn.Name, t.Hash)
    74  	l.Logger.Info(msg)
    75  	l.Logger.Info("estimated txn fee: ", t.TransactionFee)
    76  
    77  	wg.Wait()
    78  
    79  	if !cb.success {
    80  		return nil, fmt.Errorf("smartcontract: %s", cb.errMsg)
    81  	}
    82  
    83  	cb.success = false
    84  	wg.Add(1)
    85  	err = txn.Verify()
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	wg.Wait()
    91  
    92  	if !cb.success {
    93  		return nil, fmt.Errorf("smartcontract: %s", cb.errMsg)
    94  	}
    95  
    96  	switch txn.GetVerifyConfirmationStatus() {
    97  	case zcncore.ChargeableError:
    98  		return t, errors.New(txn.GetVerifyOutput())
    99  	case zcncore.Success:
   100  		return t, nil
   101  	}
   102  
   103  	return nil, fmt.Errorf("smartcontract: %v", txn.GetVerifyConfirmationStatus())
   104  }
   105  
   106  // ExecuteSmartContractSend create send transaction to transfer tokens from the caller to target address
   107  func ExecuteSmartContractSend(to, tokens, fee, desc string) (string, error) {
   108  	wg := &sync.WaitGroup{}
   109  	cb := &transactionCallback{wg: wg}
   110  	txn, err := zcncore.NewTransaction(cb, fee, 0)
   111  	if err != nil {
   112  		return "", err
   113  	}
   114  
   115  	wg.Add(1)
   116  	err = txn.Send(to, tokens, desc)
   117  	if err == nil {
   118  		wg.Wait()
   119  	} else {
   120  		return "", err
   121  	}
   122  
   123  	if cb.success {
   124  		cb.success = false
   125  		wg.Add(1)
   126  		err := txn.Verify()
   127  		if err == nil {
   128  			wg.Wait()
   129  		} else {
   130  			return "", err
   131  		}
   132  		if cb.success {
   133  			return txn.GetVerifyOutput(), nil
   134  		}
   135  	}
   136  
   137  	return "", errors.New(cb.errMsg)
   138  }