Memo

Memo Keys

In BitShares, memos are AES-256 encrypted with a shared secret between sender and receiver. It is derived from the memo private key of the sender and the memo publick key of the receiver.

In order for the receiver to decode the memo, the shared secret has to be derived from the receiver’s private key and the senders public key.

The memo public key is part of the account and can be retreived with the get_account call:

get_account <accountname>
{
  [...]
  "options": {
    "memo_key": "GPH5TPTziKkLexhVKsQKtSpo4bAv5RnB8oXcG4sMHEwCcTf3r7dqE",
    [...]
  },
  [...]
}

while the memo private key can be dumped with dump_private_keys

Memo Message

The take the following form:

{
  "from": "GPH5mgup8evDqMnT86L7scVebRYDC2fwAWmygPEUL43LjstQegYCC",
  "to": "GPH5Ar4j53kFWuEZQ9XhxbAja4YXMPJ2EnUg5QcrdeMFYUNMMNJbe",
  "nonce": "13043867485137706821",
  "message": "d55524c37320920844ca83bb20c8d008"
}

The fields from and to contain the memo public key of sender and receiver. The nonce is a random integer that is used for the seed of the AES encryption of the message.

Example

High Level

The high level memo class makes use of the pybitshares wallet to obtain keys for the corresponding accounts.

from bitshares.memo import Memo
from bitshares.account import Account

memoObj = Memo(
    from_account=Account(from_account),
    to_account=Account(to_account)
)
cipher = memoObj.encrypt(memo)
plain = memoObj.decrypt(cipher)

Low Level

from bitsharesbase.memo import memo
from bitsharesbase.account import PrivateKey, PublicKey

wifkey = "5....<wif>"
memo         = {
      "from": "GPH5mgup8evDqMnT86L7scVebRYDC2fwAWmygPEUL43LjstQegYCC",
      "to": "GPH5Ar4j53kFWuEZQ9XhxbAja4YXMPJ2EnUg5QcrdeMFYUNMMNJbe",
      "nonce": "13043867485137706821",
      "message": "d55524c37320920844ca83bb20c8d008"
    }
try :
    privkey = PrivateKey(wifkey)
    pubkey  = PublicKey(memo["from"], prefix=prefix)
    memomsg = memo.decode_memo(privkey, pubkey, memo["nonce"], memo["message"])
except Exception as e:
    memomsg = "--cannot decode-- %s" % str(e)

Definitions

bitsharesbase.memo.decode_memo(priv, pub, nonce, message)

Decode a message with a shared secret between Alice and Bob

Parameters:
  • priv (PrivateKey) – Private Key (of Bob)
  • pub (PublicKey) – Public Key (of Alice)
  • nonce (int) – Nonce used for Encryption
  • message (bytes) – Encrypted Memo message
Returns:

Decrypted message

Return type:

str

Raises:

ValueError – if message cannot be decoded as valid UTF-8 string

bitsharesbase.memo.encode_memo(priv, pub, nonce, message)

Encode a message with a shared secret between Alice and Bob

Parameters:
  • priv (PrivateKey) – Private Key (of Alice)
  • pub (PublicKey) – Public Key (of Bob)
  • nonce (int) – Random nonce
  • message (str) – Memo message
Returns:

Encrypted message

Return type:

hex

bitsharesbase.memo.get_shared_secret(priv, pub)

Derive the share secret between priv and pub

Parameters:
  • priv (Base58) – Private Key
  • pub (Base58) – Public Key
Returns:

Shared secret

Return type:

hex

The shared secret is generated such that:

Pub(Alice) * Priv(Bob) = Pub(Bob) * Priv(Alice)
bitsharesbase.memo.init_aes(shared_secret, nonce)

Initialize AES instance

Parameters:
  • shared_secret (hex) – Shared Secret to use as encryption key
  • nonce (int) – Random nonce
Returns:

AES instance

Return type:

AES