經過分析和研究,我們梳理了傳統制造業中的幾大需求:
需求1:生產計劃和物料匹配自動化
B公司根據A公司的訂單與現有成品庫產品庫存,分析出差額後製定生產計劃。根據產品的生產數量計算出所需物料。生產物料除去物料庫的庫存後直接向供應商反饋出所需物料的數量,並且預付款項。
需求2:物料供應商及時響應物料標識上鍊
供應商C、供應商D、供應商E收到物料需求訂單,準備發貨入庫。同時供應商C、供應商D、供應商E的物料匹配唯一標識,資訊上鍊。
需求3:財務可信清算
在訂單下發、物料採購、物流運送、訂單交貨等環節建立財務自動按約定清算的機制。
需求4:售後質量溯源
售後基於物料唯一標識的可信責任確權和質量溯源,做到及時響應。
底層選型的幾點考量
瞭解需求後,下一步就是技術實現,在底層選型上,團隊架構師康紅娟主要從以下幾點進行考量:
· 良好的實際可操作性。區塊鏈應用層與實際業務貼合緊密,尤其是在合約層,重新開發部署業務型合約必然會帶來反覆除錯。因此,底層的完備支援,對於專案成功非常重要。
· 完善的服務層功能元件。使用者層與鏈層的互動,必須經過中間服務層的“嫁接”,而這些“嫁接模組”具備通用性,除了基本的鏈層功能外,服務層通用元件的完備也至關重要。
· 友好的開源氛圍。對於技術極客而言,最大的快樂就是開源。
透過了解評估,團隊最終選擇了FISCO BCOS作為底層,主要是兩方面的原因:
· FISCO BCOS是安全可控的國產開源聯盟鏈,能很好滿足、貼合國內企業的使用需求;
· 社羣活躍度高,應用場景豐富,對於開發者的技術支援響應及時。
除此之外,FISCO BCOS還具備版本迭代及時、效能強勁、服務中介軟體豐富等優勢。
智慧合約解決方案
綜上所述,我們從實際業務需求出發,結合區塊鏈技術優勢,構建“基礎層、核心層、服務層、使用者層”等四個關鍵層級,覆蓋核心資料庫、業務型合約、資料解析、訊息解析、使用者管理、業務管理等功能,構建工業網際網路領域的訂單式生產協同垂直解決方案。
本文我們重點分享其中的智慧合約方案,方案如下圖。這個方案裡包括了產品合約、結算合約、生產合約、備貨合約和授權合約,下面將對這幾個合約逐一展開介紹。
· 產品合約
本合約用於完成產品生產過程中產品註冊及產品所有權變更、產品溯源。
步驟如下:
· 完成對相關合約的關係設定;
· 合約的admin向某些address授權成為product生產商;
· product生產商呼叫updateProductPrice對產品價格進行設定;
· customer需要向生產商下產品生產訂單前會先getProductPrice來比對價格的高低,然後透過payment合約向生產商下產品生產訂單;
· 生產商透過payment合約獲取到訂單後,進行產品生產;
· 在生產產品前,生產商會透過Material合約來檢查自己的產品原料儲備是否充足,如果充足就消耗原料進行產品的生產註冊registerProduct上鍊;
· 產品生產商進行交付,customer確認收到貨品,確認訂單,完成資金及產品所有權的變更。
// 廠商msg.sender更新自己productType產品的價格
function updateProductPrice(uint256 productType, uint256 newPrice) public
// 獲取廠商 _to的productType的價格
function getProductPrice(address _to, uint256 productType) public view returns(uint256 price)
// 設定供應商的原材料合約
function setMaterialContract(address _materialContract) public onlyOwner
// 設定支付合約
function setPaymentContract(address _paymentContract) public onlyOwner
// 產品生產商設定自己產品的批次號,ID,所用材料批次等資訊
function registerProduct(uint256 productType, uint256 id, uint256 batchNumber, uint256[] memory materialBatches) public
// 更換產品所有權,交付產品
function transferProducts(address from, address to, uint256 productType, uint256 count) public
// 獲取產品詳情
function details(uint256 id) public view returns(Product memory)
// 獲取msg.sender所擁有的產品陣列
function getMyProducts(uint256 productType) public view returns(uint256[] memory myProductIDs)
// 獲取某種產品的原材料用於哪些產品了
function trace(uint256 materialBatchNum) public view returns(uint256[] memory ids)
· 結算合約
負責使用者資產,具體步驟如下:
· 餘額與預付款佇列;
· 產品所有權變化(手動確認)過程中的自動結算;
· 資金如果不足,不能進行諸如備貨,入庫等的操作;
· 充值/直接消費/預付款, 餘額查詢等相關功能。
· 生產合約
擁有庫存生產個數和已擁有產品佇列, 和原材料批次佇列:
· 獲取待生產訂單,判斷原料庫存是否滿足需求,不滿足則透過結算合約向備貨合約預付款下生產訂單;
· 透過計算原材料佇列,外部唯一標識生成,將原材料的批次資訊寫入產品進行生產(外部)、入庫(呼叫產品合約的生成入口)。對庫存生產個數和已擁有產品佇列進行維護;
· 出庫(外部呼叫產品合約的產品所有權變更入口),對本合約的生產個數和已擁有產品佇列庫存合約的已擁有產品佇列進行維護,透過結算合約進行結算。
· 備貨合約
負責對上游廠商進行備貨:
· 透過呼叫生產備貨數對廠家B進行備貨,計算已有零件數,外部呼叫零件入庫(填入批次,數量等資訊);
· 出庫(外部呼叫),將零件資訊的批次資訊寫入到廠家B, 並維護自身資料佇列,完成後自動呼叫結算合約進行結算。
補充:因為零件不像產品一物一碼,多個零件只對應到某個批次就可以,不需要單獨的零件合約對零件進行維護。
· 授權合約
透過不同的許可權等級,對各個合約中的函式進行訪問限制,各種合約間角色的約定及呼叫許可權。比如普通使用者沒有許可權去向供貨商下訂單,而供貨商也不可能向普通使用者提供生產完成的商品。
// address是否有role許可權
function hasRole(bytes32 role, address account) public view returns (bool)
// 獲取role許可權的成員數
function getRoleMemberCount(bytes32 role) public view returns (uint256)
// 根據role和index獲取成員
function getRoleMember(bytes32 role, uint256 index) public view returns (address)
// 獲取role角色的管理者
function getRoleAdmin(bytes32 role) public view returns (bytes32)
// 向某個account授予role許可權
function grantRole(bytes32 role, address account) public virtual
// 移除account的role許可權
function revokeRole(bytes32 role, address account) public virtual
// account放棄持有的role許可權
function revokeRole(bytes32 role, address account) public virtual
智慧合約解決方案
整個智慧合約開發過程中,最主要其實是對整個生產流程的梳理。首先我們先進行了需求梳理,然後針對solidity語言開發出一個可用的版本,在此基礎上對相關呼叫建立一個簡單的restful伺服器,完成對各個介面的測試,有一套完整的可演示流程,最後進行相關開發完成對合約的復現。