55Module for creating and validating Hedera token transactions.
66
77This module includes:
8- - TokenCreateValidator: Validates token creation parameters.
98- TokenParams: Represents token attributes.
109- TokenKeys: Represents cryptographic keys for tokens.
1110- TokenCreateTransaction: Handles token creation transactions on Hedera.
1211"""
1312
1413from __future__ import annotations
1514
15+ import ctypes
1616from dataclasses import dataclass , field
17- from typing import Any
1817
1918from hiero_sdk_python .account .account_id import AccountId
2019from hiero_sdk_python .channels import _Channel
@@ -104,101 +103,6 @@ class TokenKeys:
104103 fee_schedule_key : Key | None = None
105104
106105
107- class TokenCreateValidator :
108- """Token, key and freeze checks for creating a token as per the proto."""
109-
110- @staticmethod
111- def _validate_token_params (token_params : TokenParams ) -> None :
112- """Ensure valid values for the token characteristics."""
113- TokenCreateValidator ._validate_required_fields (token_params )
114- TokenCreateValidator ._validate_name_and_symbol (token_params )
115- TokenCreateValidator ._validate_initial_supply (token_params )
116- TokenCreateValidator ._validate_decimals_and_token_type (token_params )
117- TokenCreateValidator ._validate_supply_max_and_type (token_params )
118-
119- @staticmethod
120- def _validate_token_freeze_status (keys : TokenKeys , token_params : TokenParams ) -> None :
121- """Ensure account is not frozen for this token."""
122- if token_params .freeze_default and not keys .freeze_key :
123- raise ValueError ("Token is permanently frozen. Unable to proceed." )
124- # freezeDefault=True simply starts accounts frozen; allow creation as long as
125- # a freeze key exists so the treasury (and others) can be unfrozen later.
126-
127- @staticmethod
128- def _validate_required_fields (token_params : TokenParams ) -> None :
129- """Ensure all required fields are present and not empty."""
130- required_fields : dict [str , Any ] = {
131- "Token name" : token_params .token_name ,
132- "Token symbol" : token_params .token_symbol ,
133- "Treasury account ID" : token_params .treasury_account_id ,
134- }
135- for _field , _value in required_fields .items ():
136- if not _value :
137- raise ValueError (f"{ _field } is required" )
138-
139- @staticmethod
140- def _validate_name_and_symbol (token_params : TokenParams ) -> None :
141- """Ensure the token name & symbol are valid in length and do not contain a NUL character."""
142- if len (token_params .token_name .encode ()) > 100 :
143- raise ValueError ("Token name must be between 1 and 100 bytes" )
144- if len (token_params .token_symbol .encode ()) > 100 :
145- raise ValueError ("Token symbol must be between 1 and 100 bytes" )
146-
147- # Ensure the token name and symbol do not contain a NUL character
148- for attr in ["token_name" , "token_symbol" ]:
149- if "\x00 " in getattr (token_params , attr ):
150- raise ValueError (f"{ attr .replace ('_' , ' ' ).capitalize ()} must not contain the Unicode NUL character" )
151-
152- @staticmethod
153- def _validate_initial_supply (token_params : TokenParams ) -> None :
154- """Ensure initial supply is a non-negative integer and does not exceed max supply."""
155- MAXIMUM_SUPPLY = 9_223_372_036_854_775_807 # 2^63 - 1
156-
157- if token_params .initial_supply < 0 :
158- raise ValueError ("Initial supply must be a non-negative integer" )
159- if token_params .initial_supply > MAXIMUM_SUPPLY :
160- raise ValueError (f"Initial supply cannot exceed { MAXIMUM_SUPPLY } " )
161- if token_params .max_supply > MAXIMUM_SUPPLY :
162- raise ValueError (f"Max supply cannot exceed { MAXIMUM_SUPPLY } " )
163-
164- @staticmethod
165- def _validate_decimals_and_token_type (token_params : TokenParams ) -> None :
166- """Ensure decimals and token_type align with either fungible or non-fungible constraints."""
167- if token_params .decimals < 0 :
168- raise ValueError ("Decimals must be a non-negative integer" )
169-
170- if token_params .token_type == TokenType .FUNGIBLE_COMMON :
171- # Fungible tokens must have an initial supply > 0
172- if token_params .initial_supply <= 0 :
173- raise ValueError ("A Fungible Token requires an initial supply greater than zero" )
174-
175- elif token_params .token_type == TokenType .NON_FUNGIBLE_UNIQUE :
176- # Non-fungible tokens must have zero decimals and zero initial supply
177- if token_params .decimals != 0 :
178- raise ValueError ("A Non-fungible Unique Token must have zero decimals" )
179- if token_params .initial_supply != 0 :
180- raise ValueError ("A Non-fungible Unique Token requires an initial supply of zero" )
181-
182- @staticmethod
183- def _validate_supply_max_and_type (token_params : TokenParams ) -> None :
184- """Ensure max supply and supply type constraints."""
185- # An infinite token must have max supply = 0.
186- # A finite token must have max supply > 0.
187- # Setting a max supply is only approprite for a finite token.
188- if token_params .max_supply != 0 and token_params .supply_type != SupplyType .FINITE :
189- raise ValueError ("Setting a max supply field requires setting a finite supply type" )
190-
191- # Finite tokens have the option to set a max supply >0.
192- # A finite token must have max supply > 0.
193- if token_params .supply_type == SupplyType .FINITE :
194- if token_params .max_supply <= 0 :
195- raise ValueError ("A finite supply token requires max_supply greater than zero 0" )
196-
197- # Ensure max supply is greater than initial supply
198- if token_params .initial_supply > token_params .max_supply :
199- raise ValueError ("Initial supply cannot exceed the defined max supply for a finite token" )
200-
201-
202106class TokenCreateTransaction (Transaction ):
203107 """
204108 Represents a token creation transaction on the Hedera network.
@@ -473,12 +377,6 @@ def _build_proto_body(self) -> token_create_pb2.TokenCreateTransactionBody:
473377 Raises:
474378 ValueError: If required fields are missing or invalid.
475379 """
476- # Validate all token params
477- TokenCreateValidator ._validate_token_params (self ._token_params )
478-
479- # Validate freeze status
480- TokenCreateValidator ._validate_token_freeze_status (self ._keys , self ._token_params )
481-
482380 # Convert keys
483381 admin_key_proto = key_to_proto (self ._keys .admin_key )
484382 supply_key_proto = key_to_proto (self ._keys .supply_key )
@@ -505,8 +403,8 @@ def _build_proto_body(self) -> token_create_pb2.TokenCreateTransactionBody:
505403 return token_create_pb2 .TokenCreateTransactionBody (
506404 name = self ._token_params .token_name ,
507405 symbol = self ._token_params .token_symbol ,
508- decimals = self ._token_params .decimals ,
509- initialSupply = self ._token_params .initial_supply ,
406+ decimals = ctypes . c_uint32 ( self ._token_params .decimals ). value ,
407+ initialSupply = ctypes . c_uint64 ( self ._token_params .initial_supply ). value ,
510408 tokenType = token_type_value ,
511409 supplyType = supply_type_value ,
512410 maxSupply = self ._token_params .max_supply ,
0 commit comments