This document introduces a common Account Module for decentralized user identity authentication.
The Meta was generated by your private key, it can be used to build a new ID for entity, or verify the ID/PK pair.
It consists of 4 fields:
Field | Description |
---|---|
type | Algorithm Version |
key | Public Key |
seed | Entity Name (Optional) |
fingerprint | Signature to generate address (Optional) |
- if
seed
exists,fingerprint = private_key.sign(seed)
; - if
seed
not exists,fingerprint = public_key.data
.
MKM
(Default)BTC
Extended BTCETH
Extended ETH- ...
/* Meta(JsON) for hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj */
{
"type" : 0x01,
"key" : {
"algorithm" : "RSA",
"data" : "-----BEGIN PUBLIC KEY-----\nMIGJAoGBALB+vbUK48UU9rjlgnohQowME+3JtTb2hLPqtatVOW364/EKFq0/PSdnZVE9V2Zq+pbX7dj3nCS4pWnYf40ELH8wuDm0Tc4jQ70v4LgAcdy3JGTnWUGiCsY+0Z8kNzRkm3FJid592FL7ryzfvIzB9bjg8U2JqlyCVAyUYEnKv4lDAgMBAAE=\n-----END PUBLIC KEY-----",
"mode" : "ECB",
"padding" : "PKCS1",
"digest" : "SHA256"
},
"seed" : "hulk",
"fingerprint" : "jIPGWpWSbR/DQH6ol3t9DSFkYroVHQDvtbJErmFztMUP2DgRrRSNWuoKY5Y26qL38wfXJQXjYiWqNWKQmQe/gK8M8NkU7lRwm+2nh9wSBYV6Q4WXsCboKbnM0+HVn9Vdfp21hMMGrxTX1pBPRbi0567ZjNQC8ffdW2WvQSoec2I="
}
The ID is used to identify an entity(user/group). It consists of 3 fields:
Field | Description |
---|---|
type | Entity type |
name | Same with meta.seed (Optional) |
address | Unique Identification |
terminal | Login point (Optional) |
The ID format is name@address[/terminal]
.
# ID examples
ID1 = "hulk@4YeVEN3aUnvC1DNUufCq1bs9zoBSJTzVEj"; // Immortal Hulk
ID2 = "moki@4WDfe3zZ4T7opFSi3iDAKiuTnUHjxmXekk"; // Monkey King
The Name field is a username, or just a random string for group:
- The length of name must more than 1 byte, less than 32 bytes;
- It should be composed by a-z, A-Z, 0-9, or charactors '_', '-', '.';
- It cannot contain key charactors('@', '/').
# Name examples
user_name = "Albert.Moky";
group_name = "Group-9527";
It's equivalent to meta.seed
The Address field was created with the Meta and a Network ID:
from typing import Optional
from mkm.types import ConstantString
from mkm.digest import sha256, ripemd160
from mkm.format import base58_encode, base58_decode
from mkm import Address
class BTCAddress(ConstantString, Address):
"""
Address like BitCoin
~~~~~~~~~~~~~~~~~~~~
data format: "network+digest+code"
network -- 1 byte
digest -- 20 bytes
check code -- 4 bytes
algorithm:
fingerprint = PK.data
digest = ripemd160(sha256(fingerprint));
code = sha256(sha256(network + digest)).prefix(4);
address = base58_encode(network + digest + code);
"""
def __init__(self, address: str, network: int):
super().__init__(string=address)
self.__network = network
@property # Override
def network(self) -> int:
return self.__network
@classmethod
def from_data(cls, fingerprint: bytes, network: int) -> Address:
"""
Generate address with fingerprint and network ID
:param fingerprint: meta.fingerprint or key.data
:param network: address type
:return: Address object
"""
head = chr(network).encode('latin1')
body = ripemd160(sha256(fingerprint))
tail = check_code(head + body)
address = base58_encode(head + body + tail)
return cls(address=address, network=network)
@classmethod
def from_str(cls, address: str) -> Optional[Address]:
"""
Parse a string for BTC address
:param address: address string
:return: Address object
"""
if len(address) < 26 or len(address) > 35:
return None
# decode
data = base58_decode(address)
if data is None or len(data) != 25:
return None
# check code
prefix = data[:21]
suffix = data[21:]
if check_code(prefix) == suffix:
network = ord(data[:1])
return cls(address=address, network=network)
def check_code(data: bytes) -> bytes:
# check code in BTC address
return sha256(sha256(data))[:4]
When you get a meta for the entity ID from the network, you must verify it with the consensus algorithm before accepting its public key.
(All data encode with BASE64 algorithm as default, excepts the address)