github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/file_create_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/hashgraph/hedera-protobufs-go/services"
    27  )
    28  
    29  // FileCreateTransaction creates a new file, containing the given contents.  It is referenced by its FileID, and does
    30  // not have a filename, so it is important to get and hold onto the FileID. After the file is created, the FileID for
    31  // it can be found in the receipt, or retrieved with a GetByKey query, or by asking for a Record of the transaction to
    32  // be created, and retrieving that.
    33  //
    34  // See FileInfoQuery for more information about files.
    35  //
    36  // The current API ignores shardID, realmID, and newRealmAdminKey, and creates everything in shard 0 and realm 0, with
    37  // a null key. Future versions of the API will support multiple realms and multiple shards.
    38  type FileCreateTransaction struct {
    39  	Transaction
    40  	keys           *KeyList
    41  	expirationTime *time.Time
    42  	contents       []byte
    43  	memo           string
    44  }
    45  
    46  // NewFileCreateTransaction creates a FileCreateTransaction which creates a new file, containing the given contents.  It is referenced by its FileID, and does
    47  // not have a filename, so it is important to get and hold onto the FileID. After the file is created, the FileID for
    48  // it can be found in the receipt, or retrieved with a GetByKey query, or by asking for a Record of the transaction to
    49  // be created, and retrieving that.
    50  //
    51  // See FileInfoQuery for more information about files.
    52  //
    53  // The current API ignores shardID, realmID, and newRealmAdminKey, and creates everything in shard 0 and realm 0, with
    54  // a null key. Future versions of the API will support multiple realms and multiple shards.
    55  func NewFileCreateTransaction() *FileCreateTransaction {
    56  	tx := FileCreateTransaction{
    57  		Transaction: _NewTransaction(),
    58  	}
    59  
    60  	tx.SetExpirationTime(time.Now().Add(7890000 * time.Second))
    61  	tx._SetDefaultMaxTransactionFee(NewHbar(5))
    62  
    63  	return &tx
    64  }
    65  
    66  func _FileCreateTransactionFromProtobuf(tx Transaction, pb *services.TransactionBody) *FileCreateTransaction {
    67  	keys, _ := _KeyListFromProtobuf(pb.GetFileCreate().GetKeys())
    68  	expiration := _TimeFromProtobuf(pb.GetFileCreate().GetExpirationTime())
    69  
    70  	return &FileCreateTransaction{
    71  		Transaction:    tx,
    72  		keys:           &keys,
    73  		expirationTime: &expiration,
    74  		contents:       pb.GetFileCreate().GetContents(),
    75  		memo:           pb.GetMemo(),
    76  	}
    77  }
    78  
    79  // AddKey adds a key to the internal list of keys associated with the file. All of the keys on the list must sign to
    80  // create or modify a file, but only one of them needs to sign in order to delete the file. Each of those "keys" may
    81  // itself be threshold key containing other keys (including other threshold keys). In other words, the behavior is an
    82  // AND for create/modify, OR for delete. This is useful for acting as a revocation server. If it is desired to have the
    83  // behavior be AND for all 3 operations (or OR for all 3), then the list should have only a single Key, which is a
    84  // threshold key, with N=1 for OR, N=M for AND.
    85  //
    86  // If a file is created without adding ANY keys, the file is immutable and ONLY the
    87  // expirationTime of the file can be changed using FileUpdateTransaction. The file contents or its keys will not be
    88  // mutable.
    89  func (tx *FileCreateTransaction) SetKeys(keys ...Key) *FileCreateTransaction {
    90  	tx._RequireNotFrozen()
    91  	if tx.keys == nil {
    92  		tx.keys = &KeyList{keys: []Key{}}
    93  	}
    94  	keyList := NewKeyList()
    95  	keyList.AddAll(keys)
    96  
    97  	tx.keys = keyList
    98  
    99  	return tx
   100  }
   101  
   102  func (tx *FileCreateTransaction) GetKeys() KeyList {
   103  	if tx.keys != nil {
   104  		return *tx.keys
   105  	}
   106  
   107  	return KeyList{}
   108  }
   109  
   110  // SetExpirationTime sets the time at which this file should expire (unless FileUpdateTransaction is used before then to
   111  // extend its life). The file will automatically disappear at the fileExpirationTime, unless its expiration is extended
   112  // by another transaction before that time. If the file is deleted, then its contents will become empty and it will be
   113  // marked as deleted until it expires, and then it will cease to exist.
   114  func (tx *FileCreateTransaction) SetExpirationTime(expiration time.Time) *FileCreateTransaction {
   115  	tx._RequireNotFrozen()
   116  	tx.expirationTime = &expiration
   117  	return tx
   118  }
   119  
   120  func (tx *FileCreateTransaction) GetExpirationTime() time.Time {
   121  	if tx.expirationTime != nil {
   122  		return *tx.expirationTime
   123  	}
   124  
   125  	return time.Time{}
   126  }
   127  
   128  // SetContents sets the bytes that are the contents of the file (which can be empty). If the size of the file and other
   129  // fields in the transaction exceed the max transaction size then FileCreateTransaction can be used to continue
   130  // uploading the file.
   131  func (tx *FileCreateTransaction) SetContents(contents []byte) *FileCreateTransaction {
   132  	tx._RequireNotFrozen()
   133  	tx.contents = contents
   134  	return tx
   135  }
   136  
   137  // GetContents returns the bytes that are the contents of the file (which can be empty).
   138  func (tx *FileCreateTransaction) GetContents() []byte {
   139  	return tx.contents
   140  }
   141  
   142  // SetMemo Sets the memo associated with the file (UTF-8 encoding max 100 bytes)
   143  func (tx *FileCreateTransaction) SetMemo(memo string) *FileCreateTransaction {
   144  	tx._RequireNotFrozen()
   145  	tx.memo = memo
   146  	return tx
   147  }
   148  
   149  // GetMemo returns the memo associated with the file (UTF-8 encoding max 100 bytes)
   150  func (tx *FileCreateTransaction) GetMemo() string {
   151  	return tx.memo
   152  }
   153  
   154  // ---- Required Interfaces ---- //
   155  
   156  // Sign uses the provided privateKey to sign the transaction.
   157  func (tx *FileCreateTransaction) Sign(
   158  	privateKey PrivateKey,
   159  ) *FileCreateTransaction {
   160  	tx.Transaction.Sign(privateKey)
   161  	return tx
   162  }
   163  
   164  // SignWithOperator signs the transaction with client's operator privateKey.
   165  func (tx *FileCreateTransaction) SignWithOperator(
   166  	client *Client,
   167  ) (*FileCreateTransaction, error) {
   168  	// If the transaction is not signed by the _Operator, we need
   169  	// to sign the transaction with the _Operator
   170  	_, err := tx.Transaction.signWithOperator(client, tx)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  	return tx, nil
   175  }
   176  
   177  // SignWith executes the TransactionSigner and adds the resulting signature data to the Transaction's signature map
   178  // with the publicKey as the map key.
   179  func (tx *FileCreateTransaction) SignWith(
   180  	publicKey PublicKey,
   181  	signer TransactionSigner,
   182  ) *FileCreateTransaction {
   183  	tx.Transaction.SignWith(publicKey, signer)
   184  	return tx
   185  }
   186  
   187  // AddSignature adds a signature to the transaction.
   188  func (tx *FileCreateTransaction) AddSignature(publicKey PublicKey, signature []byte) *FileCreateTransaction {
   189  	tx.Transaction.AddSignature(publicKey, signature)
   190  	return tx
   191  }
   192  
   193  // When execution is attempted, a single attempt will timeout when tx deadline is reached. (The SDK may subsequently retry the execution.)
   194  func (tx *FileCreateTransaction) SetGrpcDeadline(deadline *time.Duration) *FileCreateTransaction {
   195  	tx.Transaction.SetGrpcDeadline(deadline)
   196  	return tx
   197  }
   198  
   199  func (tx *FileCreateTransaction) Freeze() (*FileCreateTransaction, error) {
   200  	_, err := tx.FreezeWith(nil)
   201  	return tx, err
   202  }
   203  
   204  func (tx *FileCreateTransaction) FreezeWith(client *Client) (*FileCreateTransaction, error) {
   205  	if tx.IsFrozen() {
   206  		return tx, nil
   207  	}
   208  	tx._InitFee(client)
   209  	if err := tx._InitTransactionID(client); err != nil {
   210  		return tx, err
   211  	}
   212  	body := tx.build()
   213  
   214  	return tx, _TransactionFreezeWith(&tx.Transaction, client, body)
   215  }
   216  
   217  // SetMaxTransactionFee sets the maximum transaction fee the operator (paying account) is willing to pay.
   218  func (tx *FileCreateTransaction) SetMaxTransactionFee(fee Hbar) *FileCreateTransaction {
   219  	tx._RequireNotFrozen()
   220  	tx.Transaction.SetMaxTransactionFee(fee)
   221  	return tx
   222  }
   223  
   224  // SetRegenerateTransactionID sets if transaction IDs should be regenerated when `TRANSACTION_EXPIRED` is received
   225  func (tx *FileCreateTransaction) SetRegenerateTransactionID(regenerateTransactionID bool) *FileCreateTransaction {
   226  	tx._RequireNotFrozen()
   227  	tx.Transaction.SetRegenerateTransactionID(regenerateTransactionID)
   228  	return tx
   229  }
   230  
   231  // SetTransactionMemo sets the memo for this FileCreateTransaction.
   232  func (tx *FileCreateTransaction) SetTransactionMemo(memo string) *FileCreateTransaction {
   233  	tx._RequireNotFrozen()
   234  	tx.Transaction.SetTransactionMemo(memo)
   235  	return tx
   236  }
   237  
   238  // SetTransactionValidDuration sets the valid duration for this FileCreateTransaction.
   239  func (tx *FileCreateTransaction) SetTransactionValidDuration(duration time.Duration) *FileCreateTransaction {
   240  	tx._RequireNotFrozen()
   241  	tx.Transaction.SetTransactionValidDuration(duration)
   242  	return tx
   243  }
   244  
   245  // ToBytes serialise the tx to bytes, no matter if it is signed (locked), or not
   246  func (tx *FileCreateTransaction) ToBytes() ([]byte, error) {
   247  	bytes, err := tx.Transaction.toBytes(tx)
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	return bytes, nil
   252  }
   253  
   254  // SetTransactionID sets the TransactionID for this FileCreateTransaction.
   255  func (tx *FileCreateTransaction) SetTransactionID(transactionID TransactionID) *FileCreateTransaction {
   256  	tx._RequireNotFrozen()
   257  
   258  	tx.Transaction.SetTransactionID(transactionID)
   259  	return tx
   260  }
   261  
   262  // SetNodeAccountID sets the _Node AccountID for this FileCreateTransaction.
   263  func (tx *FileCreateTransaction) SetNodeAccountIDs(nodeID []AccountID) *FileCreateTransaction {
   264  	tx._RequireNotFrozen()
   265  	tx.Transaction.SetNodeAccountIDs(nodeID)
   266  	return tx
   267  }
   268  
   269  // SetMaxRetry sets the max number of errors before execution will fail.
   270  func (tx *FileCreateTransaction) SetMaxRetry(count int) *FileCreateTransaction {
   271  	tx.Transaction.SetMaxRetry(count)
   272  	return tx
   273  }
   274  
   275  // SetMaxBackoff The maximum amount of time to wait between retries.
   276  // Every retry attempt will increase the wait time exponentially until it reaches this time.
   277  func (tx *FileCreateTransaction) SetMaxBackoff(max time.Duration) *FileCreateTransaction {
   278  	tx.Transaction.SetMaxBackoff(max)
   279  	return tx
   280  }
   281  
   282  // SetMinBackoff sets the minimum amount of time to wait between retries.
   283  func (tx *FileCreateTransaction) SetMinBackoff(min time.Duration) *FileCreateTransaction {
   284  	tx.Transaction.SetMinBackoff(min)
   285  	return tx
   286  }
   287  
   288  func (tx *FileCreateTransaction) SetLogLevel(level LogLevel) *FileCreateTransaction {
   289  	tx.Transaction.SetLogLevel(level)
   290  	return tx
   291  }
   292  
   293  func (tx *FileCreateTransaction) Execute(client *Client) (TransactionResponse, error) {
   294  	return tx.Transaction.execute(client, tx)
   295  }
   296  
   297  func (tx *FileCreateTransaction) Schedule() (*ScheduleCreateTransaction, error) {
   298  	return tx.Transaction.schedule(tx)
   299  }
   300  
   301  // ----------- Overridden functions ----------------
   302  
   303  func (tx *FileCreateTransaction) getName() string {
   304  	return "FileCreateTransaction"
   305  }
   306  func (tx *FileCreateTransaction) build() *services.TransactionBody {
   307  	return &services.TransactionBody{
   308  		TransactionFee:           tx.transactionFee,
   309  		Memo:                     tx.Transaction.memo,
   310  		TransactionValidDuration: _DurationToProtobuf(tx.GetTransactionValidDuration()),
   311  		TransactionID:            tx.transactionID._ToProtobuf(),
   312  		Data: &services.TransactionBody_FileCreate{
   313  			FileCreate: tx.buildProtoBody(),
   314  		},
   315  	}
   316  }
   317  
   318  func (tx *FileCreateTransaction) validateNetworkOnIDs(client *Client) error {
   319  	return nil
   320  }
   321  
   322  func (tx *FileCreateTransaction) buildScheduled() (*services.SchedulableTransactionBody, error) {
   323  	return &services.SchedulableTransactionBody{
   324  		TransactionFee: tx.transactionFee,
   325  		Memo:           tx.Transaction.memo,
   326  		Data: &services.SchedulableTransactionBody_FileCreate{
   327  			FileCreate: tx.buildProtoBody(),
   328  		},
   329  	}, nil
   330  }
   331  
   332  func (tx *FileCreateTransaction) buildProtoBody() *services.FileCreateTransactionBody {
   333  	body := &services.FileCreateTransactionBody{
   334  		Memo: tx.memo,
   335  	}
   336  
   337  	if tx.expirationTime != nil {
   338  		body.ExpirationTime = _TimeToProtobuf(*tx.expirationTime)
   339  	}
   340  
   341  	if tx.keys != nil {
   342  		body.Keys = tx.keys._ToProtoKeyList()
   343  	}
   344  
   345  	if tx.contents != nil {
   346  		body.Contents = tx.contents
   347  	}
   348  
   349  	return body
   350  }
   351  
   352  func (tx *FileCreateTransaction) getMethod(channel *_Channel) _Method {
   353  	return _Method{
   354  		transaction: channel._GetFile().CreateFile,
   355  	}
   356  }
   357  func (tx *FileCreateTransaction) _ConstructScheduleProtobuf() (*services.SchedulableTransactionBody, error) {
   358  	return tx.buildScheduled()
   359  }