今天来猜猜硬钱包实现的基础核心机制之一,一言以蔽之就是,秘钥生成拼串口通讯。而其实这篇主要描述串口通讯的实现。
工业级的硬钱包还有另一个核心那就是秘钥不离那个硬件。今天这个山寨版,做不到秘钥不离这种高难度。但是可以给想自己制作硬钱包的同学提供一些思路。我是拿了两个pi,一个假装pc,一个就是山寨硬钱包。
BOM: 两个pi,和一个usb转ttl串口小板。其实一个pi足够了,另一个可以换成普通电脑。
注意,在这个实验里串口小板的正极是怎么样都不要接的。只需要rx,tx,gnd这3根针。因为我们这里不存在供电问题,两个pi都独立的连接了电源。连正极轻则usb板子短暂失效,重则烧掉。
首先,可以去网上找一个自己喜欢的HDwallet项目,在此,我找了简单易操作的py-crypto-hd-wallet · PyPI,直接来一段tezos wallet生成代码,就能得到一个wallet文本。接下来就是可爱的串口通讯,废话少说直接code。
在所谓的pc Pi这里,wallet_uart_receive.py
import serial
import time
import sys
str_request = sys.argv[1:2][0]
bytes_request = bytes(str_request,encoding="ascii")
ser = serial.Serial('/dev/ttyUSB0',115200,timeout=0.2) # Le Potato上面是ttyAML6,树莓派就是这个路径作为串口interface
if ser.isOpen == False:
ser.open() # 打开串口
ser.write(bytes_request) #把mnemonic,address,private_key,path等这一类的参数送出去,每次只能送一个。
try:
while True:
size = ser.inWaiting() # 获得缓冲区字符
if size != 0:
response = ser.read_until("\n") # 读取内容并显示
print(response)
ser.flushInput() # 清空接收缓存区
time.sleep(0.1) # 软件延时
ser.close()
break
except KeyboardInterrupt:
ser.close()
在山寨硬件钱包Pi这一端,wallet_uart_send.py
import serial
import time
import json
with open('xtz_wallet.key') as json_file:
dict_data = json.load(json_file)
dict_addresses = dict_data['change_key']
tezos_mnemonic = bytes(dict_data['mnemonic'],encoding="ascii")
tezos_pub = bytes(dict_addresses['address'],encoding="ascii")
ser = serial.Serial('/dev/ttyAML6', 115200,timeout=0.2) # Le Potato上面就是这个路径作为串口interface
if ser.isOpen == False:
ser.open() # 打开串口
# ser.write(b"Raspberry pi is ready")
# ser.write(zcash_p2pkh_addr)
try:
while True:
size = ser.inWaiting() # 获得缓冲区字符
if size != 0:
response = ser.read_until("\n") # 读取内容并显示
print(response)
str_request = response.decode("utf-8")
if str_request == "address":
ser.write(tezos_pub)
elif str_request == "mnemonic":
ser.write(tezos_mnemonic)
else:
ser.write(b"what is that for? ")
ser.flushInput() # 清空接收缓存区
str_request = "" # 清空变量
time.sleep(0.1) # 软件延时
except KeyboardInterrupt:
ser.close()
实物连接图,
命令行中两个机器的通讯图,