这就是我认为前端的样子:
hashedData = web3.utils.sha3(JSON.stringify(certificate));
contracts.mycontract.deployed().then(function(result) {
return result.createCertificate(public_addresskey,hashedData,{ from: account }); //get logged in public key from metamask
}).then(function(result) {
//send post request to backend to create db entry
}).catch(function(err) {
console.error(err);
// show error to the user.
});
合同可能类似于下面的草图。
有一个结构可以包含除 id 之外的所有内容。来自 hash => Cert 的映射用于随机访问(使用哈希作为 id)和一个 certList 来枚举证书以防哈希未知。这不应该发生,因为它会为每个重要的状态更改发出事件。您可能希望使用 onlyOwner、白名单或基于角色的访问控制来保护 newCert() 函数。
要“确认”证书,接收者通过签署交易来确认。此字段中存在 true 表明提到的用户确实签名了,因为没有其他方法可以发生这种情况。
pragma solidity 0.5.1;
contract Certificates {
struct Cert {
address recipient;
bool confirmed;
}
mapping(bytes32 => Cert) public certs;
bytes32[] public certList;
event LogNewCert(address sender, bytes32 cert, address recipient);
event LogConfirmed(address sender, bytes32 cert);
function isCert(bytes32 cert) public view returns(bool isIndeed) {
if(cert == 0) return false;
return certs[cert].recipient != address(0);
}
function createCert(bytes32 cert, address recipient) public {
require(recipient != address(0));
require(!isCert(cert));
Cert storage c = certs[cert];
c.recipient = recipient;
certList.push(cert);
emit LogNewCert(msg.sender, cert, recipient);
}
function confirmCert(bytes32 cert) public {
require(certs[cert].recipient == msg.sender);
require(certs[cert].confirmed == false);
certs[cert].confirmed = true;
emit LogConfirmed(msg.sender, cert);
}
function isUserCert(bytes32 cert, address user) public view returns(bool) {
if(!isCert(cert)) return false;
if(certs[cert].recipient != user) return false;
return certs[cert].confirmed;
}
}