This document explains how to send and receive encrypted Zcash transaction memos using zcash-cli
(the RPC interface).
The not-so-user-friendly aspect of the RPC interface is that the memos are in hexadecimal string format. (The various
wallets, such as Zecwallet and ZECC wallet, hid this detail from their users.)
So to send as ascii text string as a memo requires first converting the string to hex, and to read the memo later
as a text string requires converting from hex back to a string.
The following two tools will be handy.
Use this small script for constructing the memo when sending:
#!/usr/bin/env python3
import sys
import codecs
for x in sys.argv[1:]:
print(codecs.encode(bytes(x, 'ascii'), 'hex').decode())
Pass it the string you wish to include in the memo:
$ ascii2hex 'hello zcash'
68656c6c6f207a63617368
$
This small script will convert a hex string to ascii, useful when receiving a transaction:
#!/usr/bin/env python3
import sys
import codecs
for x in sys.argv[1:]:
print(codecs.decode(x, 'hex').decode())
Each transaction output can have its own memo. Here's an example with one output, and we've copied and pasted the hex string for "hello zcash" as the memo:
zcash-cli z_sendmany ztestsapling13ushwzyrqd8gecatanpk2uvr0th9kly2sqlvdyyyhyp350ara0ldvqjj8xaxuhgmnaaz5keej2p '[{"memo":"68656c6c6f207a63617368","address": "ztestsapling1kg3u0y7szv6509732at34alct46cyn0g26kppgf2a7h5tpqxldtwm7cmhf8rqmhgtmpakcz5mdv","amount":0.01}]'
Remember that memos can be up to 512 ascii text characters (1024 hex digits). This transaction exists on testnet.
There are two APIs that display transaction memos. Receivers of a transaction can use z_listunspent
:
$ zcash-cli z_listunspent
[
{
"txid": "4b51581abed41e0c050e9a6dcd007b70d8db3737647c146c159a71124b986231",
"outindex": 0,
"confirmations": 15,
"spendable": true,
"address": "ztestsapling1kg3u0y7szv6509732at34alct46cyn0g26kppgf2a7h5tpqxldtwm7cmhf8rqmhgtmpakcz5mdv",
"amount": 0.01000000,
"memo": "68656c6c6f207a63617368000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"change": false
}
]
Or, either the sender or receiver (but no one else!) may use z_listreceivedbyaddress
:
zcash-cli z_listreceivedbyaddress ztestsapling1kg3u0y7szv6509732at34alct46cyn0g26kppgf2a7h5tpqxldtwm7cmhf8rqmhgtmpakcz5mdv
[
{
"txid": "4b51581abed41e0c050e9a6dcd007b70d8db3737647c146c159a71124b986231",
"amount": 0.01000000,
"memo": "68656c6c6f207a63617368000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"outindex": 0,
"confirmations": 15,
"blockheight": 956859,
"blockindex": 3,
"blocktime": 1591907179,
"change": false
}
]
$
Then the hex string can be converted back to ascii text:
$ hex2ascii 68656c6c6f207a63617368
hello zcash
$
This is amazing. Thanks for writing this up.