Skip to main content

Documentation Index

Fetch the complete documentation index at: https://hedera-0c6e0218-update-evm-address-ecdsa-terminology.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Create an account using the account create API

A transaction that creates a Hedera account. A Hedera account is required to interact with any of the Hedera network services as you need an account to pay for all associated transaction/query fees. You can visit the Hedera Developer Portal to create a previewnet or testnet account. You can also use third-party wallets to generate free mainnet accounts. To process an account create transaction, you will need an existing account to pay for the transaction fee. To obtain the new account ID, request the receipt of the transaction.
When creating a new account using the AccountCreateTransaction() API you will need an existing account to pay for the associated transaction fee.
Recommended default for EVM compatibility: Create accounts with an ECDSA key and set the EVM Address from Public Key at creation. This enables native compatibility with EVM wallets, JSON-RPC tooling, and smart-contract interactions. Use setECDSAKeyWithAlias() (or setKeyWithAlias() with an ECDSA key) to do this in a single call.

Per-SDK quick reference

SDKOne-shot methodAccepts PublicKey?PublicKey.toEvmAddress() returnsAccountId.toEvmAddress()
JavaScriptsetECDSAKeyWithAlias(key)Yesstring (hex, no 0x)Yes
JavasetKeyWithAlias(key) (1-arg)YesEvmAddressYes
Pythonset_key_with_alias(key)YesEvmAddressYes
Rustset_ecdsa_key_with_alias(key)No — PrivateKey onlyOption<EvmAddress>Use to_solidity_address()
C++setECDSAKeyWithAlias(key)No — PrivateKey onlyEvmAddress (on ECDSAsecp256k1PublicKey)Use toSolidityAddress()
SwiftkeyWithAlias(_ privateKeyECDSA:)No — PrivateKey onlyEvmAddress?Yes (throws)
GoSetECDSAKeyWithAlias(key)Yesstring (hex, no 0x)Yes
Java naming: setKeyWithAlias(key) with one argument is Java’s equivalent of setECDSAKeyWithAlias(key) in other SDKs. The two-argument overload setKeyWithAlias(key, ecdsaKey) is used when the account key and the alias-derivation key differ.Long-zero address parallel: Rust and C++ do not expose toEvmAddress() on AccountId. They expose to_solidity_address() / toSolidityAddress() instead, which returns the same long-zero form (the EVM Address from Account ID). Functionally equivalent — just a naming difference.Swift throws: Swift’s AccountId.toEvmAddress() is declared throws, so call sites need try (e.g., try accountId.toEvmAddress()).

Transaction Fees and Signing

  • The sender pays for the token association fee and the rent for the first auto-renewal period.
  • See the transaction and query fees table for the base transaction fee.
  • Use the Hedera fee estimator to estimate your transaction fee cost.
  • The account paying for the transaction fee is required to sign the transaction.

Account Properties

For a complete list of account properties, see the accounts overview.

Maximum Auto-Associations and Fees

Accounts have a property, maxAutoAssociations, and the property’s value determines the maximum number of automatic token associations allowed.
Property ValueDescription
0Automatic token associations or token airdrops are not allowed, and the account must be manually associated with a token. This also applies if the value is less than or equal to usedAutoAssociations.
-1Unlimited automatic token associations are allowed, and this is the default for accounts created via auto account creation and for accounts that began as hollow accounts and are now complete. Accounts with -1 can receive new tokens without manually associating them. The sender still pays the maxAutoAssociations fee and initial rent for each association.
> 0If the value is a positive number (number greater than 0), the number of automatic token associations an account can have is limited to that number.
The sender pays the maxAutoAssociations fee and the rent for the first auto-renewal period for the association. This is in addition to the typical transfer fees. This ensures the receiver can receive tokens without association and makes it a smoother transfer process.
Reference: HIP-904

Methods

Exactly one of setKey / setKeyWithAlias / setECDSAKeyWithAlias / setKeyWithoutAlias is required.
MethodTypeKey type acceptedRequirement
setKey(<key>)KeyKey (PublicKey or PrivateKey)Optional. Sets the account key without an alias.
setKeyWithAlias(<key>)KeyKey (PublicKey or PrivateKey)Accepts ED25519 or ECDSA. Sets the EVM Address from Public Key only when given an ECDSA key.
setECDSAKeyWithAlias(<key>)Key (ECDSA)PrivateKey only in Rust/C++/Swift; PublicKey accepted in JS/Java/Python/GoRecommended for EVM use cases. Sets the key and sets the EVM Address from Public Key in one call.
setKeyWithoutAlias(<key>)KeyKey (PublicKey or PrivateKey)Sets the key without setting an EVM Address from Public Key. Use if you plan to rotate keys later (the account will fall back to the EVM Address from Account ID).
setAlias(<alias>)EvmAddressExplicitly sets the alias bytes. Pair with publicKey.toEvmAddress() (or to_evm_address() in Rust) to derive the EVM Address from Public Key.
setInitialBalance(<initialBalance>)HBarOptional
setReceiverSignatureRequired(<booleanValue>)booleanOptional
setMaxAutomaticTokenAssociations(<amount>)intOptional
setStakedAccountId(<stakedAccountId>)AccountIdOptional
setStakedNodeId(<stakedNodeId>)longOptional
setDeclineStakingReward(<declineStakingReward>)booleanOptional
setAccountMemo(<memo>)StringOptional
setAutoRenewPeriod(<autoRenewPeriod>)DurationDisabled
EVM Address from Public Key (recommended for EVM use cases)Setting an ECDSA-derived EVM address at creation makes the account natively addressable from EVM wallets, JSON-RPC, and Solidity (msg.sender). The address is the rightmost 20 bytes of the Keccak-256 hash of the ECDSA public key.Immutability: The EVM Address from Public Key is bound to the original ECDSA public key and does not change if you later rotate keys via CryptoUpdateTransaction. Integrations keyed to that EVM address (smart-contract permissions, address-based access lists) will continue to reference the original address.If key rotation is required: Use setKeyWithoutAlias() instead. The account will fall back to its EVM Address from Account ID (the long-zero form).Recovery model: If keys are compromised or must be replaced, create a new account with a new ECDSA key, then migrate assets and state. Do not rely on key rotation to preserve the same EVM identity.

Constructor

ConstructorDescription
new AccountCreateTransaction()Initializes the AccountCreateTransaction object

Transaction Properties

MethodTypeRequirement
setKey(<key>)KeyRequired
setInitialBalance(<initialBalance>)HbarOptional
setReceiverSignatureRequired(<booleanValue>)booleanOptional
setAutoRenewPeriod(<autoRenewPeriod>)DurationOptional
setAccountMemo(<memo>)StringOptional
setMaxAutomaticTokenAssociations(<amount>)intOptional
setStakedAccountId(<stakedAccountId>)AccountIdOptional
setStakedNodeId(<stakedNodeId>)longOptional
setDeclineStakingReward(<declineStakingReward>)booleanOptional
setHighVolume(<highVolume>)booleanOptional
This transaction supports high-volume entity creation (HIP-1313). Setting setHighVolume(true) routes the transaction through dedicated high-volume throttle capacity with variable-rate pricing. Always pair this with setMaxTransactionFee() to cap your costs.
//Create new ECDSA key
const ecdsaPublicKey = PrivateKey.generateECDSA().publicKey

//Create the transaction
const transaction = new AccountCreateTransaction()
    // Sets the EVM Address from Public Key (recommended for EVM compatibility)
    .setKeyWithAlias(ecdsaPublicKey)
    // Use .setKeyWithoutAlias(ecdsaPublicKey) if you plan to rotate keys soon after creation
    .setInitialBalance(new Hbar(1));

//Sign the transaction with the client operator private key and submit to a Hedera network
const txResponse = await transaction.execute(client);

//Request the receipt of the transaction
const receipt = await txResponse.getReceipt(client);

//Get the account ID
const newAccountId = receipt.accountId;

console.log("The new account ID is " + newAccountId);

//v2.0.5

Deriving the EVM address (toEvmAddress helper)

If you call setAlias(...) directly, derive the EVM address from the ECDSA public key with the SDK helper:
// publicKey.toEvmAddress() returns the EVM Address from Public Key (hex, no 0x prefix)
const evmAddress = ecdsaPublicKey.toEvmAddress();
const transaction = new AccountCreateTransaction()
  .setKey(ecdsaPublicKey)
  .setAlias(evmAddress)
  .setInitialBalance(new Hbar(1));
In most cases, prefer setECDSAKeyWithAlias(publicKey) — it sets the key and derives the alias in one call. Use the toEvmAddress helper when you need the value separately (for logging, validation, or paired with setAlias).
Note on overloading: toEvmAddress is also exposed on AccountId in some SDKs. AccountId.toEvmAddress() returns the EVM Address from Account ID (the long-zero form), not the EVM Address from Public Key. For EVM compatibility, you want the PublicKey variant. Rust and C++ name the equivalent method to_solidity_address() / toSolidityAddress() (same value, different name) — see the Per-SDK quick reference above.

Verifying the EVM address

After creating an account, confirm the EVM Address from Public Key was set correctly using either the SDK or the mirror node.

Using the SDK

const info = await new AccountInfoQuery()
  .setAccountId(newAccountId)
  .execute(client);
console.log(`EVM address: 0x${info.contractAccountId}`);
If the account was created with setKeyWithoutAlias(...), contractAccountId returns the EVM Address from Account ID (long-zero form, starting with 24 zero hex characters). If it was created with setECDSAKeyWithAlias(...) or equivalent, it returns the EVM Address from Public Key.

Using the mirror node REST API

# Look up by account ID
curl https://mainnet.mirrornode.hedera.com/api/v1/accounts/0.0.1234

# Look up by EVM address
curl https://mainnet.mirrornode.hedera.com/api/v1/accounts/0xab...cd
The evm_address field in the response is the canonical EVM address for the account.

Common pitfalls

Creating an ECDSA account with setKey() only. The account is valid and can hold HBAR, but it has no EVM Address from Public Key. It will fall back to its EVM Address from Account ID (long-zero form), which means:
  • It is not natively addressable from MetaMask or other EVM wallets keyed to the public-key EVM address.
  • Solidity contracts that compare msg.sender against the expected EVM address will not match.
  • JSON-RPC tooling expecting an ECDSA-derived address will see an unexpected long-zero address.
Use setECDSAKeyWithAlias(publicKey) (or setKeyWithAlias(publicKey) with an ECDSA key) instead.
Using deprecated PrivateKey.generate(). This helper silently returns an ED25519 key, which cannot be used to derive an EVM address. Use PrivateKey.generateECDSA() for new accounts.

Common consensus errors

Error codeCauseResolution
INVALID_ALIAS_KEYAlias is not derivable from the supplied key (typically an ED25519 key was used in an ECDSA alias flow).Use PrivateKey.generateECDSA() (or the equivalent in your SDK).
INVALID_SIGNATURETwo-key form (setKeyWithAlias(key, ecdsaKey)) was not signed by both the account key and the alias key.Sign the transaction with both keys before submitting.
ALIAS_ALREADY_ASSIGNEDThe EVM address is already in use by another account (e.g., a hollow account previously received funds at this address).Generate a fresh ECDSA key and try again, or complete the existing hollow account by signing a transaction from it.
ACCOUNT_ID_DOES_NOT_EXISTA query referenced an EVM address with no associated account.Confirm the account was created and the receipt returned SUCCESS.

Get Transaction Values

MethodTypeDescription
getKey()KeyReturns the public key on the account
getInitialBalance()HbarReturns the initial balance of the account
getAutoRenewPeriod()DurationReturns the auto renew period on the account
getDeclineStakingReward()booleanReturns whether or not the account declined rewards
getStakedNodeId()longReturns the node ID
getStakedAccountId()AccountIdReturns the node account ID
getReceiverSignatureRequired()booleanReturns whether the receiver signature is required or not
getReceiverSignatureRequired()booleanReturns whether the receiver signature is required or not
getHighVolume()booleanReturns whether this transaction uses high-volume throttles
This transaction supports high-volume entity creation (HIP-1313). Setting setHighVolume(true) routes the transaction through dedicated high-volume throttle capacity with variable-rate pricing. Always pair this with setMaxTransactionFee() to cap your costs.
See EVM Address from Public Key above for recommended defaults, immutability behavior, and key-rotation guidance.
//Create an account with 1 HBAR
const transaction = new AccountCreateTransaction()
    // Sets the EVM Address from Public Key (recommended for EVM compatibility)
    .setKeyWithAlias(newPublicKey)
    // Alternative if you expect to rotate keys soon after creation:
    // .setKeyWithoutAlias(newPublicKey)
    .setInitialBalance(new Hbar(1));

//Return the key on the account
const accountKey = transaction.getKey();