设备生命周期
Raiznet 中的设备是指任何已用 Ed25519 密钥对和隐私策略配置过的 ESP32。其身份是其公钥 —— 不是 MAC,也不是名称。
状态
[已制造] → [已配置] → [active] → [inactive] → [lost]
↑ ↓
└────────────┘| 状态 | 含义 |
|---|---|
active | 设备正常上报遥测 |
inactive | 设备在配置的时段内未上报 |
lost | 所有者将设备标记为不可恢复(硬件被毁或被盗) |
配置(按实现)
参考固件通过 强制门户 配置自身:
- 首次启动(或重置后),ESP32 创建一个临时 Wi-Fi 接入点。
- 所有者连接到它;强制门户打开一个 Identity Setup 流程:
- 设备从硬件 TRNG 生成自己的 Ed25519 密钥对并存入 NVS —— 私钥从不离开设备。
- 门户为 所有者身份 以所有者的语言(PT、EN、ES)生成一个新的 BIP-39 助记词(12 词),或导入已有的。所有者记下该短语。
- 所有者配置
publish_to、服务器地址和 Wi-Fi 凭据。 - ESP32 将所有内容写入 NVS 并以生产模式重启。
- 惰性注册(lazy): 设备在设置期间向已配置的服务器调用
POST /v1/devices,发送其 pubkey、MAC、所有者 pubkey 和初始隐私策略。409(已注册)计为成功。
通过应用配置 计划中
应用主导的流程在此之上增加:按字段的隐私策略、网络选择、在地图上选取 H3 位置,以及将活跃 Safra 的 Crop 推送到设备。
DeviceClaim 设计
在设备被配置时发布到所有者的公共事件日志中:
device_pubkey: bytes(32)
device_mac: bytes(6)
claimed_at: uint64
signature: bytes(64) // 由所有者的用户密钥签名任何对等节点都能验证所有权链:设备遥测由设备密钥签名;该密钥的所有权在由用户密钥签名的 DeviceClaim 中声明。
所有权转移(出售) 设计
- 卖方在应用中打开“转移设备”,输入买方的用户 pubkey。
- 卖方对一个
DeviceTransfer事件签名。 - 买方在其应用中收到请求并签名确认接受。
- 最终事件(两个签名)发布到买方的公共事件日志中。
- 网络识别新的
owner_pubkey,并只接受来自新所有者的配置更改。
device_pubkey: bytes(32)
from_user_pubkey: bytes(32)
to_user_pubkey: bytes(32)
transferred_at: uint64
signature_from: bytes(64) // 卖方
signature_to: bytes(64) // 买方历史读数仍由设备密钥签名。卖方的旧 DeviceClaim 作为他曾是所有者那段时间的有效记录留在日志中。
硬件丢失(烧毁的设备)
没有吊销流程。若设备被毁:
- 所有者在应用中将其标记为
lost(仅本地状态)。 - 购买新的 ESP32,作为全新设备配置(新 pubkey、新 MAC)。
- 若希望图表中的视觉连续性,应用可将旧设备与新设备显示为一条合并序列,在过渡点带视觉标记。
- 旧设备的历史数据留在所有者的服务器上,可单独查询。
设备的私钥已随硬件丢失 —— 这是可取的。克隆设备需要复制私钥,而在没有对闪存的物理访问时这是不可能的。
对称密钥轮换
每个设备有一个用于 ENCRYPTED 字段的对称密钥。密钥版本在 Device.encryption_key_version 和每个 TelemetryBlock 中跟踪。
轮换流程:
- 所有者在应用中发起轮换。
- 应用生成一个新对称密钥,并递增版本。
- 在下次连接时将新密钥发送到 ESP32。
- ESP32 对其后所有读数使用新密钥。
- 旧密钥保留在所有者应用的密钥环中,用于解密历史数据。
之前收到加密 blob 的对等节点无法用新密钥解密它们 —— 反之亦然。轮换在密钥泄露时限制暴露,代价是失去对任何持有旧密钥副本的第三方(如农艺师)的解密访问。
Crop 更新
ESP32 将活跃的 Crop 本地存储在闪存中。应用在设备连接到服务器时发送更新。若离线,设备继续使用已存版本直到重连。
Crop 更新流程:
- 网络或所有者在 CropCatalog 中发布更新的 Crop。
- 服务器从目录下载更新。
- 在下次设备连接时,服务器将更新的 Crop 推送到 ESP32。
- ESP32 写入闪存,并从下一个读数周期开始使用新值。