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 }