区块链试点——PresFlow存证合约简介

PresFlow存证合约简介

合约主要有三个功能:

1、set_wlist 配置上链权限,只有通过此接口加入到白名单的区块链帐户才可以调用数据上链的合约接口;

2、queryusernum 查询上链权限与用户编号,如果返回了一个Uint数据则说明拥用上链权限,如果返回“address is outside the wlist”则无上链权限;

3、set_hash 存证上链接口,需要将调用合约的区块链帐户对应的用户编号与存证数据一起以参数的形式输入,存证数据以Bytes32类型的数组传入;

4、get_witness 查询存证接口,参数为一个Bytes32类型的存证数据,即十六进制的SHA256,返回为空则表示此存证数据不存在,正常会返回一个Bytes32类型的数组,数组的第一个元素为第一次执行上链存证的区块链帐户,第二个元素为第二次执行上链的帐户,以此类推;

应用场景举例:

此合约可应用于处方流转与中药代煎场景:首先由监管部门或主导医院部署合约,然后为相关医院、药店、代煎工厂等机构配置上链权限,医院在开出处方后将处方进行HASH操作得到处方的SHA256,然后调用sethash接口将此SHA256上链,用户将电子版的处方拿到药店A去取药,药店A首先对处方进行HASH得到SHA256,然后调用getwitness查询此处方的上链帐户地址,并核对此帐户地址是否为处方开出医院的地址,如核对通过则药店A再用自己的区块链帐户对此SHA256调用sethash接口进行上链,表示药店A已对此处方进行了一次核销,用户取完药后可以再将处方与药材拿到代煎工厂进行代煎,代煎工厂B则可以通过getwitness查询并确认用户的处方是经过某医院开出,然后到药店A进行了取药。

部署合约

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh deploy PresFlow.sol

transaction hash: 0xa42034bc6951d7907e9e956c5a5d51154705b8cc927b9b2c45fadec835160e17
contract address: 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf
currentAccount: 0xe19163149a0c8941e853b4347773e5950c75d487

设置可以通过此合约调用上链接口的区块链帐户

调用方式: ./console.sh call 合约名 合约地址 函数名 参数

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf set_wlist'["0xe19163149a0c8941e853b4347773e5950c75d487"]'

transaction hash:
0x150d14a6772ee2d14308e300ed96a6e3c1a4f9c1f161b880954149c304d47469

transaction status: 0
description: transaction executed successfully

Receipt message: Success
Return message: Success
Return value size:0
Return types: ()
Return values:()

查询自己是否拥有上链权限与用户编号

如具备上链权限则会返回对应的用户编号:

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf query_user_num "0xe19163149a0c8941e853b4347773e5950c75d487"

---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success

Return value size:1
Return types: (UINT)
Return values:(0)

如不具备上链权限则会返回错误消息:address is outside the wlist

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf query_user_num "0xe19163149a0c8941e853b4347773e5950c75d488"

call for PresFlow failed, contractAddress: 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf
{
    "code":16,
    "msg":"address is outside the wlist"
}
description: address is outside the wlist, please refer to https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/api.html#id73


将需要存证的数据提取SHA256后进行上链

调用方式:

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf set_hash 0 '["0xabe0c2f527520cca0ca30c36130d1d86fde0552fbc6aa9ae76832a4a70071fe7"]'

transaction hash: 0xb06c9e9a9ec0925aa2664206d7dc98dddf675de38a8d2017901bef8076df74b0

transaction status: 0
description: transaction executed successfully

Receipt message: Success
Return message: Success
Return value size:0
Return types: ()
Return values:()

查询存证信息

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf get_witness "0xabe0c2f527520cca0ca30c36130d1d86fde0552fbc6aa9ae76832a4a70071fe7"

---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success

Return value size:1
Return types: (ADDRESS )
Return values:(0xe19163149a0c8941e853b4347773e5950c75d487 )

返回值是一个Address类型的数组,数组中会按顺序记录标记此HASH的帐户地址,同一个帐户执行两次上链操作(set_hash)则会得到如下结果:

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf get_witness "0xabe0c2f527520cca0ca30c36130d1d86fde0552fbc6aa9ae76832a4a70071fe7"

Return code: 0
description: transaction executed successfully
Return message: Success

Return value size:1
Return types: (ADDRESS, ADDRESS )
Return values:(0xe19163149a0c8941e853b4347773e5950c75d487, 0xe19163149a0c8941e853b4347773e5950c75d487 )

如果查询的HASH不存在,则会返回空的结果,将以上查询的HASH最后一位改为8进行查询测试:

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf get_witness "0xabe0c2f527520cca0ca30c36130d1d86fde0552fbc6aa9ae76832a4a70071fe8"

---------------------------------------------------------------------------------------------
Return code: 0
description: transaction executed successfully
Return message: Success

Return value size:1
Return types: ( )
Return values:( )

如通过不具备上链权限的帐户地址调用合约的上链接口则会返回错误消息:Caller is not wlist

root@eth-dev3:~/fisco_clent/console_wjw# ./console.sh call PresFlow 0xe87f67399b66331716ff8f92ee1eae4c9f30eddf set_hash 0 '["0xabe0c2f527520cca0ca30c36130d1d86fde0552fbc6aa9ae76832a4a70071fe7"]'

transaction hash: 0xd9111574d933209d4e182902da097b29e651ea31f49e371c206a5e467a427101

transaction status: 16

Receipt message: Caller is not wlist
Return message: Caller is not wlist

PresFlow.sol 合约内容

PresFlow.sol 文件需要保存到 console/contracts/solidity 下

// SPDX-License-Identifier: BSD Zero Clause License
pragma solidity ^0.8.0;

//------------------------------------------------------------
//处方流转场景
contract PresFlow{

    constructor(){
        owner = msg.sender;
    }

    //bool [] public count;
    address public owner;
    address [] public wlist;
    mapping (bytes32 => address []) public witness;

    modifier isAdmin() {
        require(msg.sender == owner, "Caller is not ADMIN_ADDR");
        _;
    }

    function set_wlist(address [] calldata _addr) external isAdmin
    {

       for(uint i=0; i<_addr.length; i++){
            wlist.push(_addr[i]);
       }
    }

    function set_hash(uint32  _num, bytes32[] calldata _hash) external
    {
    require(msg.sender == wlist[_num], "Caller is not wlist");
       for(uint32 i=0; i<_hash.length; i++){
            witness[_hash[i]].push(msg.sender);
       }
    }

    function get_witness(bytes32 hash) external view returns (address [] memory _witness)
    {
       return witness[hash];
    }

    function query_user_num(address uaddr) external view returns (uint32 user_num)
    {
     for(uint32 i=0; i < wlist.length; i++){
         if(uaddr == wlist[i]){
            user_num = i;
            return user_num;
         }
     }
      revert("address is outside the wlist");

    }  

}
标签