# 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](https://docs.goliath.net/apis/evm-json-rpc) -- `eth_estimateGas` reference and gas limits
* [XCN Decimal Handling](https://docs.goliath.net/developer-guide/decimal-handling) -- another Goliath-specific EVM difference
* [Getting Started](https://docs.goliath.net/developer-guide/getting-started) -- development environment setup and gas estimation examples
* [Quick Start](https://docs.goliath.net/user-guide/quickstart) -- wallet setup and first transaction
