Ethereum 教程,用于在其他地方(在非以太坊应用程序中)持久化数据,并使用DAPP与之交互并验证数据完整性

Ethereum 教程,用于在其他地方(在非以太坊应用程序中)持久化数据,并使用DAPP与之交互并验证数据完整性,ethereum,solidity,truffle,Ethereum,Solidity,Truffle,构建区块链应用程序时,为了在网站上显示状态(如支持postgres数据库),在非以太坊应用程序中保存数据的最佳做法是什么 一些具体问题: 为什么批量访问列表/数组/etc被描述为在稳定性方面令人痛苦 捕获区块链事件和更新链外数据库的最佳方式是什么 验证链外数据库完整性的最佳方法是什么(频率等) 您能否避免使用备份数据库并直接查询区块链 在“块菌宠物店”教程中,他们有一个返回整个链的视图 getAdapters()公共视图返回(地址[16]) 为什么批量访问列表/数组/etc被描述为在稳定性方面

构建区块链应用程序时,为了在网站上显示状态(如支持postgres数据库),在非以太坊应用程序中保存数据的最佳做法是什么

一些具体问题:

  • 为什么批量访问列表/数组/etc被描述为在稳定性方面令人痛苦
  • 捕获区块链事件和更新链外数据库的最佳方式是什么
  • 验证链外数据库完整性的最佳方法是什么(频率等)
  • 您能否避免使用备份数据库并直接查询区块链
  • 在“块菌宠物店”教程中,他们有一个返回整个链的视图
    getAdapters()公共视图返回(地址[16])

    为什么批量访问列表/数组/etc被描述为在稳定性方面令人痛苦

    这有几个原因:

  • 没有内置的机制以稳定的方式遍历集合。可以使用数组的长度为其创建标准for循环,但不能使用映射
  • 返回复杂对象很麻烦。如果列表中包含结构,则不能简单地将结构本身返回给客户端。您必须返回已分解的项目。将结构转换为分解的数组很难:

    struct MyStruct {
      uint256 id;
      bytes32 name;
    }
    
    MyStruct[] _structs;
    
    function getAllStructs() public constant returns (uint256[], bytes32[]) {
        uint256[] memory ids = new uint256[](_structs.length);
        bytes32[] memory names = new bytes32[](_structs.length);
    
        for (uint i = 0; i < _structs.length; i++) {
            ids[i] = _structs[i].id;
            names[i] = _structs[i].name;
        }
    
        return (ids, names);
    }
    
    struct MyStruct{
    uint256-id;
    bytes32名称;
    }
    MyStruct[]u结构;
    函数getAllStructs()公共常量返回(uint256[],bytes32[]{
    uint256[]内存ID=新的uint256[](结构长度);
    bytes32[]内存名=新的bytes32[](_structs.length);
    对于(uint i=0;i<\u structs.length;i++){
    id[i]=\u structs[i].id;
    名称[i]=\u结构[i]。名称;
    }
    返回(ID、姓名);
    }
    
  • 遍历数组仍然需要gas。即使您没有为气体付费(在
    常量
    函数中执行此操作时),当阵列变得非常大时,您仍然可能会出现气体耗尽异常。块菌宠物店的例子不受影响,因为它明确地将数组限制为16个元素

  • 捕获区块链事件和更新链外数据库的最佳方式是什么

    “最佳”方式取决于您的业务目标和对陈旧数据的容忍度。但是,最常见的方法可能是建立一个。当您接收到一个事件时,您将使用填充到事件中的自定义数据更新数据库。但是,还必须确保处理孤立块(元数据中有一个名为
    removed
    的字段,它告诉您事件是否因孤立块而不再有效)。当您收到孤立事件时,请将其从数据库中删除。在随后的12次块验证之后,您可以安全地假定事件不会孤立

    验证链外数据库完整性的最佳方法是什么(频率等)

    同样,这取决于业务需求的容忍度。如果您可以延迟使用DB中的信息,直到确定块验证,那么您只需保留块或时间戳信息,让您的应用程序知道DB中的数据反映了区块链上验证的内容。如果您担心负责监视事件的客户端进程失败,则需要让故障转移监视客户端,或允许重复持久性(随后进行重复数据消除),或在传入时跟踪已验证的块号(或3的某些组合)。我相信你也可以为此设计很多其他选择

    您能否避免使用备份数据库并直接查询区块链

    是的,如果您可以使用
    常量
    函数避免上述气体限制问题,并且您不必在应用程序的合同中对数据进行任何复杂的后处理,那么这是可能的。由于
    constant
    函数在本地EVM中运行,因此只需确保专用节点已启动并正在运行。为此,您很可能希望多台服务器作为完全同步的节点运行