github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/examples/contract_helper/contract_helper.go (about) 1 package contract_helper 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "strconv" 7 8 "github.com/hashgraph/hedera-sdk-go/v2" 9 "github.com/pkg/errors" 10 ) 11 12 type ContractHelper struct { 13 ContractID hedera.ContractID 14 stepResultValidators map[int32]func(hedera.ContractFunctionResult) bool 15 stepParameterSuppliers map[int32]func() *hedera.ContractFunctionParameters 16 stepPayableAmounts map[int32]*hedera.Hbar 17 stepSigners map[int32][]hedera.PrivateKey 18 stepFeePayers map[int32]*hedera.AccountID 19 stepLogic map[int32]func(address string) 20 } 21 22 func NewContractHelper(bytecode []byte, constructorParameters hedera.ContractFunctionParameters, client *hedera.Client) *ContractHelper { 23 response, err := hedera.NewContractCreateFlow(). 24 SetBytecode(bytecode). 25 SetGas(8000000). 26 SetMaxChunks(30). 27 SetConstructorParameters(&constructorParameters). 28 Execute(client) 29 if err != nil { 30 panic(err) 31 } 32 33 receipt, err := response.GetReceipt(client) 34 if err != nil { 35 panic(err) 36 } 37 if receipt.ContractID != nil { 38 return &ContractHelper{ 39 ContractID: *receipt.ContractID, 40 stepResultValidators: make(map[int32]func(hedera.ContractFunctionResult) bool), 41 stepParameterSuppliers: make(map[int32]func() *hedera.ContractFunctionParameters), 42 stepPayableAmounts: make(map[int32]*hedera.Hbar), 43 stepSigners: make(map[int32][]hedera.PrivateKey), 44 stepFeePayers: make(map[int32]*hedera.AccountID), 45 stepLogic: make(map[int32]func(address string)), 46 } 47 } 48 49 return &ContractHelper{} 50 } 51 52 func (this *ContractHelper) SetResultValidatorForStep(stepIndex int32, validator func(hedera.ContractFunctionResult) bool) *ContractHelper { 53 this.stepResultValidators[stepIndex] = validator 54 return this 55 } 56 57 func (this *ContractHelper) SetParameterSupplierForStep(stepIndex int32, supplier func() *hedera.ContractFunctionParameters) *ContractHelper { 58 this.stepParameterSuppliers[stepIndex] = supplier 59 return this 60 } 61 62 func (this *ContractHelper) SetPayableAmountForStep(stepIndex int32, amount hedera.Hbar) *ContractHelper { 63 this.stepPayableAmounts[stepIndex] = &amount 64 return this 65 } 66 67 func (this *ContractHelper) AddSignerForStep(stepIndex int32, signer hedera.PrivateKey) *ContractHelper { 68 if _, ok := this.stepSigners[stepIndex]; ok { 69 this.stepSigners[stepIndex] = append(this.stepSigners[stepIndex], signer) 70 } else { 71 this.stepSigners[stepIndex] = make([]hedera.PrivateKey, 0) 72 this.stepSigners[stepIndex] = append(this.stepSigners[stepIndex], signer) 73 } 74 75 return this 76 } 77 78 func (this *ContractHelper) SetFeePayerForStep(stepIndex int32, account hedera.AccountID, accountKey hedera.PrivateKey) *ContractHelper { 79 this.stepFeePayers[stepIndex] = &account 80 return this.AddSignerForStep(stepIndex, accountKey) 81 } 82 83 func (this *ContractHelper) SetStepLogic(stepIndex int32, specialFunction func(address string)) *ContractHelper { 84 this.stepLogic[stepIndex] = specialFunction 85 return this 86 } 87 88 func (this *ContractHelper) GetResultValidator(stepIndex int32) func(hedera.ContractFunctionResult) bool { 89 if _, ok := this.stepResultValidators[stepIndex]; ok { 90 return this.stepResultValidators[stepIndex] 91 } 92 93 return func(result hedera.ContractFunctionResult) bool { 94 responseStatus := hedera.Status(result.GetInt32(0)) 95 isValid := responseStatus == hedera.StatusSuccess 96 if !isValid { 97 println("Encountered invalid response status", responseStatus.String()) 98 } 99 return isValid 100 } 101 } 102 103 func (this *ContractHelper) GetParameterSupplier(stepIndex int32) func() *hedera.ContractFunctionParameters { 104 if _, ok := this.stepParameterSuppliers[stepIndex]; ok { 105 return this.stepParameterSuppliers[stepIndex] 106 } 107 108 return func() *hedera.ContractFunctionParameters { 109 return nil 110 } 111 } 112 113 func (this *ContractHelper) GetPayableAmount(stepIndex int32) *hedera.Hbar { 114 return this.stepPayableAmounts[stepIndex] 115 } 116 117 func (this *ContractHelper) GetSigners(stepIndex int32) []hedera.PrivateKey { 118 if _, ok := this.stepSigners[stepIndex]; ok { 119 return this.stepSigners[stepIndex] 120 } 121 122 return []hedera.PrivateKey{} 123 } 124 125 func (this *ContractHelper) ExecuteSteps(firstStep int32, lastStep int32, client *hedera.Client) (*ContractHelper, error) { 126 for stepIndex := firstStep; stepIndex <= lastStep; stepIndex++ { 127 println("Attempting to execuite step", stepIndex) 128 129 transaction := hedera.NewContractExecuteTransaction(). 130 SetContractID(this.ContractID). 131 SetGas(10000000) 132 133 payableAmount := this.GetPayableAmount(stepIndex) 134 if payableAmount != nil { 135 transaction.SetPayableAmount(*payableAmount) 136 } 137 138 functionName := "step" + strconv.Itoa(int(stepIndex)) 139 parameters := this.GetParameterSupplier(stepIndex)() 140 if parameters != nil { 141 transaction.SetFunction(functionName, parameters) 142 } else { 143 transaction.SetFunction(functionName, nil) 144 } 145 146 if feePayerAccountID, ok := this.stepFeePayers[stepIndex]; ok { 147 transaction.SetTransactionID(hedera.TransactionIDGenerate(*feePayerAccountID)) 148 } 149 150 frozen, err := transaction.FreezeWith(client) 151 if err != nil { 152 return &ContractHelper{}, err 153 } 154 for _, signer := range this.GetSigners(stepIndex) { 155 frozen.Sign(signer) 156 } 157 158 response, err := frozen.Execute(client) 159 if err != nil { 160 return &ContractHelper{}, err 161 } 162 163 record, err := response.GetRecord(client) 164 if err != nil { 165 return &ContractHelper{}, err 166 } 167 168 functionResult, err := record.GetContractExecuteResult() 169 if err != nil { 170 return &ContractHelper{}, err 171 } 172 173 if this.stepLogic[stepIndex] != nil { 174 address := functionResult.GetAddress(1) 175 if function, exists := this.stepLogic[stepIndex]; exists && function != nil { 176 function(hex.EncodeToString(address)) 177 } 178 } 179 180 if this.GetResultValidator(stepIndex)(functionResult) { 181 fmt.Printf("Step %d completed, and returned valid result. (TransactionId %s)", stepIndex, record.TransactionID.String()) 182 } else { 183 return &ContractHelper{}, errors.New(fmt.Sprintf("Step %d returned invalid result", stepIndex)) 184 } 185 } 186 187 return this, nil 188 }