1

I have 9.9 tezos on my address tz2B35M8eHC6FhAVsQrtp8EBPri4H73w7W7C. I want to send all of it to another address tz1i4ezL2FZ1kZ8oqEY8n6wCr2eGRJPC4xin which has never been used and is thus empty. For this I need to make an estimate to get the storage limit, gas limit, operation bytes etc.

I have the following code to make this estimate.

Tezos transaction class


import { Tezos } from 'taquito/dist/lib/taquito';
import { Estimate } from 'taquito/dist/lib/contract/estimate';
import { XTZSigner } from './xtz-signer';

class XTZTX {
    
    private xtzSigner: XTZSigner;

    constructor() {
        this.xtzSigner = new XTZSigner('tz2B35M8eHC6FhAVsQrtp8EBPri4H73w7W7C'); // my address
        await Tezos.setProvider({ rpc: 'https://api.tez.ie/rpc/mainnet', signer: this.xtzSigner });
    }

    makeEstimate() {
        const receiver = 'tz1i4ezL2FZ1kZ8oqEY8n6wCr2eGRJPC4xin'; // Empty unused address
        const amountToSend = 9900000 // All muTez (9.9 tz) available on my account
        const estimateParams = { to: receiver, amount: 9900000 };
        const estimate = await Tezos.estimate.transfer(estimateParams);
    }
}

Signer class that implements the Taquito Signer interface

import { Signer } from 'taquito/dist/lib/signer/interface';

export class XTZSigner implements Signer {

  private address: string;
  private pubkey: string;

  constructor(address: string) {
    this.address = address;
  }

  publicKeyHash(): Promise<string> {
    return Promise.resolve(this.address);
  }

  publicKey(): Promise<string> {
    const pk = b58cencode(this.pubkey, sppkPrefix);
    return Promise.resolve(pk);
  }

  secretKey(): Promise<string> {
    throw new Error('Secret key cannot be exposed');
  }

  public async sign(
    bytes: string,
    watermark?: Uint8Array
  ): Promise<void> {
    return undefined;
  }
}

So I set the amountToSend variable to my account's full supply (9 900 000 muTez), ran the makeEstimate() function, but then then Tezos.estimate.transfer() returned the following error:

Error: {
      "errors": [
        {
          "kind": "temporary",
          "id": "proto.008-PtEdo2Zk.contract.balance_too_low",
          "contract": "tz2B35M8eHC6FhAVsQrtp8EBPri4H73w7W7C",
          "balance": "9898580",
          "amount": "9900000"
        }
      ],
      "name": "TezosOperationError",
      "id": "proto.008-PtEdo2Zk.contract.balance_too_low",
      "kind": "temporary",
      "message": "(temporary) proto.008-PtEdo2Zk.contract.balance_too_low"
    }

It says my balance is 9898580. But https://tzstats.com/tz2B35M8eHC6FhAVsQrtp8EBPri4H73w7W7C says it is 9900000. I have double-checked this with Taquito's getBalance() function:

Tezos.tz
  .getBalance('tz2B35M8eHC6FhAVsQrtp8EBPri4H73w7W7C')
  .then((balance) => console.log(`${balance.toNumber()}`))
  .catch((error) => println(JSON.stringify(error)));

So I guess Taquito subtracted 1420 from my account's balance. Why 1420, what is this number? Anyway, then I thought I'd decrease the "amount" property to 9898580:

const estimateParams = { to: receiver, amount: 9898580 };

Running the makeEstimate() function again now causes the follow error to be thrown:

    Error: {
      "errors": [
        {
          "kind": "temporary",
          "id": "proto.008-PtEdo2Zk.contract.cannot_pay_storage_fee"
        },
        {
          "kind": "permanent",
          "id": "proto.008-PtEdo2Zk.context.storage_error",
          "missing_key": [
            "contracts",
            "index",
            "06",
            "04",
            "bf",
            "10",
            "9b",
            "5d",
            "00011dd9f2781e3f8c512f871e17d7624e43ad2b4b55",
            "balance"
          ],
          "function": "get"
        }
      ],
      "name": "TezosOperationError",
      "id": "proto.008-PtEdo2Zk.context.storage_error",
      "kind": "permanent",
      "message": "(permanent) proto.008-PtEdo2Zk.context.storage_error"
    }

Okay, so this time I do have enough balance, but I cannot pay the storage fee. So I tried lowering the amount even more to 9000000, and this time it worked. However, I would like to automate this process. Now I can just keep trying to lower the amount until I don't get errors anymore, but I would like to determine this amount automatically so I never get these errors again. Exactly how can I calculate how much I need to subtract so I have enough balance and enough for storage fee? What is the formula for this?

1

[Edit] As Simon has suggested, the fee has been reduced, and the only restriction is to have 1 mutez left on the account or undelegate the account if the account is used for delegation. Jev suggested a link to the newly provided documentation.

Tezos does not allow for sending the whole address balance, some dust left on the account is required to be able to execute a transaction. Some wallets require a minimum of 0.27XTZ or 0.275XTZ. The official documentation can be found here.

1
  • This is not correct. you can empty an account provided you pay the correct fees. The only restriction Tezos forces, is accounts that are delegated either must undelegate or leave 1 mutez in their wallet. 0.275 is the old default reveal / burn fee, which has been reduced now. You need to estimate the transaction and then check the return to see are these burn fees required, if so, deduct that amount from the sending amount – Simon McLoughlin Mar 19 at 17:19
1

Tezos Taquito has docs on how to drain an account which you can find here: https://tezostaquito.io/docs/drain_account

It covers how to drain implicit and originated accounts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.