MarriageEvidence结婚证书合约案例分析

  • 一、合约场景分析
  • 二丶基础合约介绍
    • 1. 角色合约
      • (1)功能说明
      • (2)接口说明
      • (3)使用说明
    • 2. 存证合约
      • (1)功能说明
      • (2)接口说明
      • (3)使用说明
  • 三丶业务合约介绍
    • 1. 结婚证书合约
      • (1)功能说明
      • (2)接口说明
      • (3)使用说明

一、合约场景分析

谨以白头之约书向鸿笺,好将红叶之盟载明鸳谱。三千年来,结婚证书的形式一直在变化,但我们相信,它承载的美好爱情和对幸福婚姻生活的向往从未变过。使用区块链技术,让结婚证书上链,定格在区块链的历史长河中——永存。

源码贡献者:

github:Blockchain_Key

源码分析者:

github:Blockchain_Key

源码链接:

https://github.com/WeBankBlockchain/SmartDev-Contract/tree/master/contracts/business_template/marriage_evidence

二丶基础合约介绍

1. 角色合约

Characters.sol

pragma solidity^0.4.25;import "./Roles.sol";contract Character{using Roles for Roles.Role;Roles.Role private _character;event characterAdded(address amount,string summary);event characterRemoved(address amount);event characterRevised(address amount,string summary);event characterSeeked(address amount);address owner;address[] characters;constructor()public{owner = msg.sender;}modifier onlyOwner(){require(owner == msg.sender,"Only owner can call");_;}function isCharacter(address amount)public view returns(bool){return _character.has(amount);}function _addCharacter(address amount,string _summary)internal{_character.add(amount,_summary);characters.push(amount);emit characterAdded(amount,_summary);}function _removeCharacter(address amount)internal{_character.remove(amount);emit characterRemoved(amount);}function _reviseCharacter(address amount,string _summary)internal{_character.revise(amount,_summary);emit characterRevised(amount,_summary);}function _seekCharacter(address amount)internal view returns(string){return _character.seek(amount);emit characterSeeked(amount);}function _removeCharacterByAddress(address amount)internal{for (uint i = 0; i < characters.length; i++) {if (amount == characters[i])for (uint j = i; j < characters.length-1; j++) characters[j] = characters[j+1];characters.length--;}}   function addCharacter(address amount,string _summary)public onlyOwner{require(!isCharacter(amount),"The character already exist");_addCharacter(amount,_summary);}function removeCharacter(address amount)public onlyOwner{require(isCharacter(amount),"The character does not exist");_removeCharacter(amount);_removeCharacterByAddress(amount);}function reviseCharacter(address amount,string _summary)public onlyOwner{require(isCharacter(amount),"The character does not exist");_reviseCharacter(amount,_summary);}function seekCharacter(address amount)public view returns(string) {require(isCharacter(amount),"The character does not exist");return _seekCharacter(amount);}function getAllCharater()public view returns(address[]){return characters;}}

Roles.sol

pragma solidity^0.4.25;library Roles{struct Role{mapping(address=>bool) bearer;mapping(address=>string) summary;}//判断角色function has(Role storage role,address amount)internal view returns(bool){require(amount!=address(0),"Address is zero address");return role.bearer[amount];}//添加角色function add(Role storage role,address amount,string _summary)internal{require(!has(role,amount),"Address already exists");role.bearer[amount] = true;role.summary[amount] = _summary;}//删除角色function remove(Role storage role,address amount)internal{require(has(role,amount),"Address does not exist");role.bearer[amount] = false;}//修改角色function revise(Role storage role,address amount,string _summary)internal {require(has(role,amount),"Address does not exist");role.summary[amount] = _summary;}//查询角色function seek(Role storage role,address amount)internal view returns(string){require(has(role,amount),"Address does not exist");return role.summary[amount];}}

(1)功能说明

本合约支持角色操作。包含角色的增删改查:

(2)接口说明

提供了两个合约:Roles合约,Character合约。其中Character合约是对外服务合约,Roles合约是库合约,用于数据和逻辑抽象化。

Character合约:对外服务的唯一接口。包含:

  • addCharacter(address amount,string summary): 管理员进行添加角色操作。amount是添加角色的地址, _summary添加角色的基本信息
  • removeCharacter(address amount): 管理员进行删除角色操作。amount是删除角色的地址
  • reviseCharacter(address amount,string _summary):管理员进行修改角色信息操作。amount是修改角色的地址, _summary修改角色的基本信息
  • seekCharacter(address amount): 任何人都可以进行查询角色信息操作。amount是查询角色的地址
  • getAllCharater():任何人都可以进行查看当前存在的所有角色操作。
  • isCharacter(address amount): 任何人都可以进行查看当前地址是否已经被添加为角色。amount是查询的地址

(3)使用说明

角色的增删改查,整个过程如下:

合约初始化:

- 以管理员地址部署Character合约

合约调用:

- 管理员调用Character.addCharacter提交添加角色请求,参数传入添加角色的地址,角色的基本信息
- 任何人调用Character.getAllCharater提交查看角色请求
- 任何人调用Character.isCharacter提交查询当前地址是否已经被添加成功
- 管理员调用Character.reviseCharacter提交修改角色信息请求,参数传入修改角色的地址,修改角色的基本信息
- 任何人调用Character.seekCharacter提交查询角色信息请求,参数传入查询角色的地址
- 管理员调用Character.removeCharacter提交删除角色的请求,参数传入删除角色的地址
- 任何人调用Character.isCharacter提交查询角色是否还存在请求,参数传入查询角色的地址
- 任何人调用Character.getAllCharater提交查看角色请求

2. 存证合约

Evidence.sol

pragma solidity ^0.4.25;contract EvidenceSignersDataABI
{//验证是否是合法地址function verify(address addr)public constant returns(bool){}//根据索引值返回签名者地址function getSigner(uint index)public constant returns(address){} //返回签名人数function getSignersSize() public constant returns(uint){}
}contract Evidence{string evidence; //存证信息address[] signers;//储存合法签名者地址address public factoryAddr;//工厂合约地址//返回事件信息,查看log->判断正确或错误的信息event addSignaturesEvent(string evi);event newSignaturesEvent(string evi, address addr);event errorNewSignaturesEvent(string evi, address addr);event errorAddSignaturesEvent(string evi, address addr);event addRepeatSignaturesEvent(string evi);event errorRepeatSignaturesEvent(string evi, address addr);//查看此地址是否为合法签名者地址function CallVerify(address addr) public constant returns(bool) {return EvidenceSignersDataABI(factoryAddr).verify(addr);}//初始化,创建存证合约constructor(string evi, address addr)  {factoryAddr = addr;//tx.origin =>启动交易的原始地址(其实就是部署者的地址)//如果是外部调用,在此可以理解为函数调用者地址if(CallVerify(tx.origin)){evidence = evi;signers.push(tx.origin);newSignaturesEvent(evi,addr);}else{errorNewSignaturesEvent(evi,addr);}}//返回签名信息,合约签名者地址,当前签名者地址function getEvidence() public constant returns(string,address[],address[]){uint length = EvidenceSignersDataABI(factoryAddr).getSignersSize();address[] memory signerList = new address[](length);for(uint i= 0 ;i<length ;i++){signerList[i] = (EvidenceSignersDataABI(factoryAddr).getSigner(i));}return(evidence,signerList,signers);}//添加签名者地址(此地址必须为合约签名者地址)function addSignatures() public returns(bool) {for(uint i= 0 ;i<signers.length ;i++){//此时的tx.orgin为当前调用此方法的调用者地址if(tx.origin == signers[i]){addRepeatSignaturesEvent(evidence);return true;}}if(CallVerify(tx.origin)){signers.push(tx.origin);addSignaturesEvent(evidence);return true;}else{errorAddSignaturesEvent(evidence,tx.origin);return false;}}//返回所有的合约签名者地址function getSigners()public constant returns(address[]){uint length = EvidenceSignersDataABI(factoryAddr).getSignersSize();address[] memory signerList = new address[](length);for(uint i= 0 ;i<length ;i++){signerList[i] = (EvidenceSignersDataABI(factoryAddr).getSigner(i));}return signerList;}
}

EvidenceFactory.sol

pragma solidity ^0.4.25;
import "Evidence.sol";contract EvidenceFactory{address[] signers;  //存储签名者地址event newEvidenceEvent(address addr); //新签证事件,返回地址//传入签名内容 string类型,创建合约Evidence并初始化function newEvidence(string evi)public returns(address){//this:代表当前工厂合约的地址Evidence evidence = new Evidence(evi, this);newEvidenceEvent(evidence);return evidence;}//获得签证信息function getEvidence(address addr) public constant returns(string,address[],address[]){return Evidence(addr).getEvidence();}function addSignatures(address addr) public returns(bool) {return Evidence(addr).addSignatures();}//初始化合约,导入签名者们的地址(数组传参)为合法签名者地址//只有合法签名者才有资格进行签证constructor(address[] evidenceSigners){for(uint i=0; i<evidenceSigners.length; ++i) {signers.push(evidenceSigners[i]);}}// 验证身份是否为合法签名者地址function verify(address addr)public constant returns(bool){for(uint i=0; i<signers.length; ++i) {if (addr == signers[i]){return true;}}return false;}//根据索引值返回合约签名者地址function getSigner(uint index)public constant returns(address){uint listSize = signers.length;//判断索引值是否越界if(index < listSize){return signers[index];}else{return 0;}}//获取当前合约签名者人数function getSignersSize() public constant returns(uint){return signers.length;}//返回所有合约签名者的地址function getSigners() public constant returns(address[]){return signers;}}

(1)功能说明

实现普通存证信息的创建,存储,获取

(2)接口说明

  • newEvidence(string evi)public returns(address):创建新签证事件,返回地址
  • getEvidence(address addr) public constant returns(string,address[],address[]):获取存证信息
  • addSignatures(address addr) public returns(bool):添加合法签名者
  • getSigner(uint index)public constant returns(address):返回签名者地址
  • getSignersSize() public constant returns(uint):获取总签名人数
  • getSigners() public constant returns(address[]):返回所有合约签名者的地址

(3)使用说明

  • 部署合约,初始化传入2个用户地址
    0x76c4e6e1d093092135d79677b724ae3470cdd6e3
    0xad6110c4f698ec996667fd5e2da0cdf5f1ee78e8

  • 查看合法签名者地址

  • 查看是否为合法地址

  • 创建签证合约(只有合法签名者才能成功创建)

  • 查看签证信息

  • 合法签名者签名签证合约

  • 再次查看签证信息

三丶业务合约介绍

1. 结婚证书合约

MarriageEvidence.sol

pragma solidity^0.4.25;
import "./EvidenceFactory.sol";
import "./Character.sol";contract MarriageEvidence is Character{address admin;address eviContractAddress;address eviAddress;constructor() public Character{admin = msg.sender;}modifier adminOnly{  require(msg.sender == admin ,"require admin");_;}modifier charactersMustBeAddedFirst{require(getAllCharater().length != 0,"It is null");_;}modifier signersOnly{require(EvidenceFactory(eviContractAddress).verify(msg.sender),"you not is signer");_;}function deployEvi() external adminOnly charactersMustBeAddedFirst{addCharacter(msg.sender,"民政局");EvidenceFactory evi = new EvidenceFactory(getAllCharater());eviContractAddress = address(evi);}function getSigners() public constant returns(address[]){return EvidenceFactory(eviContractAddress).getSigners();}function newEvi(string _evi)public adminOnly returns(address){eviAddress = EvidenceFactory(eviContractAddress).newEvidence(_evi);return eviAddress;}function sign() public signersOnly returns(bool) {return EvidenceFactory(eviContractAddress).addSignatures(eviAddress);}function getEvi() public constant returns(string,address[],address[]){return EvidenceFactory(eviContractAddress).getEvidence(eviAddress);}
}

(1)功能说明

实现结婚证书的创建,发放,夫妻签名,验证合法性等

(2)接口说明

  • addCharacter(address amount,string _summary):传入要添加的夫妻地址,以及基本信息
  • deployEvi() external adminOnly charactersMustBeAddedFirst:此方法必须要提前添加人物角色
  • getSigners() public constant returns(address[]):获取夫妻地址,返回地址数组
  • newEvi(string _evi)public adminOnly returns(address):传入结婚信息,创建结婚证书请求,返回证书地址
  • sign() public signersOnly returns(bool):夫妻分调用此接口对证书进行签名,使其具有合法性
  • getEvi()public constant returns(string,address[],address[]):获取结婚证书相关信息

(3)使用说明

  • 部署 MarriageEvidence 合约(民政局管理员key调用部署合约)

  • 调用添加角色接口

民政局管理员Key调用方法:
添加丈夫地址:0x004a8b8f111b02bc49a06bc4c8b19c29048b939c
添加丈夫信息:{ "name": "K", "url": "https://blog.csdn.net/weixin_43402353", "id": 321183200007270010, "sex": male, "address": { "street": "科技园路.", "city": "江苏苏州", "country": "中国" } }
添加妻子地址:0xd3c34312ae665884c453d46325341d649eb3c05b
添加妻子信息:{ "name": "T", "url": "https://blog.csdn.net/weixin_43402353", "id": 320382200012100001, "sex": female, "address": { "street": "国际中心", "city": "江苏扬州", "country": "中国" } }

  • 调用查看信息接口



  • 部署存证合约(调用 deployEvi 方法)

  • 创建结婚证书(本质上是支持多签的一条存证)

  • 调用sign接口(夫妻分别签名)


  • 调用getEvi查看证书

FISCO BCOS——SmartDev-Contract——MarriageEvidence结婚证书合约案例分析相关推荐

  1. FISCO BCOS——SmartDev-Contract——Traceability商品溯源合约案例分析

    Traceability商品溯源合约案例分析 一.合约场景分析 二.基础合约介绍 1. 产品基础合约 2.产品封装合约 3.功能说明 4.接口说明 5.使用说明 (1)Goods合约使用说明 (2)T ...

  2. FISCO BCOS上使用第三方CA证书底层节点部署实操

    CA证书怎么生成?节点相互验证证书时会交叉验证吗?对于社区常遇到的此类问题,分享一些个人使用第三方CA证书部署底层节点的经验,希望可以给大家一些借鉴与参考. 为什么要对第三方CA证书进行改造? 首先, ...

  3. FISCO BCOS Transaction execution error交易事务合约执行失败原因

    error|2022-06-21 19:31:31.351916|[g:1][EXECUTIVE][TxExeError]Transaction execution error,Transaction ...

  4. 区块链底层平台FISCO BCOS的证书机制

    FISCO BCOS是完全开源的联盟区块链底层技术平台,由金融区块链合作联盟(深圳)(简称金链盟)成立开源工作组通力打造.开源工作组成员包括博彦科技.华为.深证通.神州数码.四方精创.腾讯.微众银行. ...

  5. spring boot 实现fisco bcos最基础案例

    spring boot 实现fisco bcos最基础案例 一.基于国密搭建的4个节点联盟链 1.1 依赖文件 1.2 config.toml配置文件 1.3 用工具编译Helloworld.sol生 ...

  6. fisco bcos用caliper0.2.0进行压力测试的安装配置

    一.前期环境 1. 硬件 需要外网权限 2. 操作系统 版本要求:Ubuntu >= 16.04, CentOS >= 7, MacOS >= 10.14 3. 基础软件 pytho ...

  7. FISCO BCOS

    一.wsl(windows子系统)安装步骤 wsl(windows子系统)简要介绍和安装步骤_Once_day的博客-CSDN博客_wsl 1.自动安装命令 管理员身份打开CMD,输入wsl --in ...

  8. FISCO BCOS 2.0发布:新增群组架构克服吞吐瓶颈

    今日,FISCO BCOS开源社区正式对外发布FISCO BCOS的2.0版,该版本在可扩展性.性能.易用性.隐私隔离等方面均取得突破性进展,其新增的群组架构方案,可以让企业间像拉微信群一样快速组链, ...

  9. Fabric、FISCO BCOS、以太坊对比

    Fabric.FISCO BCOS.以太坊对比 一.以太坊 1.1 什么是工作量证明(POW) 1.2 这是如何运作的? 1.3 工作量证明的问题 1.4 股权证明 二.Fabric 2.1 产生背景 ...

最新文章

  1. sendStickyBroadcast和sendStickyOrderedBroadcast
  2. python中文件读写位置的作用-python配置文件的读写
  3. oracle冷备份/恢复
  4. 基于roslyn的动态编译库Natasha
  5. pc端jquery左右按钮控制带缩略图的图片切换代码_Web开发实用的图片预览插件,简单零依赖——PhotoSwipe...
  6. ajax三级联动+全国最新省市县数据
  7. 35载再忆华罗庚精神:我们应培养怎样的数学大师?​
  8. SaltStack之target
  9. OpenStack常见命令与问题集合
  10. javascript闭包(转)
  11. FreeMarker源码分析(八)
  12. #边学边记 必修4 高项:对事的管理 第1章 项目立项管理 之 立项管理内容
  13. 思维导图 基础篇(07)擎绘系统-阅读导图
  14. dfuse for EOSIO v0.1.0-beta4 版本更新说明
  15. Python学习笔记(二)(图灵学院)
  16. 查看支付宝所有交易记录方法
  17. 使用计算机的弊端,不可忽视的伤害 用电视接电脑弊端揭露
  18. 【小米集团】2019校招在线考试-算法试卷编程题
  19. 直接内存 直接内存的释放和回收
  20. 力扣 2200. 找出数组中的所有 K 近邻下标

热门文章

  1. fio工具测试硬盘性能
  2. 两个简单的xpath案例(爬取糗事百科 扇贝单词)
  3. 资深20年的大师告诉你UG与solidworks的区别!!!
  4. cad中直径符号不显示_CAD中各种比例你知道多少,不知道的赶快来看看
  5. linux解压`.xz`文件
  6. FS-D系列短信远程监测系统
  7. Vue项目与Nginx反向代理
  8. 天津2022 津沽大地 国稻种芯-农民丰收节:130余场活动展开
  9. 基于深度学习的视觉里程计算法
  10. oracle advisor权限,Oracle调整顾问(SQL Tuning Advisor 与 SQL Access Advisor )