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  }