github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/contract_call_query.go (about) 1 package hedera 2 3 /*- 4 * 5 * Hedera Go SDK 6 * 7 * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ 22 23 import ( 24 "time" 25 26 "github.com/hashgraph/hedera-protobufs-go/services" 27 ) 28 29 // ContractCallQuery calls a function of the given smart contract instance, giving it ContractFunctionParameters as its 30 // inputs. It will consume the entire given amount of gas. 31 // 32 // This is performed locally on the particular _Node that the client is communicating with. It cannot change the state of 33 // the contract instance (and so, cannot spend anything from the instance's Hedera account). It will not have a 34 // consensus timestamp. It cannot generate a record or a receipt. This is useful for calling getter functions, which 35 // purely read the state and don't change it. It is faster and cheaper than a ContractExecuteTransaction, because it is 36 // purely local to a single _Node. 37 type ContractCallQuery struct { 38 Query 39 contractID *ContractID 40 gas uint64 41 maxResultSize uint64 42 functionParameters []byte 43 senderID *AccountID 44 } 45 46 // NewContractCallQuery creates a ContractCallQuery query which can be used to construct and execute a 47 // Contract Call Local Query. 48 func NewContractCallQuery() *ContractCallQuery { 49 header := services.QueryHeader{} 50 query := _NewQuery(true, &header) 51 52 return &ContractCallQuery{ 53 Query: query, 54 } 55 } 56 57 // When execution is attempted, a single attempt will timeout when this deadline is reached. (The SDK may subsequently retry the execution.) 58 func (q *ContractCallQuery) SetGrpcDeadline(deadline *time.Duration) *ContractCallQuery { 59 q.Query.SetGrpcDeadline(deadline) 60 return q 61 } 62 63 // SetContractID sets the contract instance to call 64 func (q *ContractCallQuery) SetContractID(contractID ContractID) *ContractCallQuery { 65 q.contractID = &contractID 66 return q 67 } 68 69 // GetContractID returns the contract instance to call 70 func (q *ContractCallQuery) GetContractID() ContractID { 71 if q.contractID == nil { 72 return ContractID{} 73 } 74 75 return *q.contractID 76 } 77 78 // SetSenderID 79 // The account that is the "sender." If not present it is the accountId from the transactionId. 80 // Typically a different value than specified in the transactionId requires a valid signature 81 // over either the hedera transaction or foreign transaction data. 82 func (q *ContractCallQuery) SetSenderID(id AccountID) *ContractCallQuery { 83 q.senderID = &id 84 return q 85 } 86 87 // GetSenderID returns the AccountID that is the "sender." 88 func (q *ContractCallQuery) GetSenderID() AccountID { 89 if q.senderID == nil { 90 return AccountID{} 91 } 92 93 return *q.senderID 94 } 95 96 // SetGas sets the amount of gas to use for the call. All of the gas offered will be charged for. 97 func (q *ContractCallQuery) SetGas(gas uint64) *ContractCallQuery { 98 q.gas = gas 99 return q 100 } 101 102 // GetGas returns the amount of gas to use for the call. 103 func (q *ContractCallQuery) GetGas() uint64 { 104 return q.gas 105 } 106 107 // Deprecated 108 func (q *ContractCallQuery) SetMaxResultSize(size uint64) *ContractCallQuery { 109 q.maxResultSize = size 110 return q 111 } 112 113 // SetFunction sets which function to call, and the ContractFunctionParams to pass to the function 114 func (q *ContractCallQuery) SetFunction(name string, params *ContractFunctionParameters) *ContractCallQuery { 115 if params == nil { 116 params = NewContractFunctionParameters() 117 } 118 119 q.functionParameters = params._Build(&name) 120 return q 121 } 122 123 // SetFunctionParameters sets the function parameters as their raw bytes. 124 func (q *ContractCallQuery) SetFunctionParameters(byteArray []byte) *ContractCallQuery { 125 q.functionParameters = byteArray 126 return q 127 } 128 129 // GetFunctionParameters returns the function parameters as their raw bytes. 130 func (q *ContractCallQuery) GetFunctionParameters() []byte { 131 return q.functionParameters 132 } 133 134 func (q *ContractCallQuery) GetCost(client *Client) (Hbar, error) { 135 return q.Query.getCost(client, q) 136 } 137 138 // Execute executes the Query with the provided client 139 func (q *ContractCallQuery) Execute(client *Client) (ContractFunctionResult, error) { 140 resp, err := q.Query.execute(client, q) 141 142 if err != nil { 143 return ContractFunctionResult{}, err 144 } 145 146 return _ContractFunctionResultFromProtobuf(resp.GetContractCallLocal().FunctionResult), nil 147 } 148 149 // SetMaxQueryPayment sets the maximum payment allowed for this Query. 150 func (q *ContractCallQuery) SetMaxQueryPayment(maxPayment Hbar) *ContractCallQuery { 151 q.Query.SetMaxQueryPayment(maxPayment) 152 return q 153 } 154 155 // SetQueryPayment sets the payment amount for this Query. 156 func (q *ContractCallQuery) SetQueryPayment(paymentAmount Hbar) *ContractCallQuery { 157 q.Query.SetQueryPayment(paymentAmount) 158 return q 159 } 160 161 // SetNodeAccountIDs sets the _Node AccountID for this ContractCallQuery. 162 func (q *ContractCallQuery) SetNodeAccountIDs(accountID []AccountID) *ContractCallQuery { 163 q.Query.SetNodeAccountIDs(accountID) 164 return q 165 } 166 167 // SetMaxRetry sets the max number of errors before execution will fail. 168 func (q *ContractCallQuery) SetMaxRetry(count int) *ContractCallQuery { 169 q.Query.SetMaxRetry(count) 170 return q 171 } 172 173 // SetMaxBackoff The maximum amount of time to wait between retries. 174 // Every retry attempt will increase the wait time exponentially until it reaches this time. 175 func (q *ContractCallQuery) SetMaxBackoff(max time.Duration) *ContractCallQuery { 176 q.Query.SetMaxBackoff(max) 177 return q 178 } 179 180 // SetMinBackoff sets the minimum amount of time to wait between retries. 181 func (q *ContractCallQuery) SetMinBackoff(min time.Duration) *ContractCallQuery { 182 q.Query.SetMinBackoff(min) 183 return q 184 } 185 186 // SetPaymentTransactionID assigns the payment transaction id. 187 func (q *ContractCallQuery) SetPaymentTransactionID(transactionID TransactionID) *ContractCallQuery { 188 q.paymentTransactionIDs._Clear()._Push(transactionID)._SetLocked(true) 189 return q 190 } 191 192 func (q *ContractCallQuery) SetLogLevel(level LogLevel) *ContractCallQuery { 193 q.Query.SetLogLevel(level) 194 return q 195 } 196 197 // ---------- Parent functions specific implementation ---------- 198 199 func (q *ContractCallQuery) getMethod(channel *_Channel) _Method { 200 return _Method{ 201 query: channel._GetContract().ContractCallLocalMethod, 202 } 203 } 204 205 func (q *ContractCallQuery) getName() string { 206 return "ContractCallQuery" 207 } 208 209 func (q *ContractCallQuery) buildQuery() *services.Query { 210 pb := services.Query_ContractCallLocal{ 211 ContractCallLocal: &services.ContractCallLocalQuery{ 212 Header: q.pbHeader, 213 Gas: int64(q.gas), 214 }, 215 } 216 217 if q.contractID != nil { 218 pb.ContractCallLocal.ContractID = q.contractID._ToProtobuf() 219 } 220 221 if q.senderID != nil { 222 pb.ContractCallLocal.SenderId = q.senderID._ToProtobuf() 223 } 224 225 if len(q.functionParameters) > 0 { 226 pb.ContractCallLocal.FunctionParameters = q.functionParameters 227 } 228 229 return &services.Query{ 230 Query: &pb, 231 } 232 } 233 234 func (q *ContractCallQuery) validateNetworkOnIDs(client *Client) error { 235 if client == nil || !client.autoValidateChecksums { 236 return nil 237 } 238 239 if q.contractID != nil { 240 if err := q.contractID.ValidateChecksum(client); err != nil { 241 return err 242 } 243 } 244 245 if q.senderID != nil { 246 if err := q.senderID.ValidateChecksum(client); err != nil { 247 return err 248 } 249 } 250 251 return nil 252 } 253 254 func (q *ContractCallQuery) getQueryResponse(response *services.Response) queryResponse { 255 return response.GetContractCallLocal() 256 }