New TZIP draft: transaction memos

I’d like to include memos with some of the transfers I send around on the chain. I posted a proposal that’s light-weight, doesn’t incur high costs and is easy for wallets to implement.

The proposal is here, the related sample contract is here and the merge request.

Thank you for your consideration


Bakers need a direct way of communicating with delegates sometimes and something like this would be a very good step in the right direction. Airdrops of any sort would be improved with memos as well. This seems to be a very good thing.


Support for 0 value transactions that don’t forward? On top of adding a memo to a single TX there are many use cases for making a memo part of a batch to annotate it.


Great Idea !


tezos doesn’t allow 0-amount transactions to implicit accounts. in general though, you want the operation to forward to the destination address such that the wallet software has a trigger to parse the operation group and note the memo in the top-level call. so sending a memo to someone will require that they also get 0.000001 xtz.

I really like this idea :raised_hands:

Is the idea of the proxy contract approach, that the “memo” will be in the transaction and that wallets / explorers / indexers will parse & display the “memo” if THE proxy contract is used? And the reason for a tzip is that it would be a specific contract that will be used for this?

As I understand it, It feels a bit like this is something that can and should be solved in the protocol layer - albeit it will be a bit more involved :sweat_smile:


the idea is that if you send an operation group that starts with a call to the memo proxy and then does the asset transfer as in internal transaction, it’s easy to get the parent transaction arguments and display them in the wallet, indexer, etc. this way the memo isn’t being stored in the contract and is cheap to use. the TZIP specifies the interface. the contract is written to be completely trustless.

this could be part of the protocol, but i’d like to demonstrate that not everything needs to be a protocol upgrade and be written in ocaml. the LB smart contract is a contract also for example.

1 Like

I see :blush: It’s a good and very useful idea :raised_hands:

Would be interested to hear some feedback from wallet / indexer creators. Will it be easy for them to identify such an operation group? :thinking:

I do still think that it would be super useful for transactions to support this by default, so we would not have to use a proxy contract in order to attach a memo. But this is a great first step :+1:

It works great as a dapp too :sweat_smile: :sparkles:

Good initiative Mike. I don’t quite understand why memo and value transfer have to be connected that way. The additional complexity this creates downstream (indexer/explorer/matching algos) feels unnecessary. The problems I see with the proxy-forward approach are the following:

  1. You create a mixer which for all intents and purposes is not what you want and not what your users want. The first illicit funds transfer will taint the proxy address and all its users with it. AML providers need to implement an extra whitelist for this contract to prevent user wallets from being flagged when they send funds to an exchange.

  2. The extra hop will increase complexity for different scenarios, e.g. our baker payout matching algorithms. When we summarize and display which delegator has received payouts we look at transactions sent by any of the payout addresses associated with any of the bakers a delegator has ever delegated to. If you put an extra hop in between (even if its the same operation group) our code complexity probably more than doubles. (Reason is that all data models for operations in Tezos assume a single sender and a single receiver, this is how we all built our databases).

  3. The way we (maybe other explorers too) display transactions on account pages today is that we individually show effects of each atomic event (i.e. all external and internal transactions in a group are handled separate and produce separate output lines if you will). We don’t aggregate over internal transactions or operation groups because this would require us to understand the semantics of each contract. What that means is that with your proxy in the middle, all transfers sent to or from that proxy will display on the counterparty account as being sent to or received from the proxy instead of the other user (and only the sender side will display the memo). I have no desire to reengineer this explorer logic as it is already complicated enough.

Potential solution

I wonder why the proxy contract has to forward a value transfer. Why can’t we just create an operation group with a memo call (first or second) plus the normal tez or FA transfer? This approach would compose with other patterns allow/transfer/revoke too. Baker payouts to multiple receivers could have interleaved memos. Its kind of similar to how you have to hack the same thing as Ethereum logs/events in Tezos today.


If we go the route of a proxy contract then maybe something like the babylon might be better since it does not limit what transactions it can proxy.
While I agree with the arguments @Alex makes another solution that circumvents the same problems might be to add a memo field to transactions in the protocol, this would also help with gas consumption :thinking:

1 Like

I can send data to any arbitrary endpoint without anything other than a tx fee, requiring funds to go through the contract in order to add a memo limits functionality.

On other chains this can be done all day, and tezos is capable of it too, why apply an unnecessary artificial limitation. A separate endpoint would suffice and it would be a much more useful tool.


It’s not clear what benefit there is to add an FA transfer to this. A canonical contract with a bytes entrypoints that simply drops its input would achieve the same thing. A memo can be added to any manager operation by including one or several such calls in the batch.


thank you for your feedback.

  1. it is not a mixer, there is a direct relationship between the call to the proxy and a subsequent transfer.

  2. the extra hop is meant to be as easy as possible to parse. i agree that additional support would be needed but to me this is a useful feature worth adding support for.

  3. similar complexity exists already when dealing with the very numerous wrapped tezos tokens on the platform.

you’re right, it would be possible to create an operation group containing a call to the contract to the memo and a separate transaction to send the balance. that feels like bad UX because you’re breaking up a single operation into two. like sending a blank postcard and then texting the message you meant to write in it.

an FA transfer is useful if/when platforms start accepting stable coins as payment. or when air-dropping NFTs for winning a contest, etc.

this contract has specific entry points for ease of use and understanding. certainly you can craft a similar operation using the manager contract, but that would require users to have much deeper understanding of the platform to read the operation that’s encoded in the call.

i’m proposing a change that doesn’t require a platform update in ocaml. if someone wants to do that instead… :rocket:

You can do an FA transfer regardless, there is no reason to integrate it directly with the memo since you can achieve that by adding it to any batch operation.


adding a functional method that takes no funds or token does not require changes to the protocol, you can do that all in contract. there are many contracts on the chain that do this now. Im not sure I fully understand the resistance to a feature that makes it easier to trust and allows more flexibility.

To be frank, I dont want to send my funds through unnecessary contracts. I need to be convinced why I would want to do this, so far all Im seeing is “because”

1 Like

The description in the proposal for the default entrypoint confused me and seemed counterintuitive. It wasn’t until I looked at the code in the sample contract that I realized I had interpreted it to mean the opposite of what was intended.

This entrypoint always fails to prevent incoming XTZ transfers.

I read this as “This entrypoint never succeeds at preventing incoming XTZ transfers.” Perhaps it could be reworded to make the intent more clear. Maybe something like “This entrypoint always fails. This is done to prevent incoming XTZ transfers.”

1 Like

While this is a great attempt, I’d rather see this become part of the core protocol. By using a contract you are requiring additional steps, the use of gas, and additional complexity; it’s more complex (cpu/memory) for a individual node to “execute” a smart contract than simply manage a transfer. A simpler implementation, something far simpler for inexperienced users, and far easier for wallet makers to integrate, is to simply add a ‘memo’ field to the existing transfer function.

Yes, please make this happen. We bakers need a way to send messages to our delegators. Also delegators of discontinued bakers could be informed. A possible issue I see is Spam. Can the ability to send messages be limited to accounts that are associated in some way?