Account creation fee construction metadata

Background on Account Creation Fee in Coda

When a payment transaction transfers funds in the default token to an address that doesn’t exist in the ledger, a small account-creation-fee is charged to the receiver of a payment. This is done to provide some economic disincentive to filling up the ledger on chain.


Consider this payment which is included in a block created by Carl where account creation fee is 3:

Sender: Alice
Receiver: Bob
Fee: 10
Amount: 20
Do-not-pay-creation-fee: false

If the payment is applied when Bob’s account already exists in the ledger, the following balance changing events occur: Alice -10, Alice -20, Bob +20, Carl +10. If Bob’s account does not already exist in the ledger, all of the above events occur, and additionally Bob -3 and those 3 are removed from circulation. Bob’s ending balance depends on whether or not the account existed prior to the payment taking place.

Alice must have a balance of at least 30 in her account regardless if Bob’s account exists or not.

If Alice wants to ensure that Bob’s account exists, she can change her payment to set Do-not-pay-creation-fee to true. In that case, the payment will only successfully apply when Bob’s account already exists in the ledger.

Helpful Construction Metadata

What sort of metadata can we provide to help consumers of Rosetta integrate with our protocol?

Here is one idea: The following row could be included in the /construction/metadata payload { "expected_account_creation_fee_operation": Operation? }. When the requested operations when combined with information about the ledger preceding the payment (at the moment of hitting the endpoint) show that an account-creation-fee will be charged, the operation will be returned. If not, null will be sent instead.

Is there any other way to make this easier to consume?

Is there some optional way for the sender to pay this account creation fee? I say optional because we would probably like to pay any “account creation fee” on deposit (otherwise we will need to pre-create all deposit addresses).

We have seen a ton of confusion from users withdrawing from Coinbase into a personal address in blockchains that utilize a “receiver creation fee mechanism”. In short, users see a balance less than what they withdrew from Coinbase and believe we have a bug that caused them to be short-changed (this usually leads to a lot of support tickets). I think of this is represented clearly on block explorers, it shouldn’t be too confusing…

We would always want to set do-not-pay-creation-fee to false (otherwise it could appear like we could not withdraw funds for some users that didn’t understand the mechanics of your blockchain). That being said, I would suggest you provide the ability to optionally specify this is not desired in the ConstructionPreprocessRequest.Metadata. The metadata returned by /construction/metadata is treated as opaque by the caller so putting information there will likely not be inspected nor modified (but could be used by /construction/payloads).

On another note, I would strongly recommend representing this “receiver creation fee” as a separate operation in the transaction instead of just representing the increment of the receiver balance as send_amount - receiver_creation_fee. AKA don’t do Bob +17 in the example above (you should do Bob + 20, Bob -3).

Thank you for the feedback!

Unfortunately, this will be a large change for us, but we’ll be sure to spend time documenting this behavior well and working with block explorers to make it very clear.

Yes, makes sense!