rasyidred/driver_dapp_contract
GitHub: rasyidred/driver_dapp_contract
基于 Solidity 的智能合约层,为智能交通系统提供不可篡改的驾驶员分心事件记录与司机自主控制的分页查询访问机制。
Stars: 0 | Forks: 0
# DRIVERDAPP — 智能合约层
用于 DRIVERDAPP 的 Solidity 智能合约。此存储库仅包含**智能合约层**。
## 架构
合约层由两个合约和两个接口组成:
### AccessRegistry.sol
中心化注册表和数据网关。
- 由所有者控制、带有角色分配(RBAC)的利益相关者注册。
- 由司机控制的授权:利益相关者默认被拒绝访问,必须由司机明确批准。
- 作为 API 网关:将分页记录查询代理到 `DistractionRecorder`,并为前端分页聚合记录计数元数据。
- 管理在记录时使用的司机与车牌号关联。
### DistractionRecorder.sol
不可变的分心事件存储。
- 将 `DistractionRecord` 结构体存储在按司机划分的映射中,并以连续的记录 ID 作为索引。
- 为每个分心类别公开一个专用的记录函数(由边缘设备调用)。
- 在记录时从 `AccessRegistry` 解析车牌号;如果司机没有注册的车辆,则回退到 `"XXX-0000"`。
- 记录检索是分页的,并且仅限于 `AccessRegistry` 调用者 — 所有授权检查都在代理调用之前的 `AccessRegistry` 中进行。
### 访问控制模型
每次查询都强制执行双层授权:
1. 调用者必须是已注册的利益相关者(或司机本人)。
2. 司机必须已明确授权该利益相关者。
| 参与者 | 职责 |
| -------------------- | ------------------------------------------------------------ |
| 所有者 (IT 部门) | 部署合约、注册利益相关者、分配车牌号 |
| 司机 | 授权和撤销利益相关者的访问权限;记录自己的分心事件 |
| 边缘设备 | 代表司机地址调用事件记录函数 |
| 利益相关者 | 通过 AccessRegistry 网关查询分心记录 |
## 分心事件类别
在 `IDistractionRecorder.EventClass` 中定义:
| 索引 | 类别 |
| ---- | ------------------ |
| 0 | SafeDriving |
| 1 | TextingRight |
| 2 | PhoneRight |
| 3 | TextingLeft |
| 4 | PhoneLeft |
| 5 | Radio |
| 6 | Drinking |
| 7 | ReachingBehind |
| 8 | HairMakeup |
| 9 | TalkingToPassenger |
## 利益相关者角色
在 `IAccessRegistry.StakeholderRole` 中定义:
| 角色 | 描述 |
| ------------------ | -------------------------------------- |
| `InsuranceCompany` | 评估与驾驶行为相关的索赔 |
| `LawEnforcement` | 审计已验证的违规行为 |
| `FleetManager` | 审查车队司机事件 |
| `RegulatoryBody` | 监控合规性和数据分析 |
## 快速开始
### 前置条件
- 已安装 [Foundry](https://getfoundry.sh):
curl -L https://foundry.paradigm.xyz | bash && foundryup
- 项目根目录下需包含以下内容的 `.env` 文件:
RPC_BESU=http://:8545
PRIVATE_KEY=
### 安装依赖
```
make install
```
安装 `forge-std` 和 OpenZeppelin 合约。
### 构建
```
make build
```
### 运行测试
```
make test
```
测试在私有 Besu 网络的分支上运行。必须设置 `RPC_BESU`。
### 格式化代码
```
make format
```
### 本地开发节点
```
make anvil
```
### 部署
```
# 本地 Anvil
make deploy-local
# 私有 Besu 网络 (chain ID 1984)
make deploy-besu
```
部署通过 `script/DeploymentScript.s.sol` 自动化执行:首先部署 `AccessRegistry`,然后使用注册表地址部署 `DistractionRecorder`。这两个合约都将部署者设置为所有者。
试运行变体(`deploy-besu-dry`)可模拟部署而无需进行广播。
### 安全分析
```
# Slither (先激活 .venv)
source .venv/bin/activate
make slither
# Aderyn
make aderyn
# Coverage 报告
make coverage
```
## 主要函数
### AccessRegistry — 管理员函数(仅限所有者)
| 函数 | 参数 | 描述 |
| --------------------------- | ----------------------------------------------- | --------------------------------------------------- |
| `registerStakeholder` | `address _stakeholder, StakeholderRole _role` | 注册具有角色的实体;角色不能为 `None` |
| `revokeStakeholder` | `address _stakeholder` | 移除注册并将角色设置为 `None` |
| `updateVehicleForDriver` | `address _driver, string _plateNo` | 为司机分配或更新车牌号 |
| `setDistractionRecorder` | `address _distractionRecorder` | 关联 `DistractionRecorder` 合约地址 |
### AccessRegistry — 司机函数
| 函数 | 参数 | 描述 |
| ------------------------------ | --------------------- | --------------------------------------------------- |
| `addAuthorizedStakeholder` | `address _stakeholder` | 授予已注册的利益相关者访问调用者记录的权限 |
| `removeAuthorizedStakeholder` | `address _stakeholder` | 撤销利益相关者访问调用者记录的权限 |
### AccessRegistry — 数据网关
| 函数 | 参数 | 返回值 | 描述 |
| ----------------------------- | ------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getDistractedDrivingEvents` | `address _driver, uint256 _offset, uint256 _limit` | `DistractionRecord[] records, uint256 totalCount` | 具有完整授权检查的分页记录检索。可由司机或司机已授权的任何利益相关者调用。返回记录页面以及用于分页元数据的总记录数。 |
### AccessRegistry — 查看函数
| 函数 | 返回值 | 描述 |
| ----------------------------------------------------- | ----------------- | --------------------------------------- |
| `isAuthorized(address _driver, address _stakeholder)` | `bool` | 司机是否已授权该利益相关者 |
| `isRegisteredStakeholder(address _stakeholder)` | `bool` | 该地址是否具有非 None 角色 |
| `getStakeholderRole(address _stakeholder)` | `StakeholderRole` | 分配给该利益相关者的角色 |
| `getDriverVehicleNumber(address _driver)` | `string` | 为该司机注册的车牌号 |
### DistractionRecorder — 事件记录
由边缘设备使用司机地址作为 `msg.sender` 进行调用。每个函数记录一个分心类别并返回分配的记录 ID(从 0 开始,按司机顺序排列)。
| 函数 | 分心类别 | 返回值 |
| -------------------------------------------- | ---------------- | ------------------ |
| `recordDistractionEventTextingRight()` | TextingRight | `uint256 recordId` |
| `recordDistractionEventPhoneRight()` | PhoneRight | `uint256 recordId` |
| `recordDistractionEventTextingLeft()` | TextingLeft | `uint256 recordId` |
| `recordDistractionEventPhoneLeft()` | PhoneLeft | `uint256 recordId` |
| `recordDistractionEventRadio()` | Radio | `uint256 recordId` |
| `recordDistractionEventDrinking()` | Drinking | `uint256 recordId` |
| `recordDistractionEventReachingBehind()` | ReachingBehind | `uint256 recordId` |
| `recordDistractionEventHairMakeup()` | HairMakeup | `uint256 recordId` |
| `recordDistractionEventTalkingToPassenger()` | TalkingToPassenger | `uint256 recordId` |
### DistractionRecorder — 查看函数
| 函数 | 返回值 | 描述 |
| ------------------------------------------------------------------- | -------------------- | --------------------------------------------------- |
| `getDriverRecordCount(address _driver)` | `uint256` | 为该司机存储的记录总数 |
| `getDriverVehicleNumber(address _driver)` | `string` | 从 `AccessRegistry` 解析的车牌 |
| `getDriverRecords(address _driver, uint256 _offset, uint256 _limit)` | `DistractionRecord[]` | 分页记录;仅限于 `AccessRegistry` 调用者 |
### DistractionRecorder — 管理员函数(仅限所有者)
| 函数 | 参数 | 描述 |
| ------------------- | --------------------- | ------------------------------------- |
| `setAccessRegistry` | `address _newRegistry` | 更新关联的 `AccessRegistry` 地址 |
## 事件
### AccessRegistry
| 事件 | 参数 | 触发时机 |
| ----------------------------- | --------------------------------------------------------------------------------- | ---------------------------------- |
| `StakeholderRegistered` | `address indexed stakeholder, StakeholderRole indexed role` | 注册利益相关者时 |
| `StakeholderRevoked` | `address indexed stakeholder` | 移除利益相关者注册时 |
| `StakeholderAuthorized` | `address indexed driver, address indexed stakeholder` | 司机授予访问权限时 |
| `StakeholderDeauthorized` | `address indexed driver, address indexed stakeholder` | 司机撤销访问权限时 |
| `VehicleNumberUpdated` | `address indexed driver, string indexed vehicleNumber, uint256 indexed timestamp` | 分配或更新车牌时 |
| `DistractionRecorderUpdated` | `address indexed newRecorder` | 更新 Recorder 合约地址时 |
### DistractionRecorder
| 事件 | 参数 | 触发时机 |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| `DistractedDrivingRecorded` | `address indexed driver, string indexed vehicleNumber, EventClass indexed eventClass, uint256 timestamp, uint256 recordId` | 记录分心事件时 |
| `AccessRegistryUpdated` | `address indexed newRegistry` | 更新 Registry 地址时 |
## 数据结构
```
struct DistractionRecord {
string vehicleNumber; // plate number at time of event
EventClass eventClass; // distraction class
uint256 timestamp; // block.timestamp at time of recording
}
```
## 错误参考
| 错误代码 | 合约 | 条件 |
| ------------------------------- | ------------------ | ------------------------------------------------- |
| `AR_ZeroAddress` | AccessRegistry | 提供的地址为 `address(0)` |
| `AR_InvalidRole` | AccessRegistry | 角色参数为 `None` |
| `AR_NotRegistered` | AccessRegistry | 目标利益相关者未注册 |
| `AR_UnknownEntity` | AccessRegistry | 司机试图授权未注册的地址 |
| `AR_RecorderNotSet` | AccessRegistry | 未配置 `DistractionRecorder` 地址 |
| `AR_UnauthorizedStakeholder` | AccessRegistry | 调用者不是已注册的利益相关者 |
| `AR_AccessDenied` | AccessRegistry | 司机未授权调用者 |
| `DR_ZeroAddress` | DistractionRecorder | 提供的地址为 `address(0)` |
| `DR_RegistryNotSet` | DistractionRecorder | 未配置 `AccessRegistry` 地址 |
| `DR_UnauthorizedAccessRegistry` | DistractionRecorder | 调用者不是配置的 `AccessRegistry` |
## 存储库结构
```
src/
AccessRegistry.sol # RBAC registry and data gateway
DistractionRecorder.sol # Immutable distraction event storage
interfaces/
IAccessRegistry.sol # AccessRegistry interface
IDistractionRecorder.sol # DistractionRecorder interface, EventClass enum, DistractionRecord struct
test/
AccessRegistry.t.sol # 69 tests across 11 categories
DistractionRecorder.t.sol # 57 tests across 11 categories
mocks/
MockDistractionRecorder.sol
script/
DeploymentScript.s.sol # Automated deployment (AccessRegistry → DistractionRecorder)
```
## 技术规格
| 属性 | 值 |
| --------------- | ------------------------------------------- |
| Solidity 版本 | 0.8.30 |
| 构建工具链 | Foundry (Forge, Cast, Anvil) |
| 依赖项 | OpenZeppelin Contracts (Ownable), forge-std |
| 区块链目标 | Hyperledger Besu (QBFT consensus) |
| 测试框架 | Forge Test(共计 126 个测试) |
## 许可证
MIT
标签:Solidity, Streamlit, 区块链, 智能交通, 智能合约, 物联网, 访问控制