# Cross Supply Chain **Repository Path**: luyu-community/cross-supply-chain ## Basic Information - **Project Name**: Cross Supply Chain - **Description**: 供应链跨链应用 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 4 - **Created**: 2021-07-23 - **Last Updated**: 2024-09-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 供应链跨链 ## 一、功能场景 在供应链场景下,实现跨区块链的物流流转 * 需求 * 基础功能:跨区块链的供应链物流流转 * 跨链可信:一个物品从一条链跨到另一条链,通过跨链机制保证两条链间相互调用的操作正确可信 * 事务性:物品的状态流转在两条链上需存在事务性,即货物在一条链上的导出和另一条链上的导入操作是原子操作 * 限制 * 区块链相互间仅能进行有限的操作,敏感信息不互通 ## 二、系统架构 ![](docs/imgs/framework.svg) * **数据层** * 区块链 * 关口合约([PortContract](contracts/PortContract.sol)):货物跨链逻辑 * 供应链合约([SupplyContract](contracts/SupplyContract.sol)):管理供应链数据,对其它链不可见 * **互连层** * Router + 插件 * Account-Manager * **应用层** * 关口服务([Port Service](port-service/README.md)):跨链物品发送与接收的记录上链 ## 三、方案描述 **场景** * 货物从A链转移至B链 **机制** 采用HTLC的事务机制实现货物跨链的事务性,即下述操作必同时发生或失败 * 货物在A链删除 * 货物在B链创建 **模块** * 供应链合约A:货物的**起始**位置 * 关口合约A、B:管理货物跨链时的HTLC状态 * 关口服务A、B:相互配合对合约进行调用,主导HTLC的流程,推动货物跨链转移 * 供应链合约B:货物的**目的**位置 **流程** 为方面说明,此处仅给出关键流程和简要接口参数 * 供应链合约A:(发起)发起货物转移请求 * 关口服务A、B:(锁定)在各自链上发起跨链提案,哈希时间锁锁定,即:承认该跨链转移操作可在本连上发生 * 关口服务A、B:(解锁)相互配合,去对方链上解锁,即:让对方链上的转移操作生效 * 供应链合约B:(接收)接收货物 ``` sequence participant 供应链合约A participant 关口合约A participant 关口服务A participant 关口服务B participant 关口合约B participant 供应链合约B 供应链合约A->关口合约A: 货物转移请求 关口服务A-->关口服务B: 发送货物(线下) 关口服务A->关口合约A: lockA: transferPropose(cargoId, hashLock) 关口服务B->关口合约B: lockB: transferPropose(cargoId, hashLock) 关口服务A->关口合约B: unlockB: transferConform(cargoId, secret) 关口服务B->关口合约A: unlockA: transferConform(cargoId, secret) 关口合约B->供应链合约B: 生成货物记录 关口合约A->供应链合约A: 删除货物记录 ``` ![](docs/imgs/flowSimple.png) ## 四、模块设计 ### 4.1 供应链合约 SupplyContract 管理当前链的物流数据,仅对有权限的用户开放 ``` javascript interface ISupplyContract { //// 事件 event Transfer(address indexed from, address indexed to, uint256 cargoId); // new: 0 -> sender, remove: sender -> 0 event Approval(address indexed from, address indexed to, uint256 cargoId); event ExportRequest( uint256 indexed cargoId, string toChainPath, string receiver ); event ExportConfirm(uint256 indexed cargoId); event ExportCancel(uint256 indexed cargoId); //// 供应链常规接口 function ownerOf(uint256 cargoId) external view returns (address); // 货物拥有者 function cargoURI(uint256 cargoId) external view returns (string memory); // 货物描述 function transfer(address to, uint256 cargoId) external; // 货物转移owner,仅owner和approver可转移 function approve(address to, uint256 cargoId) external; // 货物授权给某人,即设置 approver function getApproved(uint256 cargoId) external view returns (address); // 查询approver function newCargo(uint256 cargoId, string calldata uri) external; // 新建货物 function removeCargo(uint256 cargoId) external; // 删除货物 //// 货物跨链接口 function exportRequest(uint256 cargoId, string calldata toChainPath, string calldata receiver) external; // 新建跨链请求 function exportConfirm(uint256 cargoId) external; // 确认跨链完成接口(仅PortContract可调用) function exportCancel(uint256 cargoId) external; // 取消跨链请求接口(仅PortContract可调用) function getExportRequestCargoIds() external view returns (uint256[] memory); // 获取所有跨链请求的货物id function getExportRequestByCargoId(uint256 cargoId) external view returns (string memory toChainPath, string memory receiver); // 查询货物信息 function getMyAddress() external view returns (address); // 工具接口,查询调用者的地址 } ``` ### 4.2 关口合约 **作用** * 管理货物跨链时的HTLC状态 **货物状态 ** * 正在:`transfering` * 完成:`transferred` * 取消:`cancelled` **事务机制** * 保证上述状态转换的原子性 * HTLC ``` javascript interface IPortContract { //// 事件 event TransferPropose(uint256 indexed cargoId, string fromChainPath, string toChainPath, string receiver, string hashLock, uint256 lockTime); event TransferConfirm(uint256 indexed cargoId, string secret); event TransferCancel(uint256 indexed cargoId); //// 货物跨链接口 function transferPropose( uint256 cargoId, string calldata cargoURI, string calldata fromChainPath, string calldata toChainPath, string calldata receiver, // 目的SupplyContract上的接收者地址 string calldata hashLock, uint256 lockTime ) external; // 发起货物跨链(锁定) function transferConfirm(uint256 cargoId, string calldata secret) external; // 确认货物跨链(解锁),发送方销毁cargoId,接收方生成cargoId并发送给receiver function transferCancel(uint256 cargoId) external; // 取消货物跨链(仅lockTime过后才可操作) //// 信息查询 function getTransferingCargoIds() external view returns (uint256[] memory); // 获取所有发送中(锁定中)的cargoId function getCargoInfo(uint256 cargoId) external view returns ( string memory cargoURI, string memory fromChainPath, string memory toChainPath, string memory receiver, // 目的SupplyContract上的接收者地址 string memory cargoStatus, string memory hashLock, string memory secret, uint256 lockTime ); // 查询货物信息 } ``` ### 4.3 关口服务 #### 4.3.1 准备阶段 主导货物的跨链转移,基于[luyu-java-sdk](https://gitee.com/luyu-community/luyu-java-sdk)开发,基于HTLC机制在两条链上实现转移的原子性。 **初始化阶段(双方)** 1. 部署供应链合约 SupplyContract 2. 部署关口合约 PortContract,参数:当前链的供应链合约地址、关口服务的二级账户地址、当前链的path(如:`payment.chain0`) 3. 关口服务去**对方链**注册自身对应的链path:`registerChainOwner(payment.chainXXX)` **A:发起货物导出请求** 1. 生成货物:`A.SupplyContract.newCargo()` 2. 跨链请求:`A.SupplyContract.exportRequest()` #### 4.3.2 操作阶段 **A:发起跨链提案(锁定)** 1.1 遍历导出请求:`A.SupplyContract.getExportRequestCargoIds()`、`A.SupplyContract.getExportRequestByCargoId()` 1.2 发起跨链提案:`A.PortContract.transferPropose()`(链下生成secret和hashLock并妥善保存) ``` sequence participant supply A participant port A participant service A participant service B participant port B participant supply B note over port A, port B: A lock阶段 supply A->service A:1.1 遍历导出请求 service A-> port A:1.2 发起跨链提案 ``` ![](docs/imgs/flow1.png) **B:响应跨链提案(锁定)** 2.1 查询对方跨链提案:`A.PortContract.getTransferingCargoIds()`、`A.PortContract.getCargoInfo()` 2.2 发起跨链提案:`B.PortContract.transferPropose()`(hashLock用A上查询来的) ``` sequence participant supply A participant port A participant service A participant service B participant port B participant supply B note over port A, port B: B lock阶段 port A->service B:2.1 查询对方跨链提案 service B->port B:2.2 发起跨链提案 ``` ![](docs/imgs/flow2.png) **A:执行对方的提案操作(解锁)** 3.1 查询对方链是否已提案:`B.PortContract.getCargoInfo()`(判断cargoStatus是否为transfering,hashLock是否一致) 3.2 执行对方链的提案操作:`B.transferConfirm()`(用事先保存的secret解锁) 3.3 生成货物:解锁后合约自动生成货物并转移至`B.SupplyContract`的receiver(合约自动完成,无需关口服务发交易) ``` sequence participant supply A participant port A participant service A participant service B participant port B participant supply B note over port A, port B: A unlock阶段 service A->port B:3.1 查询对方链是否已提案 service A->port B:3.2 执行对方链的提案操作 port B -> supply B:3.3 生成货物 ``` ![](docs/imgs/flow3.png) **B:执行对方的提案操作(解锁)** 4.1 遍历是否已解锁:`B.PortContract.getCargoInfo()`(得到secret) 4.2 用secret执行对方链的提案操作:`A.transferConfirm()` 4.3 删除货物:解锁后合约自动从`A.SupplyContract`上删除货物(合约自动完成,无需关口服务发交易) ``` sequence participant supply A participant port A participant service A participant service B participant port B participant supply B note over port A, port B: B unlock阶段 port B->service B:4.1 遍历是否已解锁 service B->port A:4.2 执行对方链的提案操作 port A->supply A:4.3 删除货物 ``` ![](docs/imgs/flow4.png) **完整流程如下** ``` sequence participant supply A participant port A participant service A participant service B participant port B participant supply B note over port A, port B: A lock阶段 supply A->service A:1.1 遍历导出请求 service A-> port A:1.2 发起跨链提案 note over port A, port B: B lock阶段 port A->service B:2.1 查询对方跨链提案 service B->port B:2.2 发起跨链提案 note over port A, port B: A unlock阶段 service A->port B:3.1 查询对方链是否已提案 service A->port B:3.2 执行对方链的提案操作 port B -> supply B:3.3 生成货物 note over port A, port B: B unlock阶段 port B->service B:4.1 遍历是否已解锁 service B->port A:4.2 执行对方链的提案操作 port A->supply A:4.3 删除货物 ``` ![](docs/imgs/flowAll.png) ### 4.4 演示模块 数据与操作的可视化(此模块仅关注具体业务功能,可无需感知关口服务的存在) * Server * 提供Web服务 * 此Server基于luyu-java-sdk开发,部署一个Router共其连接,该Router与各链的Router相连 * Web * 新建货物 * 发起货物跨链 * 查询货物所属