github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/ethereum_transaction.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/pkg/errors" 27 28 "github.com/hashgraph/hedera-protobufs-go/services" 29 ) 30 31 // EthereumTransaction is used to create a EthereumTransaction transaction which can be used to construct and execute 32 // a Ethereum Transaction. 33 type EthereumTransaction struct { 34 Transaction 35 ethereumData []byte 36 callData *FileID 37 MaxGasAllowed int64 38 } 39 40 // NewEthereumTransaction creates a EthereumTransaction transaction which can be used to construct and execute 41 // a Ethereum Transaction. 42 func NewEthereumTransaction() *EthereumTransaction { 43 tx := EthereumTransaction{ 44 Transaction: _NewTransaction(), 45 } 46 tx._SetDefaultMaxTransactionFee(NewHbar(2)) 47 48 return &tx 49 } 50 51 func _EthereumTransactionFromProtobuf(tx Transaction, pb *services.TransactionBody) *EthereumTransaction { 52 return &EthereumTransaction{ 53 Transaction: tx, 54 ethereumData: pb.GetEthereumTransaction().EthereumData, 55 callData: _FileIDFromProtobuf(pb.GetEthereumTransaction().CallData), 56 MaxGasAllowed: pb.GetEthereumTransaction().MaxGasAllowance, 57 } 58 } 59 60 // SetEthereumData 61 // The raw Ethereum transaction (RLP encoded type 0, 1, and 2). Complete 62 // unless the callData field is set. 63 func (tx *EthereumTransaction) SetEthereumData(data []byte) *EthereumTransaction { 64 tx._RequireNotFrozen() 65 tx.ethereumData = data 66 return tx 67 } 68 69 // GetEthereumData returns the raw Ethereum transaction (RLP encoded type 0, 1, and 2). 70 func (tx *EthereumTransaction) GetEthereumData() []byte { 71 return tx.ethereumData 72 } 73 74 // Deprecated 75 func (tx *EthereumTransaction) SetCallData(file FileID) *EthereumTransaction { 76 tx._RequireNotFrozen() 77 tx.callData = &file 78 return tx 79 } 80 81 // SetCallDataFileID sets the file ID containing the call data. 82 func (tx *EthereumTransaction) SetCallDataFileID(file FileID) *EthereumTransaction { 83 tx._RequireNotFrozen() 84 tx.callData = &file 85 return tx 86 } 87 88 // GetCallData 89 // For large transactions (for example contract create) this is the callData 90 // of the ethereumData. The data in the ethereumData will be re-written with 91 // the callData element as a zero length string with the original contents in 92 // the referenced file at time of execution. The ethereumData will need to be 93 // "rehydrated" with the callData for signature validation to pass. 94 func (tx *EthereumTransaction) GetCallData() FileID { 95 if tx.callData != nil { 96 return *tx.callData 97 } 98 99 return FileID{} 100 } 101 102 // SetMaxGasAllowed 103 // The maximum amount, in tinybars, that the payer of the hedera transaction 104 // is willing to pay to complete the transaction. 105 func (tx *EthereumTransaction) SetMaxGasAllowed(gas int64) *EthereumTransaction { 106 tx._RequireNotFrozen() 107 tx.MaxGasAllowed = gas 108 return tx 109 } 110 111 // SetMaxGasAllowanceHbar sets the maximum amount, that the payer of the hedera transaction 112 // is willing to pay to complete the transaction. 113 func (tx *EthereumTransaction) SetMaxGasAllowanceHbar(gas Hbar) *EthereumTransaction { 114 tx._RequireNotFrozen() 115 tx.MaxGasAllowed = gas.AsTinybar() 116 return tx 117 } 118 119 // GetMaxGasAllowed returns the maximum amount, that the payer of the hedera transaction 120 // is willing to pay to complete the transaction. 121 func (tx *EthereumTransaction) GetMaxGasAllowed() int64 { 122 return tx.MaxGasAllowed 123 } 124 125 // ---- Required Interfaces ---- // 126 127 // Sign uses the provided privateKey to sign the transaction. 128 func (tx *EthereumTransaction) Sign( 129 privateKey PrivateKey, 130 ) *EthereumTransaction { 131 tx.Transaction.Sign(privateKey) 132 return tx 133 } 134 135 // SignWithOperator signs the transaction with client's operator privateKey. 136 func (tx *EthereumTransaction) SignWithOperator( 137 client *Client, 138 ) (*EthereumTransaction, error) { 139 // If the transaction is not signed by the _Operator, we need 140 // to sign the transaction with the _Operator 141 _, err := tx.Transaction.signWithOperator(client, tx) 142 if err != nil { 143 return nil, err 144 } 145 return tx, nil 146 } 147 148 // SignWith executes the TransactionSigner and adds the resulting signature data to the Transaction's signature map 149 // with the publicKey as the map key. 150 func (tx *EthereumTransaction) SignWith( 151 publicKey PublicKey, 152 signer TransactionSigner, 153 ) *EthereumTransaction { 154 tx.Transaction.SignWith(publicKey, signer) 155 return tx 156 } 157 158 // AddSignature adds a signature to the transaction. 159 func (tx *EthereumTransaction) AddSignature(publicKey PublicKey, signature []byte) *EthereumTransaction { 160 tx.Transaction.AddSignature(publicKey, signature) 161 return tx 162 } 163 164 // When execution is attempted, a single attempt will timeout when tx deadline is reached. (The SDK may subsequently retry the execution.) 165 func (tx *EthereumTransaction) SetGrpcDeadline(deadline *time.Duration) *EthereumTransaction { 166 tx.Transaction.SetGrpcDeadline(deadline) 167 return tx 168 } 169 170 func (tx *EthereumTransaction) Freeze() (*EthereumTransaction, error) { 171 return tx.FreezeWith(nil) 172 } 173 174 func (tx *EthereumTransaction) FreezeWith(client *Client) (*EthereumTransaction, error) { 175 _, err := tx.Transaction.freezeWith(client, tx) 176 return tx, err 177 } 178 179 // SetMaxTransactionFee sets the maximum transaction fee the operator (paying account) is willing to pay. 180 func (tx *EthereumTransaction) SetMaxTransactionFee(fee Hbar) *EthereumTransaction { 181 tx._RequireNotFrozen() 182 tx.Transaction.SetMaxTransactionFee(fee) 183 return tx 184 } 185 186 // SetRegenerateTransactionID sets if transaction IDs should be regenerated when `TRANSACTION_EXPIRED` is received 187 func (tx *EthereumTransaction) SetRegenerateTransactionID(regenerateTransactionID bool) *EthereumTransaction { 188 tx._RequireNotFrozen() 189 tx.Transaction.SetRegenerateTransactionID(regenerateTransactionID) 190 return tx 191 } 192 193 // GetRegenerateTransactionID returns true if transaction ID regeneration is enabled. 194 func (tx *EthereumTransaction) GetRegenerateTransactionID() bool { 195 return tx.Transaction.GetRegenerateTransactionID() 196 } 197 198 // GetTransactionMemo returns the memo for this EthereumTransaction. 199 func (tx *EthereumTransaction) GetTransactionMemo() string { 200 return tx.Transaction.GetTransactionMemo() 201 } 202 203 // SetTransactionMemo sets the memo for this EthereumTransaction. 204 func (tx *EthereumTransaction) SetTransactionMemo(memo string) *EthereumTransaction { 205 tx._RequireNotFrozen() 206 tx.Transaction.SetTransactionMemo(memo) 207 return tx 208 } 209 210 // SetTransactionValidDuration sets the valid duration for this EthereumTransaction. 211 func (tx *EthereumTransaction) SetTransactionValidDuration(duration time.Duration) *EthereumTransaction { 212 tx._RequireNotFrozen() 213 tx.Transaction.SetTransactionValidDuration(duration) 214 return tx 215 } 216 217 // ToBytes serialise the tx to bytes, no matter if it is signed (locked), or not 218 func (tx *EthereumTransaction) ToBytes() ([]byte, error) { 219 bytes, err := tx.Transaction.toBytes(tx) 220 if err != nil { 221 return nil, err 222 } 223 return bytes, nil 224 } 225 226 // SetTransactionID sets the TransactionID for this EthereumTransaction. 227 func (tx *EthereumTransaction) SetTransactionID(transactionID TransactionID) *EthereumTransaction { 228 tx._RequireNotFrozen() 229 230 tx.Transaction.SetTransactionID(transactionID) 231 return tx 232 } 233 234 // SetNodeAccountIDs sets the _Node AccountID for this EthereumTransaction. 235 func (tx *EthereumTransaction) SetNodeAccountIDs(nodeID []AccountID) *EthereumTransaction { 236 tx._RequireNotFrozen() 237 tx.Transaction.SetNodeAccountIDs(nodeID) 238 return tx 239 } 240 241 // SetMaxRetry sets the max number of errors before execution will fail. 242 func (tx *EthereumTransaction) SetMaxRetry(count int) *EthereumTransaction { 243 tx.Transaction.SetMaxRetry(count) 244 return tx 245 } 246 247 // SetMaxBackoff The maximum amount of time to wait between retries. 248 // Every retry attempt will increase the wait time exponentially until it reaches this time. 249 func (tx *EthereumTransaction) SetMaxBackoff(max time.Duration) *EthereumTransaction { 250 tx.Transaction.SetMaxBackoff(max) 251 return tx 252 } 253 254 // SetMinBackoff sets the minimum amount of time to wait between retries. 255 func (tx *EthereumTransaction) SetMinBackoff(min time.Duration) *EthereumTransaction { 256 tx.Transaction.SetMinBackoff(min) 257 return tx 258 } 259 260 func (tx *EthereumTransaction) SetLogLevel(level LogLevel) *EthereumTransaction { 261 tx.Transaction.SetLogLevel(level) 262 return tx 263 } 264 265 func (tx *EthereumTransaction) Execute(client *Client) (TransactionResponse, error) { 266 return tx.Transaction.execute(client, tx) 267 } 268 269 func (tx *EthereumTransaction) Schedule() (*ScheduleCreateTransaction, error) { 270 return tx.Transaction.schedule(tx) 271 } 272 273 // ----------- Overridden functions ---------------- 274 275 func (tx *EthereumTransaction) getName() string { 276 return "EthereumTransaction" 277 } 278 func (tx *EthereumTransaction) validateNetworkOnIDs(client *Client) error { 279 if client == nil || !client.autoValidateChecksums { 280 return nil 281 } 282 283 if tx.callData != nil { 284 if err := tx.callData.ValidateChecksum(client); err != nil { 285 return err 286 } 287 } 288 289 return nil 290 } 291 292 func (tx *EthereumTransaction) build() *services.TransactionBody { 293 body := &services.EthereumTransactionBody{ 294 EthereumData: tx.ethereumData, 295 MaxGasAllowance: tx.MaxGasAllowed, 296 } 297 298 if tx.callData != nil { 299 body.CallData = tx.callData._ToProtobuf() 300 } 301 302 return &services.TransactionBody{ 303 TransactionID: tx.transactionID._ToProtobuf(), 304 TransactionFee: tx.transactionFee, 305 TransactionValidDuration: _DurationToProtobuf(tx.GetTransactionValidDuration()), 306 Memo: tx.Transaction.memo, 307 Data: &services.TransactionBody_EthereumTransaction{ 308 EthereumTransaction: body, 309 }, 310 } 311 } 312 313 func (tx *EthereumTransaction) buildScheduled() (*services.SchedulableTransactionBody, error) { 314 return nil, errors.New("cannot schedule `EthereumTransaction") 315 } 316 317 func (tx *EthereumTransaction) getMethod(channel *_Channel) _Method { 318 return _Method{ 319 transaction: channel._GetContract().CallEthereum, 320 } 321 }