bguiz
bguiz

Reputation: 28587

How to convert a Hedera native address into a non-long-zero EVM address?

Using Hedera SDK JS, I can convert an Account ID to "long-zero" format EVM address. e.g. 0.0.3996280 --> 0x00000000000000000000000000000000003cfa78

(See related question: "How to convert a Hedera native address into an EVM address?".)

How do I convert to the "non-long-zero" format EVM address? e.g. 0.0.3996280 --> 0x7394111093687e9710b7a7aeba3ba0f417c54474

(See 0.0.3996280 on Hashscan.)

I need this because when you send ContractCallQuery via Hedera SDKs, the value of msg.sender as visible within any smart contract functions invoked is the "non-long-zero" format EVM address.

What I'm doing currently:

const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorEvmAddress = operatorId.toSolidityAddress();

However, operatorEvmAddress is in the "long-zero" format, and I therefore cannot use that in my subsequent smart contract interactions.

Upvotes: 5

Views: 276

Answers (2)

bguiz
bguiz

Reputation: 28587

As mentioned in Ashe's answer, and requested in David's comment:

If you do not have access to the account's public key ... You will need to query the network state, for example through a Hedera mirror node query.​

Here is one way to do it, via the mirror node:

curl \
  --silent \
  -X 'GET' \
  -H 'accept: application/json' \
  'https://testnet.mirrornode.hedera.com/api/v1/accounts/0.0.3996280?limit=1' \
  | jq --raw-output ".evm_address"

This will output:

0x7394111093687e9710b7a7aeba3ba0f417c54474

which is indeed the non-long-zero EVM address that corresponds to this account.


Ref: Mirror Node Swagger for the above API: https://testnet.mirrornode.hedera.com/api/v1/docs/#/accounts/getAccountByIdOrAliasOrEvmAddress

Upvotes: 1

Ashe Oro
Ashe Oro

Reputation: 86

The answer depends on whether you have access to the public key of the account. Note that if you have the private key, you can extract the public key from it. ​ If you do not have access to the account's public key: ​ You can obtain the long-zero EVM address using the SDK, as this is a mathematical conversion. ​ However, you cannot obtain the non-long-zero EVM address using the SDK alone, as this is not a mathematical conversion. You will need to query the network state, for example through a Hedera mirror node query. ​ If you do have access to the account's public key: ​ You can obtain both the long-zero EVM address and the non-long-zero EVM address using the SDK. ​

const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorPrivateKey = PrivateKey.fromString(process.env.OPERATOR_KEY);
const operatorPublicKey = operatorPrivateKey.publicKey;
​
// AccountId.toSolidityAddress --> long-zero
const operatorEvmAddressLongZero = operatorId.toSolidityAddress();
​
// PublicKey.toEvmAddress --> non-long-zero
const operatorEvmAddressNonLongZero = operatorPublicKey.toEvmAddress();

Upvotes: 7

Related Questions