Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

2.10. 藝術品區塊鏈溯源防偽平台

2.10.1. 都有哪些角色參與其中

參與藝術品上鏈,鑒定,交易包含了下面幾種角色。

平台至少有三種角色會

  • 用戶
  • 機構
  • 鑒定師
  • 藝術家

所以我們需要為不同的角色提供不同的App應用。

用戶端:功能包括防偽查詢,鏈上資產的瀏覽,權益轉讓,資產拍賣,資產抵押,社區互動,分享,數字資產行情,錢包等等

機構端:負責信息收集,信息整理,數據提交,數據審查,資產上鏈,資產劃撥等等

鑒定師:負責數字資產的鑒定,需要有相關資質。

2.10.2. 需要運用的防偽技術

防偽溯源涉及的技術棧

  • 紙紋防偽(PaperPrint),紙紋防偽即紙紋防偽技術。它是一種基于提取和識別每張紙與生俱來的、獨一無二且無法仿造、克隆的自然纖維紋理作為防偽特徵(即紙紋)來實現防偽的新型防偽技術。
  • 螢光防偽油墨,使用螢光油墨印刷技術,在特定波長的紫外線或者紅外線下才能看到。螢光二維碼,螢光印章,螢光指紋,螢光暗記,佈滿整個宣紙的螢光圖案。我們可以為每個藝術家定製帶有螢光圖案的專屬紙張。
  • DNA防偽, 將藝術家的血液滴在書畫上或者頭髮夾在宣紙中間。據說某中世紀著名畫家將自己的精液和油畫顏料混合 :)
  • 特徵識別防偽,類似我們手機的面部識別,記錄物品的特徵,例如使用電子顯微鏡平射紙文理,畫面局部等等。油畫還可以拍攝X光片。
  • 3D 建模掃瞄,例如3D掃描器,將物品的3D數據記錄下來。
  • 激光內雕,例如施華洛世奇將 logo 內雕在他的水晶製品中。
  • QRcode 二維碼,用於鏈上數據查詢
  • NFC(Near Field Communication) 有兩個作用,一可以存儲數據,二用來防偽,因為生產相同UID的NFC晶片難度極大,門檻很高。
  • RFID(Radio Frequency Identification) 是 NFC 的一種,區別是不能存儲數據,NFC 不能替代 RFID,RFID 可以實現資產盤點,以及安防。
  • GPS 定位與地圖,記錄用戶位置,資產位置,機構位置,鑒定師位置,還能實現次產跟蹤,例如兩次查詢資產的GPS坐標,不在安全範圍,將視為被盜,系統將通知機構或用戶。
  • 高清相機、高清視頻設備
  • 安防設備,CCTV監控,門禁等等

舉例,書畫怎樣做防偽

以國畫為例,我們首先找一個宣紙企業合作,在宣紙生產過程中,將NFC晶片夾在宣紙中間,然後我們使用螢光油墨在宣紙上印刷防偽圖案。也可以採用人民幣上的金屬絲方案,最後拍攝紙紋。視頻記錄下藝術家的整個作畫過程,然後再拍攝特徵數據。最後使用激光打孔技術,在宣紙上打出防偽圖案數據,針孔極小肉眼難以分辨,每個防偽數據都是唯一的。

NFC 標籤可以使用易碎紙粘貼在藝術品上,缺點是壽命較短。使用PVC材料又容易撕下。

油畫可以講NFC晶片放在紡織布中,使用堆彩技術的畫家可以講NFC晶片覆蓋(埋植)在顏料下面

2.10.3. 技術架構

2.10.3.1. 前端技術

由於 H5 技術無法滿足我們的需求,例如相機,麥克風,NFC,定位...等等。我們重點放在 App 開發,H5 緊緊用於官網,區塊鏈瀏覽器,資訊,等等。

由於使用了很多手機上技術,原生App更適合,而混合開發 React Native,Vue.js, Flutter 不在我們選擇之列。

微信小程序可以考慮,但是如果涉及 Token 可能隨時會被下架。

2.10.3.2. 微服務端

服務端設計為可以水平擴展,可以隨時根據用戶量,擴展伺服器規模。

Nginx 負載均衡,HTTP2 (安卓 Okhttp 已經很好的支持 http2)

框架採用 Spring cloud

資料庫開發使用 JPA

介面認證 Oauth2 + Jwt

2.10.3.3. 存儲層

MongoDB

Redis

2.10.3.4. 消息隊列層

Kafka

2.10.3.5. 搜索層

ELK(ElasticSearch, Logstash, Kibana)

搜索是非常重要的功能,因為區塊鏈只能通過 hash 值取出鏈上的數據,雖然 Hyperledger Fabrc 在數據使用 CouchDB 時提供了 World State 的一些高級搜索功能,但是仍然不能滿足我們的需求。

所以鏈上數據需要存儲一份在搜索引擎中,搜索引擎的分詞功能,可以提供快速精準的搜索服務。

搜索引擎的工作流程是:

			
User --> Phone App --> Nginx --> Spring cloud --> Elastsearch --> Hyperledger Fabric	
			
			

2.10.3.6. 區塊鏈

我們不做山寨鏈,我發現很多國內企業熱衷于做山寨鏈,什麼事山寨鏈呢,就是在現有的區塊鏈(Ethereum, Hyperledger Fabric 或 EOS) 的基礎上二次開發,首先開發山寨鏈需要大量的資金人力,私鏈是沒有任何意義的,沒有公信力。即使目前的現有區塊鏈無法滿足我們的需求,可以通過架構調節去適應他。

所以我們只用最成熟的產品:

Hyperledger Fabric 盟鏈:主要用於資產上鏈,鏈上資產查詢

Ethereum 公鏈:用於 Token ,由於 Hyperledger Fabric 無法實現 Token,所以我們仍然需要以太坊。(作者寫過一篇文章關於為什麼Hyperledger Fabric 不能實現 Token,請興趣自己在網上搜索)

EOS Token/資產上鏈:由於在我設計這個系統之時 EOS 還沒有 Release 所以當時沒有考慮 EOS。現在我們可以使用 EOS,甚至替換掉 Hyperledger Fabrc + Ethereum 方案。因為 EOS 即能實現資產上鏈,也能實現 Token。 這裡我們將資產也在 EOS 上鏈一份,同時也支持 EOS 發的 Token。

IPFS 星際檔案系統:用於存儲多媒體數據,例如圖片,視頻。(注意:IPFS 暫時不支持流媒體,我的解決方案是上鏈同事複製一份到 nginx 中,並開啟 mp4 流媒體功能)

註:雖然以太坊目前嘗嘗擁堵,但是很多應用場景仍是不可替代的。

2.10.3.7. 支持層

監控 Zabbix

2.10.4. RFID/NFC

2.10.4.1. RFID

RFID基本概念:

RFID(Radio Frequency Identification)的縮寫,即射頻識別,俗稱電子標籤。  RFID射頻識別是一種非接觸式的自動識別技術,它通過射頻信號自動識別目標對象並獲取相關數據,識別工作無須人工干預,可工作於各種惡劣環境。  RFID是一種簡單的無線系統,只有兩個基本器件,該系統用於控制、檢測和跟蹤物體。系統由一個詢問器(或閲讀器)和很多應答器(或標籤)組成。 

RFID包括:  低頻125KHz  主要是動物管理  中頻 一般指433MHz(這個頻段一般也是有源的 也有做高速收費)  高頻13.56MHz 公交卡 身份證都是這個頻段。  超高頻860-960MHz 主要用在物流和停車場管理。 微波2.45GHz  ETC用這個頻段的多

2.10.4.2. NFC

NFC基本概念: 

NFC(Near Field Communication)縮寫,即近距離無線通訊技術。由飛利浦公司和索尼公司共同開發的一項無線技術。NFC由非接觸式射頻識別及互聯互通技術整合演變而來,可以在移動設備、消費類電子產品、PC和智能控件工具間進行近距離無線通信。NFC提供了一種簡單、觸控式的解決方案,可以讓消費者簡單直觀地交換信息、訪問內容與服務。  NFC技術特點:  1、 在13.56MHz頻率運行距離在20公分內;  2、 傳輸速度可分106Kbits/sec,212 Kbits/sec,424 Kbits/sec;  3、 運作可分主動與被動模式。主動模式需使用電池,也需要獨立發射模組;被動模式不需使用電池,但無法獨立發射訊號;  4、 已成為ISO/IEC IS 18092國家標準、ETSI TS 102 190標準、EMCA-340標準。

目前主流手機都帶有 NFC 是近場通信功能,安卓手機對 NFC 方案全開放,蘋果手機暫時開放部分功能.

2.10.4.3. RFID/NFC 兩種技術的差異

RFID/NFC 比較

  • 距離,RFID遠,NFC進
  • RIFD由讀卡器和標籤組成,讀卡器只能讀取標籤上的數據。NFC既可以做讀卡器,也能提供標籤服務,還能實現P2P點對點傳輸數據。
  • 修改,RFID是隻讀的,NFC上的數據可以修改,例如公交卡

2.10.5. 資產投資與份額持有

傳統藝術品投資門檻非常高,一是用戶不知道從哪些渠道可以投資,二是藝術品價值過高,三是藝術品鑒定難。這導致了投資藝術品門檻過高。 Token 能實現份額化,實現人人參與,人人持有,P2P交易。

例如某機構上鏈一件藝術品,用戶可以投資該藝術品的一定份額,可以轉讓他持有的權益。且交易去中心化,不受任何機構,管理者的制約。

下面的合約可以展示如何分割藝術品份額,最終達到鏈上資產的份額分割和持有與交易。

		
pragma solidity ^0.4.25;

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, reverts on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}        

contract Ownable {
    
    address public owner;
    
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    constructor() public {
        owner = msg.sender;
    }
    
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    
    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0));
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }

}

contract NetkillerAssetsToken is Ownable {
    using SafeMath for uint256;
    
    string public name;
    string public symbol;
    uint public decimals;
    uint256 public totalSupply;
    
    mapping(address => mapping(string => uint256)) internal balances;
    mapping(string => address) internal tokens;
    
    event Transfer(address indexed _from, address indexed _to, string indexed _tokenId);
    event Burn(address indexed from, string _tokenId);
    
    constructor(
        string tokenName,
        string tokenSymbol,
        uint decimalUnits
    ) public {
        owner = msg.sender;
        name = tokenName;
        symbol = tokenSymbol; 
        decimals = decimalUnits;
        totalSupply = 0; 
    }
    
    function add(address _owner, string _tokenId) onlyOwner returns(bool status){
        balances[_owner][_tokenId] = 100 * 10 ** uint256(decimals);
        tokens[_tokenId] = _owner;
        totalSupply = totalSupply.add(1);
        return true;
    }
    
    function balanceOf(address _owner, string _tokenId) constant returns(uint balance){ 
        return balances[_owner][_tokenId];
    }

    function ownerOf(string _tokenId) constant returns (address owner) {
        return tokens[_tokenId];
    }
    
    function transfer(address _to, string _tokenId){
        
        address _from = msg.sender;
        uint256 amount = balances[_from][_tokenId];
        transfer(_to, amount, _tokenId);
    }
    function transfer(address _to, uint256 _value, string _tokenId){
        require(msg.sender == ownerOf(_tokenId));
        require(msg.sender != _to);
        require(_to != address(0));
        
        address _from = msg.sender;
        uint256 amount = balances[_from][_tokenId];
        require(amount >= _value);
        
        balances[_from][_tokenId] = balances[_from][_tokenId].sub(_value);
        balances[_to][_tokenId] = balances[_to][_tokenId].add(_value);
        tokens[_tokenId] = _to;

        emit Transfer(_from, _to, _tokenId);
    }
    
    function burn(address _owner, string _tokenId) onlyOwner public returns (bool success) {
        require(balances[_owner][_tokenId] > 0 && balances[_owner][_tokenId] == 100 * 10 ** uint256(decimals));

        balances[_owner][_tokenId] = 0;
        tokens[_tokenId] = address(0);

        totalSupply = totalSupply.sub(1);
        emit Burn(msg.sender, _tokenId);
        return true;
    }
    
}		
		
		

由於 ERC721 不太符合我的需求,所以我結合 ERC20 和 ERC721 寫出了我的合約。合約儘量保持了ERC20的使用習慣,函數定義儘量兼容 ERC20。

我們來看下面的構造方法,每個種類的物品一個合約,例如字畫,陶瓷,青銅器。

		
    constructor(
        string tokenName,
        string tokenSymbol,
        uint decimalUnits
    ) public {
        owner = msg.sender;
        name = tokenName;
        symbol = tokenSymbol; 
        decimals = decimalUnits;
        totalSupply = 0; 
    }
		
		

通過下面函數,添加資產到 Token,使鏈上資產與Token綁定。

		
    function add(address _owner, string _tokenId) onlyOwner returns(bool status){
        balances[_owner][_tokenId] = 100 * 10 ** uint256(decimals);
        tokens[_tokenId] = _owner;
        totalSupply = totalSupply.add(1);
        return true;
    }		
		
		

balances[_owner][_tokenId] = 100 * 10 ** uint256(decimals); 初始化份額是 100 表示 100%

totalSupply = totalSupply.add(1); 物品件數加一。可以用於統計鏈上資產的數量。

下面函數是查詢資產的持有人

		
function ownerOf(string _tokenId) constant returns (address owner) {
        return tokens[_tokenId];
    }		
		
		

下面函數是,權益轉讓和權益份額轉讓。

		
    function transfer(address _to, string _tokenId){
        
        address _from = msg.sender;
        uint256 amount = balances[_from][_tokenId];
        transfer(_to, amount, _tokenId);
    }
    function transfer(address _to, uint256 _value, string _tokenId){
        require(msg.sender == ownerOf(_tokenId));
        require(msg.sender != _to);
        require(_to != address(0));
        
        address _from = msg.sender;
        uint256 amount = balances[_from][_tokenId];
        require(amount >= _value);
        
        balances[_from][_tokenId] = balances[_from][_tokenId].sub(_value);
        balances[_to][_tokenId] = balances[_to][_tokenId].add(_value);
        tokens[_tokenId] = _to;

        emit Transfer(_from, _to, _tokenId);
    }		
		
		

接下來,我們就是可以開發 Dapp 錢包了,在錢包中實現資產的轉移交易。

這個合約可以移植到 EOS 上,Hyperledger Fabric 不可以,因為 Fabric 沒有鎖的機制,會導致計算出錯。

2.10.6. 資產上鏈的

我們希望資產上鏈適用於任何領域,後面也方便將業務拓展。所以我實現了一個萬能合約。以不變應萬變,Hyperledger Fabic 鏈碼如下。

		
package main

import (
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

type SmartContract struct {}

func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) pb.Response {
	return shim.Success(nil)
}

func (s *SmartContract) Query(stub shim.ChaincodeStubInterface) pb.Response {
	return shim.Success(nil)
}

func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) pb.Response {

	// Retrieve the requested Smart Contract function and arguments
	function, args := stub.GetFunctionAndParameters()
	// Route to the appropriate handler function to interact with the ledger appropriately
	if function == "create" {
		return s.create(stub, args)
	} else if function == "find" {
		return s.find(stub, args)
	} else if function == "update" {
		return s.update(stub, args)
	} else if function == "delete" {
		return s.delete(stub, args)
	}

	return shim.Error("Invalid Smart Contract function name.")
}

func (s *SmartContract) create(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	_key  	:= args[0]
	_data	:= args[1]

	if(_data == ""){
		return shim.Error("Incorrect string of data")
	}

	existAsBytes,err := stub.GetState(_key)
	if string(existAsBytes) != "" {
		fmt.Println("Failed to create account, Duplicate key.")
		return shim.Error("Failed to create account, Duplicate key.")
	}

	err = stub.PutState(_key, []byte(_data))
	if err != nil {
		return shim.Error(err.Error())
	}
	fmt.Printf("create %s %s \n", _key, string(_data))

	return shim.Success(nil)
}

func (s *SmartContract) find(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	_key  	:= args[0]
	_data, err := stub.GetState(_key)
	if err != nil {
		return shim.Error(err.Error())
	}
	if string(_data) == "" {
		return shim.Error("The key isn't exist.")
	}else{
		fmt.Printf("query %s %s \n", _key, string(_data))
	}

	return shim.Success(_data)
}

func (s *SmartContract) update(stub shim.ChaincodeStubInterface, args []string) pb.Response {

	if len(args) != 2 {
		return shim.Error("Incorrect number of arguments. Expecting 2")
	}

	_key  	:= args[0]
	_data	:= args[1]

	if(_data == ""){
		return shim.Error("Incorrect string of data")
	}

	err := stub.PutState(_key, []byte(_data))
	if err != nil {
		return shim.Error(err.Error())
	}else{
		fmt.Printf("update %s %s \n", _key, string(_data))
	}
	
	return shim.Success(nil)
}

// Deletes an entity from state
func (t *SmartContract) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 1 {
		return shim.Error("Incorrect number of arguments. Expecting 1")
	}

	_key := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(_key)
	if err != nil {
		return shim.Error("Failed to delete state")
	}

	return shim.Success(nil)
}

func main() {

	err := shim.Start(new(SmartContract))
	if err != nil {
		fmt.Printf("Error creating new Smart Contract: %s", err)
	}
}
		
		
		

鏈碼有四個函數,分別是創建,查找,更新,刪除。

		
	if function == "create" {
		return s.create(stub, args)		// 創建
	} else if function == "find" {
		return s.find(stub, args)		// 查找
	} else if function == "update" {
		return s.update(stub, args)		// 更新
	} else if function == "delete" {
		return s.delete(stub, args)		// 刪除
	}		
		
		

上鏈使用 create 方法,函數有兩個參數,一個是 key, 另一個是數據。

key 使用 UUID 存儲再資料庫和鏈上,同時 UUID 對應通證的

data 是序列化 byte 數據。例如可以使用 json, hession, msgpack 等序列化後的數據。

		
err = stub.PutState(_key, []byte(_data))		
		
		

這個鏈碼考慮到前期產品上市,不確定性因素很多,需要更新和刪除等等。後期我們可以在數據中設置一個 status 變數,當 status = false 就不在允許數據的刪除和更新。

2.10.7. 原型設計

2.10.7.1. 註冊與登錄

註冊

  • 安裝APP後,點擊註冊連結,進入註冊界面。
  • 用戶類型選擇選擇 “機構”或者”鑒定師”。對於前台只有用戶一種角色。
  • 輸入手機號碼,然後獲取驗證碼
  • 輸入密碼
  • 點擊註冊按鈕,完成註冊

登錄,平台提供多重登錄方式

  • 密碼登錄
  • 驗證碼登錄
  • 微信登錄
  • 指紋登錄
  • 面部識別登錄
  • 助記詞登錄
  • 私鑰登錄
  • 閃付卡登錄(類似銀行卡的 QuickPass 閃付,可以在 Post 機上做 Token 付款,轉賬等操作)

2.10.7.2. 用戶角色

防偽查詢

查看鏈上資產

資產交易

評論

分享

用戶是權益持有人,當用戶(用戶端)委託機構負責自己的資產上鏈。權益持有人一次性獲得次產權益100%份額,機構可以查看的機構名下的權益持有人。

2.10.7.3. 鑒定師角色

鑒定師是管理機構認證並頒發資質證書人員,藝術品溯源區塊鏈領域,他主要的職責事藝術品鑒定。鑒定師可以掛靠到機構。

如何註冊成為鑒定師?

			
		首先進入APP -> 點擊『註冊 』->閲讀條款->點擊同意按鈕。
		輸入手機號碼,發送驗證碼,輸入密碼,重複輸入密碼,選擇『鑒定師』,提交。			
			
			

註冊成功會自動登錄,進入完善資料頁面,鑒定師需要實名認證,上傳身份證信息,鑒定師證書,等等資質檔案。鑒定師需要仔細填寫每一項,並保證資料的真實性。

提交資料後,等待管理機構審批,管理機構會仔細核對每項數據。如果被拒,需要鑒定師重新填寫,再提交。

審批通過前,只能看到鑒定師信息頁面。 審批通過後,可以看到,鑒定師信息,已簽名資產,未處理資產。

怎樣鑒定物品?

鑒定師登錄APP後,進入『我的』可以看淡未處理資產菜單,進入菜單可以看到任務列表。點開一件物品,將鑒定結果提交上去,完成鑒定。鑒定師可以在[已簽名資產]中查看自己鑒定過的物品。

2.10.7.4. 機構角色

機構主要負責資產上鏈,審查,資產託管

如何註冊成為機構

  • 首先進入APP -> 點擊『註冊 』->閲讀條款->點擊同意按鈕。
  • 輸入手機號碼,發送驗證碼,輸入密碼,重複輸入密碼,選擇『機構』,提交數據。
  • 註冊成功後自動登錄APP,進入完善機構信息頁面,填寫機構信息同時上傳資質檔案,選擇區塊鏈應用領域(目前只開通了藝術品領域)
  • 提交資料後,等待管理員審批,管理員會仔細核對每項數據。如果被拒,需要鑒定師重新填寫,再提交。

審批通過前:機構只能看到機構信息頁面

審批通過後:機構擁有機構權限,機構信息,錢包,地址管理,安全,區塊鏈屬性配置,資產管理,權益持有人,評論審核,申請溯源標籤

2.10.7.4.1. 地址管理

地址為收貨地址,管理員會郵寄AI智能標籤給機構。

進入“我的” -> “設置” -> “地址管理” -> 添加地址

2.10.7.4.2. 申請溯源標籤

首先機構需要完善收貨地址,至少添加一個收貨地址。

然後進入『申請溯源標籤』,進入“我的” -> “機構” -> “申請溯源標籤” 。輸入數量,選擇類型,選擇收貨地址,系統會自動計算費用,提交後從錢包中扣取。

標籤有以下幾種類型

  1. 易碎紙
  2. PVC
  3. 捆紮帶
  4. 玻璃管標籤
  5. 可以根據機構的需求定製AI防偽溯源標籤的大小,形狀等等。

注意:暫時只能線上申請,綫下付款。待錢包功能上線後同意採用 Token 結算。提交信息後,管理員收到信息會主動聯繫你,完成付款後將標籤郵寄給機構的收貨地址。

2.10.7.4.3. 數字資產上鏈

數字資產上鏈是將企業數字化資產上傳到區塊鏈上,相比資料庫區塊鏈是分散式共識,可以防止信息篡改。

準備工作

  • 檢查你的App是否是最新版本
  • 連結WiFI活4G(需要信號穩定)
  • 開啟手機或者設備的NFC功能,GPS定位功能,授權攝像頭,指紋認證
  • 準備好物品信息
  • 將溯源標籤粘貼到藝術品上
  • 信息錄入可以使用藍芽鍵盤連結手機或者管理員指定專用設備上,以便加快信息錄入
  • 有些輸入可以提供語音輸入,或者掃碼錄入。

資產錄入

  • 錄入物品信息,下一步
  • 上傳多媒體資料,例如圖片,視頻,聲音等等
  • 如果物品有歷史事件資料,可以追加這些信息到歷史記錄中。
  • 綁定AI只能溯源防偽標籤
  • 綁定二維碼,方便作品調出
  • 設置定位信息 (可選)
  • 指定一個或多個鑒定師鑒定物品。
  • 指定權益持有人(暫時不可用,權益持有人來自用戶端)
  • 鑒定師鑒定物品,輸入鑒定結果。
  • 機構提交信息。
  • 管理員審批
  • 資產上鏈。

經過上面幾個步驟完成數字資產上鏈。

注意:管理員沒有審批前可以修改資產信息,管理員審批後鏈上數據無法修改。

2.10.7.4.4. 機構成員管理

在整個區塊鏈溯源防偽的過程中,上鏈的工作量是最大的,所以非一人所為,必須團隊完成。 機構可以添加自己的員工,為員工分配令牌,通過令牌登錄後可以一同完成資產上鏈的數據錄入。

2.10.7.4.5. 資產審核

分支機構可以對員工添加的資產信息逐一核對,核對後點擊『提交』按鈕,信息將提交至管理員。待管理員在此審批通過,數據便會上鏈。

無論是機構拒絶還是管理員拒絶,信息都需要重新填寫。

信息的審核責任主要在機構,管理員審核通常是看物品是否符合國家法律,法規,政策等等方面。

2.10.7.4.6. 鑒定師隷屬於機構

當鑒定師為機構鑒定物品後即成為該機構的鑒定師,機構可以查看的機構名下的鑒定師,可以理解為鑒定師掛靠該機構,該機構負責管理鑒定師。

鑒定師負責物品鑒定,並給出鑒定結論。一個物品可以有多名鑒定師同時鑒定。

用戶也可以邀請鑒定師鑒定某肩藝術品。

2.10.7.4.7. 評論

用戶(用戶端)可以評論上鏈的數字資產,增加用戶與機構,用戶與用於的互動粘合。

防止用戶隨意提交無意義的信息,所以機構需要審核每一條評論信息。

2.10.7.4.8. 安全
2.10.7.4.8.1. 指紋認證

開啟指紋後,添加物品,審批,等等需要確認的地方都需要指紋驗證。

2.10.7.4.8.2. 藝術品跟蹤

當發現查詢作品的GPS坐標與作品所在位置的GPS坐標不在安全範圍時,發送報警信息您的藝術品可能被盜,請儘快核實,如需協助,我方可以向公安機關提供:

  1. 物品所在位置
  2. 以及查詢者的身份信息
2.10.7.4.8.3. 令牌管理

為員工指派令牌,機構註冊的賬號,只能登錄一部設備,如果需要多人錄入資產信息,就需要使用令牌登錄。

管理員會收取一部分費用(Token)

2.10.7.5. 錢包

用戶數字資產的交易