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  }