skip to Main Content

I’ve done the following steps 1 through 3, and figuring out how to complete step 4.

(1) Generate several several EVM addresses (evmAddress*) locally, and those EVM addresses do not have accounts on the Hedera network yet.

(2) Create a TransferTransaction which transfers from an existing account (operatorId) to the EVM addresses, like so:

const tinyBarsPerHbar = 100_000_000;
const multiTransferTx = new TransferTransaction()
        .addHbarTransfer(operatorId, -30 * tinyBarsPerHbar)
        .addHbarTransfer(evmAddress1, 10 * tinyBarsPerHbar)
        .addHbarTransfer(evmAddress2, 10 * tinyBarsPerHbar)
        .addHbarTransfer(evmAddress3, 10 * tinyBarsPerHbar)
        .freezeWith(client)
        .sign(operatorKey);
const transferTxResponse = await multiTransferTx.execute(client);

(3) When multiTransferTx completes, the EVM addresses now have accounts on the Hedera network lazily created, and associated with them

(4) Now need to find out what account ID each EVM address maps to, i.e. produce something like this:

{
  evmAddress1: accountId1,
  evmAddress2: accountId2,
  evmAddress3: accountId3,
}

How can step 4 be accomplished?


Note:

I have self-answered below, with a caveat that unfortunately makes it a not-good-enough solution. Would like to receive another answer that isn’t subject to this caveat where the order/ mapping is guaranteed.

2

Answers


  1. Chosen as BEST ANSWER

    Step 4 can be accomplished, with a caveat, described below, using the following code

        // obtain `transferTxId` from `multiTransferTx`
    
        // convert transaction ID to a Mirror Node API URL
        const [idPart1, idPart2] = transferTxId.split('@');
        const transferTxIdMnFormat = `${idPart1}-${idPart2.replace('.', '-')}`;
        const transferTxMnResponse = await fetch(`https://testnet.mirrornode.hedera.com/api/v1/transactions/${transferTxIdMnFormat}?nonce=0`);
        const transferTxMnResult = await transferTxMnResponse.json();
    
        // parse 
        const transfers = transferTxMnResult.transactions[0].transfers;
    

    This produces an output similar to this:

    [
      { account: '0.0.5', amount: 4547, is_approval: false },
      { account: '0.0.98', amount: 96793, is_approval: false },
      { account: '0.0.800', amount: 10754, is_approval: false },
      { account: '0.0.1521', amount: -2000112094, is_approval: false },
      { account: '0.0.1529253', amount: 1000000000, is_approval: false },
      { account: '0.0.1529255', amount: 1000000000, is_approval: false },
      { account: '0.0.1530238', amount: 1000000000, is_approval: false }
    ]
    

    Subsequently, filtering this list by amount === 1000000000, yields the account IDs that I want.


    The caveat:

    The above approach works, however, it does not state which account IDs map to which EVM addresses. We can make the assumption that the order in which these account IDs appear is the same as the order in which addHbarTransfer is called when creating the multiTransferTx. And manual testing seems to bear this out - the order does indeed match. However, this is not documented behaviour, and thus is not guaranteed. We don't even know if the order is deterministic.


  2. You can query the account id of the accounts created by following these step:

    1. Get the tx record:

      const transferToAliasRec = await transferToAliasSubmit.getRecord(client);

    2. Perform a record query with .setIncludeChildren() set to true:

      const txRec = await new TransactionRecordQuery().setTransactionId(transferToAliasRec.transactionId).setIncludeChildren(true).execute(client);

    3. Iterate through the children with i to get the account id from the receipt from each child tx:

      `console.log(`- New account ID: ${txRec.children[i].receipt.accountId.toString()} n`);
      
    4. [Optional] Double check on HashScan

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search