参考于https://mp.weixin.qq.com/s/YG1sbWKA8kS8VAT6pIIaBQ

目的

结合Character角色合约与Evidence存证合约打造结婚证书,示范角色合约和存证合约如何使用。

智能合约的开发步骤

  1. 角色分析
  2. 基于角色的功能设计
  3. 编码实现各个功能

合约结构说明

在这里插入图片描述

Character: 见证人合约(工作人员、结婚夫妻)
Evidence: 存证多签合约
EvidenceFactory: 存证工厂合约
MarriageEvidence: 结婚合约
Roles: 角色合约

1. 角色控制合约

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;
    }
    
}
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];
    }
    
}

接口说明
提供了两个合约: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是查询的地址

MarriageEvidence合约

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. 部署 MarriageEvidence 合约

民政局管理员wzl调用部署合约

在这里插入图片描述

  1. 调用添加角色接口

民政局管理员wzl调用方法:

添加丈夫地址:0xb2bb841d09c9e0ff82eee353715197e046c9684c 添加丈夫信息:
{
“name”:“Alice”,
“url”:“https://blog.csdn.net/weixin_43402353”,
“id”:321183200007270010,
“sex”:“male”,
“address”:{
“street”:“科技 园路.”,
“city”:“江苏苏州”,
“country”:“中国”
}
}
添加妻子地址:0x336c9a9d34c3dca40f8a0ac9573b45fa576b07a3 添加妻子信息:
{
“name”:“Bob”,
“url”:“https://blog.csdn.net/weixin_43402353”,
“id”:321183200007270010,
“sex”:“male”,
“address”:{
“street”:“科技 园路.”,
“city”:“江苏苏州”,
“country”:“中国”
}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 调用查看信息接口
    在这里插入图片描述
    在这里插入图片描述
  2. 部署存证合约

调用 deployEvi 方法。
在这里插入图片描述

  1. 创建结婚证书

本质上是支持多签的一条存证。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 调用sign接口,夫妻分别签名
    在这里插入图片描述
  2. 调用getEvi查看证书
    在这里插入图片描述
Logo

为所有Web3兴趣爱好者提供学习成长、分享交流、生态实践、资源工具等服务,作为Anome Land原住民可不断优先享受各种福利,共同打造全球最大的Web3 UGC游戏平台。

更多推荐