简体   繁体   English

Solidity:学生认证架构

[英]Solidity: Students certification architecture

I recently did a course on uDemy and get the first concepts.我最近在 uDemy 上做了一门课程并获得了第一个概念。 I'm starting to build a real-life app for a training center.我开始为培训中心构建一个真实的应用程序。 I want to register in the blockchain that Jhon Doe, ID (document) xxxx, approved the course "Master of blockchain" at a specific date, and also register the "expiration date" for the certification/permission.我想在区块链中注册 Jhon Doe,ID(文件)xxxx,在特定日期批准了“区块链大师”课程,并注册了认证/许可的“到期日期”。

In PHP I would create an array like this:在 PHP 中,我会创建一个这样的数组:

$certifications[123456] = [
    [
    "name" => "Jhon",
    "lastName" => "Doe",
    "courseName" => "Blockchain master",
    "Expiration date" => "2022-01-01"
    ],
    [
    "name" => "Jhon",
    "lastName" => "Doe",
    "courseName" => "Just another course",
    "Expiration date" => "2021-01-01"
    ]
];

With the output:随着输出:

array (size=1)
  123456 => 
    array (size=2)
      0 => 
        array (size=4)
          'name' => string 'Jhon' (length=4)
          'lastName' => string 'Doe' (length=3)
          'courseName' => string 'Blockchain master' (length=17)
          'Expiration date' => string '2022-01-01' (length=10)
      1 => 
        array (size=4)
          'name' => string 'Jhon' (length=4)
          'lastName' => string 'Doe' (length=3)
          'courseName' => string 'Just another course' (length=19)
          'Expiration date' => string '2021-01-01' (length=10)

Furthermore, I want to create a function to find by document ID the certification he/she did.此外,我想创建一个函数来通过文档 ID 查找他/她所做的认证。

Needless to say that I want to keep it on memory on a persistent way, using gas if necesary.不用说,我想以持久的方式将它保存在内存中,必要时使用 gas。

I thought in create a mix between mapping and array for this, maybe struct... But I've the feeling that I'm on the wrong way.我想为此创建映射和数组之间的混合,也许是结构......但我感觉我走错了路。

So... Anybody can guide me or send me a similar example to check how to approach?所以......任何人都可以指导我或给我发送一个类似的例子来检查如何接近?

Thanks in advance!提前致谢!

Edition 1:第 1 版:

I write this code following some tips and got it working except 2 thing:我按照一些提示编写此代码并使其正常工作,除了两件事:

pragma solidity 0.6.6;
pragma experimental ABIEncoderV2;
// SPDX-License-Identifier: MIT

import 'https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol';

contract Certification {
    using SafeMath for uint256;
    
    address private owner;
    
    struct Certificate {
        string name;
        string lastname;
        string certificationName;
        string instructorName;
        uint256 dueDate;
        uint256 expirationDate;
    }
    
    
    Certificate[] public certifications;

    mapping(uint => uint) public dniToCertification;
    
    event certificateSubscribed(string name, string lastname, uint dni, string certification, string instructor, uint256 date, uint256 untilDate);
    
    constructor() public {
        owner = msg.sender;
    }
    
    modifier isOwner() {
        require(owner == msg.sender);
        _;
    }
    
    function subscribeCertificate(
        string memory name,
        string memory lastname,
        uint dni,
        string memory certificationName,
        string memory instructorName,
        uint256 dueDate,
        uint256 expirationDate) public isOwner {
            
        certifications.push(Certificate(
           name,
           lastname,
           certificationName,
           instructorName,
           dueDate,
           expirationDate
        ));
            
        Certificate storage certification; //certification will be an instance of Struct Certificate
        
        certification.name = name;
        certification.lastname = lastname;
        certification.certificationName = certificationName;
        certification.instructorName = instructorName;
        certification.dueDate = dueDate;
        certification.expirationDate = expirationDate;
        
        uint id = certifications.length - 1;
    
        dniToCertification[dni] = id;
        
        
        emit certificateSubscribed(name, lastname, dni, certificationName, instructorName, dueDate, expirationDate);
    }
    
    function checkCertificateByDni(uint id) public view returns (Certificate memory) {
        return (certifications[dniToCertification[id]]);
        
    }
    
}
  1. Mapping is not iterable, so I have to return the entire Struct objects using experimental ABIEncoderV2映射是不可迭代的,所以我必须使用experimental ABIEncoderV2返回整个 Struct 对象
  2. I got error at the second time I want to call subscribeCertificate with not detailed information...我第二次遇到错误,我想在没有详细信息的情况下调用subscribeCertificate ...

I suggest save the certificate array in Structs and have a mapping for address and list of documents ids users have.我建议将证书数组保存在 Structs 中,并为用户拥有的地址和文档列表建立映射。

//certificate object
struct Certificate {
    string name;
    string lastName;
    string courseName;
    uint256 expirationDate;
}

// you can save all certifications on this array.
Certificate[] public certifications;

//save every address certifications and address
mapping(address => uint256[]) public userCertifications;

Usage example:用法示例:

// get certificate  by id
certifications[id]

// get user certifications-> return array of user certifications
userCertifications[msg.sender] or userCertifications[address]

Edition 1 answer版本 1 个回答

I changed your code to this and I think it can work for you!我将您的代码更改为此,我认为它可以为您工作!

pragma solidity 0.6.6;
// SPDX-License-Identifier: MIT

import 'https://github.com/OpenZeppelin/openzeppelin- 
solidity/contracts/math/SafeMath.sol';

contract Certification {
using SafeMath for uint256;

address private owner;

struct Certificate {
    string name;
    string lastName;
    string certificationName;
    string instructorName;
    uint256 dueDate;
    uint256 expirationDate;
}


Certificate[] public certifications;

mapping(uint => uint) public dniToCertification;




event certificateSubscribed(string name, string lastname, uint dni, string certification, string instructor, uint256 date, uint256 untilDate);

constructor() public {
    owner = msg.sender;
}

modifier isOwner() {
    require(owner == msg.sender);
    _;
}

function subscribeCertificate(
    string memory name,
    string memory lastname,
    uint dni,
    string memory certificationName,
    string memory instructorName,
    uint256 dueDate,
    uint256 expirationDate) public isOwner {
        
        
        certifications.push(Certificate(
           name,
           lastname,
           certificationName,
           instructorName,
           dueDate,
           expirationDate));

        uint id = certifications.length - 1;
        
        dniToCertification[dni] = id;
        
        
        emit certificateSubscribed(name, lastname, dni, certificationName, instructorName, dueDate, expirationDate);
}

}

Copy and paste it remix and you see you have 2 methods one to get a certificate and another to get a certificate by dni.复制并粘贴remix ,您会看到有两种方法,一种是获取证书,另一种是通过 dni 获取证书。 Also, you can't get an array of structs in solidity and you must do it on the client-side and by using loop get the whole certificates.此外,您无法获得可靠的结构数组,您必须在客户端执行此操作,并使用循环获取整个证书。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM