Solidity

在乙太坊區塊鏈上儲存雜湊的理想方式

  • March 11, 2019

我想在區塊鏈上儲存證書。我只需要儲存它的雜湊值以及它是否被雙方驗證。

我是否應該為雜湊創建一個由 bytes32 組成的結構,以及一個布爾值以查看其是否已確認。然後創建這個結構的映射。我需要某種 ID 來進行映射嗎?用結構映射id?

該證書將針對個人 X,並且他的公鑰將在前端已知。然後此人必須使用他的私鑰簽名,如果已簽名,則布爾值應設置為 true。

我將使用數據庫來儲存所有數據。在有人搜尋證書時。數據將從數據庫中提取。散列數據,然後確認散列在區塊鏈上。

附帶說明:如果我需要不同使用者的權限,如果權限在區塊鏈上,我在結構中添加一個變數來儲存所有有權查看此證書的公鑰。

這就是我認為前端的樣子:

    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.
        });

契約可能看起來像下面的草圖。

有一個struct包含id 之外的所有內容。來自 hash => Cert 的映射用於隨機訪問(使用散列作為 id)和certList用於列舉證書以防散列未知。這不應該發生,因為它會為每個重要的狀態更改發出事件。我省略了訪問控制以保持簡短。您可能希望使用、 a或基於角色的訪問控制來保護該newCert()功能。onlyOwner``whiteList

為了“確認”證書,接收者通過簽署交易來確認。此欄位中存在 atrue表明提到的使用者確實簽名了,因為沒有其他方法可以發生這種情況。

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

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/68231