Closed larrysalibra closed 6 years ago
@jcnelson wrote
Ah, I see what you mean. I'm definitely in favor of making the Stacks account identifier Stacks-specific. I agree that we should use a format that does not get confused with an existing cryptocurrency---the account identifier format should be Stacks-specific.
That being said, I have no strong opinions on what exactly the format will be. Do you have any suggestions? The only thing that might have been a good idea but we cannot do is change the address version to make the first character S, since we're already using those for subdomain addresses in DIDs. However, anything else is fine with me.
@anastik wrote
What about using a “$” at the front of each address? It might give off the wrong impression, but it still kind of uses the “S” and it easily denotes that it’s financial in nature. Could even be “$tx” or something along those lines.
@jcnelson wrote
@Anastik Nice idea, but we want to avoid country-specific money identifiers. $ is pretty US-centric.
That being said, I have no strong opinions on what exactly the format will be. Do you have any suggestions? The only thing that might have been a good idea but we cannot do is change the address version to make the first character S, since we're already using those for subdomain addresses in DIDs. However, anything else is fine with me.
Possible to us "S" for both? Is there any reason not to? We just don't want the same character as Bitcoin addresses right?
Can use "S" for both. The only point of confusion is that we already use S-encoded addresses for subdomain DIDs. Example:
$ python
Python 2.7.14 (default, Dec 14 2017, 15:51:29)
[GCC 6.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import blockstack
>>> blockstack.lib.client.get_name_DID('jude.statism.id', hostport='http://localhost:6264')
u'did:stack:v0:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i-0'
>>> blockstack.lib.client.resolve_DID('did:stack:v0:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i-0', hostport='http://localhost:6264')
{'public_key': '020fadbbcea0ff3b05f03195b41cd991d7a0af8bd38559943aec99cbdaf0b22cc8'}
What do you think of having a prefix in front of the address? Examples:
BSK:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg
(no special address formatting)STACKS:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg
(no special address formatting)BSK:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i
(special address encoding)STACKS:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i
(special address encoding)One important thing to keep in mind here is that this is going to interact with any wallet initialization that participants in the genesis block are going to be doing. So I think it's important for @yknl to see and weigh in on this.
If we don't want to look like Bitcoin, we should avoid base58check encoding.
Base58 Check Encoding has some pretty well thought out benefits though (doesn't use ambiguous characters, encodes checksums and zero-padding effectively). Getting those last two right can be unfortunately kind of bug-prone and I'd hate to introduce a bug here.
Another option is to use the S-prefixed base58 check address, but do something purely to the display like prefacing with 0-
and throwing a hyphen in at character 5:
0-SSXM-cDiCZ7yFSQSUj7mWzmDcdwYhq97p2i
Makes it look very different from a bitcoin address. I have nothing to add from a brand awareness or marketability perspective, but I think those are probably important perspectives to consider.
One thing about having hyphens or punctuation characters is that you can't double click it to select the whole string.
Let me see if I can summarize here:
0
)0
and O
cannot both be characters in the encoding, and nor can 1
and l
.To make it unambiguous, I highly recommend a short prefix be appended to addresses. This seems to have worked well for Ethereum, for example---a long hex string starting with 0x
is assumed to be an Ethereum address.
The choice of prefix must not conflict with the encoding alphabet letters.
Let 395f3643cea07ec4eec73b4d9a973dcce56b9bf1
be the account's hexadecimal representation.
Let the version be 00
.
Then, the checksum is double_sha256(version + '395f3643cea07ec4eec73b4d9a973dcce56b9bf1')[:8] = '435e3bc5'
.
So, we'll really be encoding 00395f3643cea07ec4eec73b4d9a973dcce56b9bf1435e3bc5
as our example.
0123456789abcdef
00395f3643cea07ec4eec73b4d9a973dcce56b9bf1435e3bc5
ABCDEFGHIJKLMNOPQRSTUVWXYZ234567
A4V6NSDZ2QH5RHOY45U3GUXHXGOK2436FBV4O6F
ybndrfg8ejkmcpqxot1uwisza345h769
yhi6p1d34o87t8qah7w5gwz8zgqk4h56fbihq6f
0123456789ABCDEFGHJKMNPQRSTVWXYZ
0WNYDJ3STG7XH7ERWXMV6MQ7Q6EATWVY51NWEY5
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
AOV82Q86gfsTuxztNmpc9zOVrm/FDXjvF
My vote is for one of the Base32 encodings plus a s
prefix. Also maybe a different prefix for testnet addresses?
I like the Base32 ones as well.
So...use z-base-32 encoding with a s
prefix for mainnet and a t
prefix for testnet? Does that work for everyone?
sounds good to me
Okay, here's what I'm going with:
s
denotes a single-key mainnet addressm
denotes a script-hash (multisig) mainnet addresst
denotes a single-key testnet addressn
denotes a script-hash (multisig) testnet addressAn address of compressed public key P
is:
addr(P) = version + RIPEMD160(SHA256(P)) + checksum(version, RIPEMD160(SHA256(P))
where checksum(version, pubkeyhash) = SHA256(SHA256(version + pubkeyhash))[:4]
.
Private key: 35ad2ef1f303dcbe74c2714ac133031e34db7c7529d072b741537030584cb6c401
Public key: 035a5235220903d5f89c2d19069c08c31622253422baba80dcb26f43619ca5e248
RIPEMD160(SHA256(public key)): a46ff88886c2ef9762d970b4d2c63678835bd39d
Mainnet pay-to-pubkey-hash (starts with s
):
checksum('16', 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: 71b4ba47
sn1g96reo5bq9f5n5famjwsgg3hegs6uuia5jq18
Mainnet pay-to-script-hash (starts with m
)
checksum('0b', 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: 61ab97bb
mn1g96reo5bq9f5n5famjwsgg3hegs6uuio4zf75
Testnet pay-to-pubkey-hash (starts with t
)
checksum('11' + 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: bf29c230
tn1g96reo5bq9f5n5famjwsgg3hegs6uus91uoto
Testnet pay-to-script-hash (starts with n
)
checksum('02' + 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: 2f458b49
nn1g96reo5bq9f5n5famjwsgg3hegs6uuwzwmn4j
Please :+1: this if you agree.
I'm fine with this latest iteration.
Looking over the whole thread, I did see the value in the S–
options. I kind of see this as a branding opportunity while people transact using our token. And a safeguard against confusion as people make transfers between wallets and exchanges, which is a real problem in everyday use. Re selecting—on mac 3 clicks will select the entire string including any dashes.
Looking over the whole thread, I did see the value in the S– options. I kind of see this as a branding opportunity while people transact using our token.
+1 to this. I don't think they look unique enough to be instantly recognizable as blockstack addresses like 0x addresses are instantly recognizable as ethereum addresses.
We probably shouldn't have people copying and selecting addresses anyways. The selecting the whole string issue probably shouldnt' be weighted as much as branding.
@jcnelson are we limited to only ascii characters to put between S and the rest of the address?
Adding a thumbs down vote until we've re-visited the branding issue. I'm not strongly against, but it seems like we should take advantage of the opportunity if possible.
We probably shouldn't have people copying and selecting addresses anyways. The selecting the whole string issue probably shouldnt' be weighted as much as branding.
I strongly disagree. People will copy/paste addresses into web forms and the CLI all the time, no matter what we tell them. We should select an address format that is amenable to double-click-select (desktop) or tap-hold-select (mobile). The convenience of being able to do this significantly outweighs the extra branding boost we may or may not get by having a -
in the address format.
@jcnelson are we limited to only ascii characters to put between S and the rest of the address?
I'm using the z-base-32 alphabet to encode addresses. We can have non-z-base-32 characters as a prefix, but I must insist that whatever prefix we use, it preserves the ability to easily select and copy addresses.
People will copy/paste addresses into web forms and the CLI all the time, no matter what we tell them.
This is good point. Thinking more about it, I'm also sold on the value of this.
the extra branding boost we may or may not get by having a
I just think there's an opportunity to have a uniquely blockstack address and I was surprised by how they looked less unique than I expected.
The reason I asked about non-ascii characters was that I thinking about including a symbol or emoji character. That would add the trade off of making it hard to type. Thoughts on that?
--
What about capitalizing the first letter?
Private key: 35ad2ef1f303dcbe74c2714ac133031e34db7c7529d072b741537030584cb6c401
Public key: 035a5235220903d5f89c2d19069c08c31622253422baba80dcb26f43619ca5e248
RIPEMD160(SHA256(public key)): a46ff88886c2ef9762d970b4d2c63678835bd39d
Mainnet pay-to-pubkey-hash (starts with S
):
checksum('16', 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: 71b4ba47
Sn1g96reo5bq9f5n5famjwsgg3hegs6uuia5jq18
Mainnet pay-to-script-hash (starts with M
)
checksum('0b', 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: 61ab97bb
Mn1g96reo5bq9f5n5famjwsgg3hegs6uuio4zf75
Testnet pay-to-pubkey-hash (starts with T
)
checksum('11' + 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: bf29c230
Tn1g96reo5bq9f5n5famjwsgg3hegs6uus91uoto
Testnet pay-to-script-hash (starts with N
)
checksum('02' + 'a46ff88886c2ef9762d970b4d2c63678835bd39d')
: 2f458b49
Nn1g96reo5bq9f5n5famjwsgg3hegs6uuwzwmn4j
That's fine by me.
I have a z32check encoding library here, if you all want to take a look: https://github.com/jcnelson/z32check
Forum post: https://forum.blockstack.org/t/stacks-token-address/5612
Let's get this closed by 2 July.
@shea256 raised an interesting point that one advantage of the Cockford base32 alphabet is that it can be written in either upper or lower case without losing its meaning and without introducing homoglyphs. This is a UX win because it makes it easier to communicate addresses, especially when typing is difficult. z-base-32 does not have this property, since it includes both i
and 1
.
What do you all think about Cockford base32? @larrysalibra @kantai @yknl
I don't see any downsides compared to zbase32, sounds good to me 👍
Also works for me
New repo for address encoding: https://github.com/jcnelson/c32check
Works for me too!
Got it shipped. Thanks everyone!
Moved from: https://github.com/blockstack/blockstack-core/issues/822#issuecomment-391680586
I think from a product and user experience perspective it makes more sense to use different address formats for the different token types.
There are a number of reasons for this. One reason is that without its "own" format like ethereum has it's own 0x format, it doesn't seem like a full blown separate coin.
Another reason is to avoid user confusion. A bitcoin address is a bitcoin address. If i want to ask someone for the account to which they'd like to send me Stacks, do I ask them for a bitcoin address? How can someone looking at the string determine if the wallet software that generated supports stacks or only bitcoin?