TimeChain 浏览器
通过标识符或确认链接打开任意 Montana 时间币转账并亲自核验。记录从节点读取;其哈希、后量子签名以及其密钥的余额——由该密钥的整条链折叠得出——都在此处、在您的浏览器中核验。
节点报告的网络检查点
最近的转账
每个节点上最新的记录。每一行在列出时即在此处核验:其哈希、签名及其在密钥链上的位置。
如何独立验证
一笔转账是一条记录,由发送方的种子签名,写入其密钥选定节点上的该密钥链中;日志只追加:记录永不被替换或删除。整数为小端序。
下面是记录的布局,以及其签名、标识符和发送方地址,采用 Python 写法(切片 [a:b] 取第 a 到第 b − 1 个字节)。
记录 — 5443 字节
记录携带其类型以及该类型使用的字段;某类型不使用的字段为零。SEND:pair 是配对标签,to = SHA-256(mt-coin-to ‖ 接收方的 from ‖ blind),其中 blind = 在配对密钥下对 mt-coin-blind ‖ nonce 计算的 HMAC-SHA-256,t0 是金额中经声明而非铸造的部分。RECV:to 携带 blind,ref 指向其接收的 SEND,t0 为相同的声明部分。REFUND:ref 指向发送方自己的 SEND。MINT:t0 和 t1 界定铸造的秒数。GENESIS:密钥的钱包在其链开启时声明的余额。
| 偏移 | 字节 | 字段 | 内容 |
|---|---|---|---|
| 0 | 4 | magic | ASCII MTTX |
| 4 | 1 | version | 0x03 |
| 5 | 1 | kind | 1 SEND, 2 RECV, 3 MINT, 4 REFUND, 5 GENESIS |
| 6 | 8 | amount | u64,时间币数量,至少为 1 |
| 14 | 8 | birth | u64,自 1970-01-01 UTC 起的毫秒数,发送方时钟 |
| 22 | 16 | nonce | 随机字节 |
| 38 | 32 | prev | 该密钥在其链上上一条记录的标识符;首条记录为 32 个零字节 |
| 70 | 32 | pair | 以配对密钥对 ASCII mt-coin-pair-v1 计算的 HMAC-SHA-256 |
| 102 | 32 | to | SEND:接收方承诺;RECV:打开该承诺的 blind |
| 134 | 32 | ref | RECV、REFUND:其结算的 SEND 的标识符 |
| 166 | 8 | t0 | MINT:铸造的第一秒(自 1970 年起的节点秒);SEND、RECV:金额中的声明部分 |
| 174 | 8 | t1 | MINT:最后铸造秒之后的一秒 |
| 182 | 1952 | pubkey | 发送方的 ML-DSA-65 公钥 |
| 2134 | 3309 | sig | ML-DSA-65 签名 |
msg = b"mt-coin-tx-v3" + record[0:2134]
pk = record[182:2134]
sig = record[2134:5443]
valid = ML-DSA-65.Verify(pk, msg, sig, ctx=b"") # FIPS 204
id = SHA-256(record).hex()
from = SHA-256(pk).hex()
prev = record[38:70].hex() # 64 zeros: the key's first record
chain = ["montana.quest", "montana.xxx"][SHA-256(pk)[0] % 2] # the node whose word counts密钥的链位于协议固定的链节点表(按名称排序,见上方公式)中的一个节点上:序号为 from[0] mod n 的节点,其中 from[0] 是发送方地址的第一个字节。该节点只接受位于密钥链头之上的记录,因此同一前驱上的两条记录只会有一条成立。沿着 prev 逐条回溯,即可将密钥的链走回其第一条记录;本页面将每条记录链接到其上一条记录。
密钥的余额是其链从第一条记录起的折叠:MINT 在自密钥第一条记录起的第 s 秒最多增加 2 × min(13, max(1, bit_length(s) − 1)) 枚时间币,区间至少 60 秒且从上一区间结束处开始;SEND 扣减——先扣铸造部分——且不得低于零;RECV 增加一笔其 to 能用 blind 打开到该密钥的 SEND;REFUND 在一天后无人接收时退回该密钥自己的 SEND。在接收方密钥尚未知晓时写入的 SEND 不指明接收方:它同样扣减,接收方的钱包则在其自身时间允许的范围内通过铸造将这些时间币计入自己的链。SEND 的链节点对每笔 SEND 只结算一次:被接收或被退回,绝不两者兼有。
签名采用 FIPS 204 的 ML-DSA-65,上下文为空,因此该标准的任何实现都能验证。本页面使用编译为 WebAssembly 的 Montana 核心(即 Montana 网页应用所运行的模块)验证签名,并用浏览器的 Web Crypto 计算 SHA-256。
配对标签只有对话双方知道:任何人都能看到该地址向某个配对付款,却无法知道配对是谁。
每个节点在接受记录之前都用 Montana 核心验证签名,每个读取者在相信之前都会再次验证——钱包在入账之前,本页面在显示有效之前。您可以亲自从任一节点读取记录;该命令打印记录的长度、标识符和发送方地址:
curl -s -H 'Content-Type: application/json' -d '{"id":"{id}"}' https://montana.xxx/pushwake/tx-get | python3 -c 'import sys,json,base64,hashlib; r=base64.b64decode(json.load(sys.stdin)["rec"]); k={1:(69,2021),2:(101,2053),3:(182,2134)}[r[4]]; print(len(r), hashlib.sha256(r).hexdigest(), hashlib.sha256(r[k[0]:k[1]]).hexdigest())'
curl -s -H 'Content-Type: application/json' -d '{"id":"{id}"}' https://montana.xxx/pushwake-msk/tx-get | python3 -c 'import sys,json,base64,hashlib; r=base64.b64decode(json.load(sys.stdin)["rec"]); k={1:(69,2021),2:(101,2053),3:(182,2134)}[r[4]]; print(len(r), hashlib.sha256(r).hexdigest(), hashlib.sha256(r[k[0]:k[1]]).hexdigest())'记录证明了什么。密钥余额的每一次变动都是其链上的一条记录:时间币只能通过 MINT(不超过该密钥已存在的时间所允许的数量)、RECV(打开发给该密钥的转账)或 REFUND(一天内无人接收的转账)进入,只能通过 SEND 离开。链节点拒绝超过链所持余额的 SEND,每个节点和每部保存副本的手机都折叠同一条链,本页面在您的浏览器中再次折叠它。
转账的确认链接为 https://montana.xxx/explorer/#tx= 加上其标识符。
格式:Montana 时间币记录(MTTX)。
