# Lazy Account Creation (Gas)

## Sending to New Addresses on Goliath

When sending native XCN or tokens to an address that **does not yet exist** on Goliath, the chain automatically creates a new account via "lazy-create" (hollow account creation). This requires significantly more gas than a standard transfer.

{% hint style="warning" %}
**A hardcoded gas limit of 21,000 will fail with `INSUFFICIENT_GAS` when the destination address does not yet exist on Goliath.** Always use `eth_estimateGas` before submitting transactions.
{% endhint %}

## Gas Comparison

| Scenario                                             | Gas Required                       |
| ---------------------------------------------------- | ---------------------------------- |
| Transfer to an **existing** address                  | \~21,000                           |
| Transfer to a **new** address (triggers lazy-create) | \~587,000                          |
| Recommended `gasLimit` for lazy-create transfers     | **704,400** (587,000 + 20% buffer) |

The difference is roughly **28x** more gas for a transfer that triggers account creation compared to a transfer to an existing account.

## For Wallet and Frontend Developers

If you are building a wallet, dApp frontend, or any application that submits transactions on Goliath, follow these guidelines:

1. **Always call `eth_estimateGas` before submitting a transaction.** The Goliath JSON-RPC relay returns the correct estimate (\~587,000) when the destination triggers lazy-create, and \~21,000 when it does not.
2. **Do NOT hardcode gas limits.** A hardcoded 21,000 will succeed for existing accounts but fail for new addresses. Use `eth_estimateGas` every time.
3. **Do NOT cache gas estimates across transactions.** Each call to `eth_estimateGas` checks whether the destination account currently exists on-chain. An address that was new (lazy-create) in one block may already exist in the next.
4. **Add a safety buffer.** Apply a 10-20% buffer on top of the estimate to account for minor fluctuations:

```javascript
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('https://rpc.goliath.net');

async function sendWithEstimate(signer, to, value) {
  // Always estimate -- do not assume 21,000
  const estimated = await provider.estimateGas({
    from: signer.address,
    to: to,
    value: value
  });

  // Add 20% buffer
  const gasLimit = estimated * 120n / 100n;

  const tx = await signer.sendTransaction({
    to: to,
    value: value,
    gasLimit: gasLimit
  });

  return tx;
}
```

```python
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://rpc.goliath.net'))

def send_with_estimate(account, to, value):
    # Always estimate -- do not assume 21,000
    estimated = w3.eth.estimate_gas({
        'from': account.address,
        'to': to,
        'value': value
    })

    # Add 20% buffer
    gas_limit = int(estimated * 1.2)

    tx = {
        'to': to,
        'value': value,
        'gas': gas_limit,
        'nonce': w3.eth.get_transaction_count(account.address),
    }

    signed = account.sign_transaction(tx)
    return w3.eth.send_raw_transaction(signed.raw_transaction)
```

## For End Users

MetaMask, Brave Wallet, and other major wallets call `eth_estimateGas` automatically before each send. **No special action is needed** for normal usage.

If a transaction fails with `INSUFFICIENT_GAS`:

1. **Clear your wallet's activity/transaction cache.** In MetaMask: Settings > Advanced > Clear activity & nonce data. This forces the wallet to re-fetch the correct gas estimate instead of reusing a stale one.
2. **Retry the transaction.** The wallet will call `eth_estimateGas` again and receive the correct value.
3. **If using a custom script or CLI**, set `gasLimit` to at least **587,000** for transfers to new addresses, or better yet, call `eth_estimateGas` and apply a buffer as shown above.

## Technical Details

Goliath is built on the Hedera consensus layer. When a transfer targets an EVM address that has no corresponding account on the ledger, the relay node automatically triggers a `CryptoCreate` operation to establish the account before completing the transfer. This is called **lazy-create** or **hollow account creation**.

### How gas is calculated

The gas requirement for lazy-create is derived from the underlying Hedera fee schedule:

```
gasCost = CryptoCreateFee * 1000 / gasPrice
```

At current fee levels, this works out to approximately 587,000 gas units. The exact value may vary slightly as the Hedera fee schedule is updated, which is why calling `eth_estimateGas` is always the correct approach.

### Address requirements

The destination address must be a valid ECDSA-derived address (the result of `keccak256` applied to a secp256k1 public key). Synthetic addresses that do not correspond to a real public key -- for example, `0x0000000000000000000000000000000000CAFE` -- will fail with `INVALID_ALIAS_KEY`.

This means lazy-create works for any standard Ethereum wallet address but will reject addresses that were manually constructed or derived from non-ECDSA key types.

### When lazy-create does NOT apply

Lazy-create is only triggered for addresses that have never received a transaction on Goliath. Once an account exists, all subsequent transfers to that address use the standard \~21,000 gas. There is no way to "re-trigger" lazy-create for an existing account.

## Related Pages

* [EVM JSON-RPC API](/apis/evm-json-rpc.md) -- `eth_estimateGas` reference and gas limits
* [XCN Decimal Handling](/developer-guide/decimal-handling.md) -- another Goliath-specific EVM difference
* [Getting Started](/developer-guide/getting-started.md) -- development environment setup and gas estimation examples
* [Quick Start](/user-guide/quickstart.md) -- wallet setup and first transaction


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.goliath.net/developer-guide/lazy-create-gas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
