FISCO BCOS——SmartDev-Contract——MarriageEvidence结婚证书合约案例分析
Posted Blockchain_KT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FISCO BCOS——SmartDev-Contract——MarriageEvidence结婚证书合约案例分析相关的知识,希望对你有一定的参考价值。
MarriageEvidence结婚证书合约案例分析
一、合约场景分析
谨以白头之约书向鸿笺,好将红叶之盟载明鸳谱。三千年来,结婚证书的形式一直在变化,但我们相信,它承载的美好爱情和对幸福婚姻生活的向往从未变过。使用区块链技术,让结婚证书上链,定格在区块链的历史长河中——永存。
源码贡献者:
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)
evi以上是关于FISCO BCOS——SmartDev-Contract——MarriageEvidence结婚证书合约案例分析的主要内容,如果未能解决你的问题,请参考以下文章