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?