【问题标题】:How to store a hash of some data in a currently publicly available blockchain?如何在当前公开的区块链中存储一些数据的哈希?
【发布时间】:2019-10-26 12:49:01
【问题描述】:

我听说区块链不擅长存储大文件。但他们说,你可以创建一个文件的哈希并以某种方式将其存储在区块链中。我怎么做?我应该查看哪些 API 或服务?我可以在 bitcoin.org 上做,还是需要某种特殊的“参数化”区块链服务?

在我看到的博客中,我看到吹捧您可以将数据存储在 mysql 中但将哈希存储在区块链中的地方有多酷,它们并没有显示 你实际上是如何获得细节的散列到区块链中,甚至建议使用哪些服务来执行此操作。 API在哪里?我将散列传递到哪个字段?

【问题讨论】:

  • 我要问,为什么?你想完成什么?

标签: blockchain


【解决方案1】:

这就是我认为前端的样子:

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

【讨论】:

    【解决方案2】:

    简短的回答是:“使用带有事件的以太坊智能合约,不要在合约中存储哈希值。”

    在 Etherscan 上,您可能会找到一份在以太坊中存储哈希值的完整合约:HashValueManager。正如您将在此代码示例中看到的那样 - 事情有点复杂。你必须管理访问权限,这里的成本并不重要(此合约是为联合区块链设计的)

    实际上,将哈希数据存储在区块链中是非常昂贵的。当您使用以太坊合约存储哈希数据时,您需要为每笔交易支付大约 0.03 欧元(取决于 ETH 和 Gas 奖励)。

    最好不在合约中存储哈希值。一个更便宜的替代方案是在智能合约中发出索引事件并查询事件(这非常快)。有关事件的信息存储在挖掘块的布隆过滤器中,并且将永远可读。唯一的缺点是无法从合约中读取事件(但这不是您的业务逻辑)

    您可以在此处阅读有关事件以及如何在应用程序中获取它们的更多详细信息:"ETHEREUM EVENT EXPLORER FOR SMART CONTRACTS"(免责声明:本文是我的博客)。完整的源代码也可以在 GitHub 上获得。

    【讨论】:

      【解决方案3】:

      对于商店,现有几种方式。更有趣的问题:您打算如何检索和使用您的数据?我想,你打算通过某种方式去检索。否则,如果没有检索 - 没有意义存储。

      好的。有两种方法来存储你的哈希值。我将在emercoin 区块链中演示示例。

      1. 存储为 OP_RETURN UTXO。为此,请通过 JSON RPC API 或命令行界面使用命令“createrawtransaction”。只需指定“数据”来定义 UTXO,包含您的哈希。 在这种情况下,数据将存储在不可花费的交易输出之一中。此保存的数据没有被索引,您需要保存 TXID 以备将来检索。否则,您需要重新扫描整个区块链以检索您的数据。

      2. 您可以将数据存储在索引 NVS 子系统(名称-值存储)中。要上传,您需要运行命令“name_new”,其中 hash 可以是您的搜索关键字。将来,您可以使用“name_show”或“name_history”命令通过搜索键快速检索数据。此外,还可以将您的数据保存为 emerDNS 中的 DNS 记录,并通过协议 RFC1035 的 DNS UDP 请求进行检索。

      详情见文档:https://emercoin.com/en/documentation/emercoin-api

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 2018-10-31
        • 2022-08-03
        • 1970-01-01
        • 2021-06-29
        • 1970-01-01
        相关资源
        最近更新 更多