ebellocchia/py_crypto_hd_wallet

Support for Bitcoin Cash (BCH) CashToken address type

Opened this issue · 1 comments

Bitcoin Cash is upgrading it's network to allow for miner validated tokens the implementation is called CashTokens. It adds two new CashAddress types are specified to indicate support for accepting tokens:

Type Bits Meaning
2 (0b0010) Token-Aware P2PKH
3 (0b0011) Token-Aware P2SH

Token-Aware CashAddresses

CashAddress Type Bits Size Bits Payload (Hex)
bitcoincash:qr7fzmep8g7h7ymfxy74lgc0v950j3r2959lhtxxsl 0 (P2PKH) 0 (20 bytes) fc916f213a3d7f1369313d5fa30f6168f9446a2d
bitcoincash:zr7fzmep8g7h7ymfxy74lgc0v950j3r295z4y4gq0v 2 (Token-Aware P2PKH) 0 (20 bytes) fc916f213a3d7f1369313d5fa30f6168f9446a2d
bchtest:qr7fzmep8g7h7ymfxy74lgc0v950j3r295pdnvy3hr 0 (P2PKH) 0 (20 bytes) fc916f213a3d7f1369313d5fa30f6168f9446a2d
bchtest:zr7fzmep8g7h7ymfxy74lgc0v950j3r295x8qj2hgs 2 (Token-Aware P2PKH) 0 (20 bytes) fc916f213a3d7f1369313d5fa30f6168f9446a2d

More info here:
https://github.com/bitjson/cashtokens#cashaddress-token-support

Could you please consider adding support for the new type.

Here's some more info, I wrote a "cheat sheet" a while ago:

CashAddress Cheat Sheet

It is constructed from bytes: version_byte || payload || checksum (|| indicates byte concatenation) that are then encoded using base32 with custom dictionary to get the human-readable CashAddress.

size_bits = version_byte & 0x07 - this extracts 3 lowest bits (bits 0-2) from the version_byte and it encodes the payload length. We've used only 0 (p2pkh & p2sh20) until now since payload was 20 bytes in both cases. p2sh32 will have size_bits == 3 since payload will be 32 bytes.

type_bits = version_byte >> 3 - this extracts bits 3-6. We've used only 0 (p2pkh) and 1 (p2sh20, and p2sh32 will have the same type_bits) until now. Token-aware addresses will be using 2 for p2pkh and 3 for token p2sh20 and p2sh32.

So, we will have these combinations:

  • p2pkh: 0x00 (b00000000) (size_bits == 0, type_bits == 0)
  • p2sh20: 0x08 (b00001000) (size_bits == 0, type_bits == 1)
  • p2sh32: 0x0b (b00001011) (size_bits == 3, type_bits == 1)
  • token p2pkh: 0x10 (b00010000) (size_bits == 0, type_bits == 2)
  • token p2sh20: 0x18 (b00011000) (size_bits == 0, type_bits == 3)
  • token p2sh32: 0x1b (b00011011) (size_bits == 3, type_bits == 3)

And raw output locking script must be constructed from the decoded payload like so:

  • p2pkh & token p2pkh: 0x76a914{payload}88ac
  • p2sh20 & token p2sh20: 0xa914{payload}87
  • p2sh32 & token p2sh32: 0xaa20{payload}87