如何将JSON文件存储在IPFS上,并使用Oraclize访问智能合约中的数据呢?
  
  以太坊是一个成熟的区块链,使开发人员能够创建智能合约,在区块链上执行的程序可以由交易触发。人们经常将区块链称为数据库,但使用区块链作为数据存储非常昂贵。
  
  以目前的价格(530美元,4gwei)在以太坊上存储250GB将花费你106,000,000美元。一般来说,我们可以忍受高成本因为我们:
  
  不会在以太坊区块链上保存那么多数据。
  
  区块链的审查制度,透明度和稳健性是值得的。
  
  如果你是以太坊的新手,请查看此介绍。
  
  去中心化存储
  
  IPFS(星际文件系统)对区块链存储有一些保证,即去中心化和防篡改,但不比传统的磁盘空间花费更多费用。使用EBS 250GB存储运行EC2 t2.micro实例将花费你大约15美元/月。IPFS的一个独特功能是它处理文件的方式。它不使用基于位置的寻址(如域名,IP地址,文件路径等),而是使用基于内容的寻址。将文件(或目录)添加到IPFS存储库后,可以通过其加密哈希来引用它。
  
  $ ipfs add article.json
  
  added Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM article.json
  
  $ ipfs cat Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
  
  {
  
  "title": "This is an awesome title",
  
  "content": "paragraph1\r\n\r\nparagraph2"
  
  }
  
  $ curl https://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
  
  {
  
  "title": "This is an awesome title",
  
  "content": "paragraph1\r\n\r\nparagraph2"
  
  }
  
  然后,你可以使用IPFS客户端或任何公共网关访问文件。你还可以创建非公共网关,默认情况下使其成为可写(只读),并实现授权方案,以便以编程方式访问IPFS网络。
  
  重要的是要了解IPFS不是一种服务,其他节点将存储你的内容。如果你的内容不受欢迎,如果他们没有固定哈希(他们不​​想租用磁盘空间),垃圾收集器会将其从其他节点中删除。只要网络上至少有一个对等体确实关心你的文件并且有兴趣存储它们,网络上的其他节点就可以轻松获取该文件。即使你的文件从网络中消失,也可以在以后再次添加,除非其内容发生更改,否则其地址(哈希)将相同。
  
  IPFS和以太坊智能合约
  
  尽管以太坊协议没有提供任何连接到IPFS的本地方式,但我们可以回到像Oraclize这样的离线解决方案来解决这个问题。Oraclize允许使​​用各种数据提供智能合约。其中一个可用的数据源是URL。我们可以使用公共网关从IPFS上的JSON文件中读取。依靠单个网关会很单薄。我们将要使用的另一个数据源是IPFS。通过使用JSON解析器(它是查询的一部分)读取Oraclize智能合约,我们可以在JSON文档中提取特定字段。
  
  oraclize_query("IPFS", "json(Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM).title"));
  
  如果Oraclize可以在20秒内获取文件,则可以预期获得异步请求。如果使用连接良好的节点上传文件,则不需要关注超时。我们的EC2(欧盟法兰克福)实例连接到大约750个同行。通过公共网关或本地运行守护进程获取文件几乎是即时的。响应是异步的,oraclize_query调用返回查询id(bytes32)。你可以将其作为来自Oraclize的数据的标识符。
  
  function __callback(bytes32 _queryId, string _data) public {
  
  require(msg.sender == oraclize_cbAddress());
  
  process_data(_data);
  
  }
  
  出于安全原因,我们希望确保只允许Oraclize调用__callback函数。
  
  你可以在GitHub上找到博客示例的完整代码库:tooploox/ipfs-eth-database
  
  性能和实施
  
  最初,我很担心性能表现。它是否可以像集中服务发送响应一样快速地获取IPFS上托管的JSON文件?结果令我很惊喜。
  
  $ wrk -d10s https://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
  
  Running 10s test @ https://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
  
  2 threads and 10 connections
  
  Thread Stats Avg Stdev Max +/- Stdev
  
  Latency 59.18ms 24.36ms 307.93ms 94.73%
  
  Req/Sec 86.34 15.48 101.00 85.57%
  
  1695 requests in 10.05s, 1.38MB read
  
  Requests/sec: 168.72
  
  Transfer/sec: 140.70KB
  
  在我们审查博客时,作者必须在智能合约上调用addPost时仅输入IPFS哈希值。我们使用IPFS和Oraclize从文件中读取标题,以使用以太坊事件存储它。我们不需要为其他智能合约保留标题,因此使用事件对于我们的用例来说已经足够了。这可能不是最具开创性的例子,但很好地展示了如何优化低交易费用。
  
  pragma solidity 0.4.24;
  
  import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
  
  import "./lib/usingOraclize.sol";
  
  import "./lib/strings.sol";
  
  contract Blog is usingOraclize, Ownable {
  
  using strings for *;
  
  mapping(address => string[www.gcyl152.com]) public hashesByAuthor;
  
  mapping(bytes32 => www.gcyL157.com string) public hashByQueryId;
  
  mapping(bytes32 =>www.yigouyule2.cn address) public authorByHash;
  
  event PostAdded(address www.mhylpt.com indexed author, string hash, uint timestamp, string title);
  
  event PostSubmitted(address indexed author, string hash, bytes32 queryId);
  
  uint private gasLimit;
  
  constructor(uint _gasPrice, uint _gasLimit) public {
  
  setCustomOraclizeGasPrice(www.michenggw.com _gasPrice);
  
  setCustomOraclizeGasLimit(_gasLimit);
  
  }
  
  function getPrice(string _source) public view returns (uint) {
  
  return oraclize_getPrice(_source);
  
  }
  
  function setCustomOraclizeGasPrice(uint _gasPrice) public onlyOwner {
  
  oraclize_setCustomGasPrice(www.mingcheng178.com_gasPrice);
  
  }
  
  function setCustomOraclizeGasLimit(uint _gasLimit) public onlyOwner {
  
  gasLimit = _gasLimit;
  
  }
  
  function withdraw() public onlyOwner {
  
  owner.transfer(address(this).balance);
  
  }
  
  function __callback(bytes32 _queryId, string _title) public {
  
  require(msg.sender == oraclize_cbAddress());
  
  require(bytes(hashByQueryId[_queryId]).length != 0);
  
  string memory hash = hashByQueryId[_queryId];
  
  address author = authorByHash[keccak256(bytes(hash))];
  
  hashesByAuthor[author].push(hash);
  
  emit PostAdded(author, hash, now, _title);
  
  }
  
  function addPost(string _hash) public payable returns (bool) {
  
  require(authorByHash[keccak256(bytes(_hash))] == address(0), "This post already exists");
  
  require(msg.value >= oraclize_getPrice("IPFS"), "The fee is too low");
  
  bytes32 queryId = oraclize_query("IPFS", "json(".toSlice().concat(_hash.toSlice()).toSlice().concat(").title".toSlice()), gasLimit);
  
  authorByHash[keccak256(bytes(_hash))] = msg.sender;
  
  hashByQueryId[queryId] = _hash;
  
  emit PostSubmitted(msg.sender, _hash, queryId);
  
  return true;
  
  }
  
  function getPriceOfAddingPost() public view returns (uint) {
  
  return oraclize_getPrice("IPFS");
  
  }
  
  }
  
  前端使用Web3读取事件,并为给定作者构建所有博客帖子的列表。
  
  降价商品的内容也存储在IPFS上。它允许保留添加新博客帖子的固定费用。我们使用一系列公共IPFS,从我们自己开始。这有意义,尤其是当您从同一节点上传文件时。如果您决定以写入模式运行网关,则还可以以编程方式固定文件(默认情况下,它是只读的)。我们还允许用户指定自己的网关。 如果用户安装了IPFS Companion,他可以利用自己的节点运行。
  
  BlogEvents.getPastEvents("PostAdded", { fromBlock: 0, filter: { author } }).then(events => {
  
  this.setState({ addedPosts: events.map(e => e.returnValues) });
  
  });
  
  // ...
  
  getPost(gatewayIndex = 0) {
  
  this.fetchPostFromIpfs(gateways[gatewayIndex])
  
  .catch(() => this.retry(gatewayIndex))
  
  }
  
  结论
  
  我们从以太坊智能合约中请求IPFS数据的小实验让我们深入了解IPFS性能,并为更多生产用例的进一步实施奠定了基础。
  
  性能问题唯一顾虑的地方可能是IPNS。IPNS是IPFS的命名系统,允许可变URL。hash对应于对等ID而不是文件或目录内容hash。在版本0.4.14中引入的新IPNS解析器和发布者已经缓解了一些问题。确保你拥有最新版本并使用-enable-namesys-pubsub选项运行守护程序,以便从几乎即时的IPNS更新中受益。
  
  在Amazon Linux 2上连续运行IPFS节点没有任何重大问题。
  
  ======================================================================
  
  分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:
  
  java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  
  python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  
  php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  
  以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  
  以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  
  C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  
  EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  
  java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  
  php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  
  tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

以太坊和IPFS如何存储数据的更多相关文章

  1. 数字货币比特币以太坊买卖五档行情数据API接口

    数字货币比特币以太坊买卖五档行情数据API接口       数字货币一般包含比特币BTC.以太坊ETH.瑞波币XRP.泰达币USDT.比特币现金BCH.比特币SV.莱特币LTC.柚子币EOS.OKB. ...

  2. 以太坊开发DApp入门教程——区块链投票系统(一)

    概述 对初学者,首先要了解以太坊开发相关的基本概念.   学习以太坊开发的一般前序知识要求,最好对以下技术已经有一些基本了解: 一种面向对象的开发语言,例如:Python,Ruby,Java... 前 ...

  3. 以太坊(ethereum)开发DApp应用的入门区块链技术教程

    概述 对初学者,首先要了解以太坊开发相关的基本概念.   学习以太坊开发的一般前序知识要求,最好对以下技术已经有一些基本了解: 一种面向对象的开发语言,例如:Python,Ruby,Java... 前 ...

  4. 以太坊开发DApp实战教程——用区块链、星际文件系统(IPFS)、Node.js和MongoDB来构建电商平台(一)

    第一节 简介 欢迎和我们一起来用以太坊开发构建一个去中心化电商DApp!我们将用区块链.星际文件系统(IPFS).Node.js和MongoDB来构建电商平台类似淘宝的在线电商应用,卖家可以自由地出售 ...

  5. 以太坊go-ethereum常见问题汇总

    (1)什么是 Ethereum? 以太坊是一个分散的智能合同平台,由Ether的加密货币提供支持. (2) 听说过以太坊,但什么是Geth,Mist,Ethminer,Mix? Geth: 以太坊节点 ...

  6. 死磕以太坊源码分析之txpool

    死磕以太坊源码分析之txpool 请结合以下代码阅读:https://github.com/blockchainGuide/ 写文章不易,也希望大家多多指出问题,交个朋友,混个圈子哦 交易池概念原理 ...

  7. 以太坊: ETH 发送交易 sendRawTransaction 方法数据的签名 和 验证过程

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  8. 基于以太坊开发的类似58同城的DApp开发与应用案例

    今天,Origin开发团队很高兴地宣布在以太坊Rinkeby测试网络上推出Origin Protocol Demo DApp ! 在这个DApp中,你可以在不同垂直行业的solidarity econ ...

  9. Solidity陷阱:以太坊的随机数生成

    title: Solidity陷阱:以太坊的随机数生成 Solidity是一种相当新的语言,因为没有代码是完美的,它包含与代码相关的问题以及你希望用它完成的任务.本文将指导你使用随机数作为以太坊智能合 ...

随机推荐

  1. RHEL 6.5 ----Postfix邮件服务器

    主机名 IP  服务  master 192.168.30.130   slave 192.168.30.131   软件包介绍 包名  介绍  postfix-2.6.6-2.2.el6_1.x86 ...

  2. [转]ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL

    本文转自:http://www.cnblogs.com/John-Connor/archive/2012/05/03/2478821.html 引言-- 在初级篇中,我们介绍了如何利用基于ASP.NE ...

  3. 04.NopCommerce启用MiniProfiler调试

    最近在调试NopCommerce的时候,常遇到一个地址不知道请求哪个路由(比如http://localhost/apparel-shoes,比如http://localhost/login)您能快速说 ...

  4. Jquary基础

    基本知识: 就是一个JS函数包 选择器:基本选择器: 基本:ID选择器 “#” , Class选择器 “.”,标签选择器 “标签名” 组合:并列用“,”隔开   后代用空格隔开 过滤选择器:基本过滤: ...

  5. SpringBoot 2.x (5):异常处理与部署WAR项目

    异常处理: SpringBoot的异常处理是不友好的,前端只会显示最基本的错误名称 后端控制台会报出具体的错误,那么我们如何告知前端具体的错误信息呢? 1:对全局异常进行处理 一个测试的Control ...

  6. webapi之fiddler头设置

    Host: localhost:16648Connection: keep-aliveContent-Length: 36Accept: application/json, text/javascri ...

  7. [Python筆記] 將 Pandas 的 Dataframe 寫入 Sqlite3

    使用 pandas.io 寫入 Sqlite import sqlite3 as lite from pandas.io import sql import pandas as pd 依照 if_ex ...

  8. vscode 打开新文件不替换旧文件

    设置 "workbench.editor.enablePreview": false

  9. Python matlab octave 矩阵运算基础

    基础总结,分别在三种软件下,计算 求逆矩阵 矩阵转置 等运算,比较异同 例子:正规方程法求多元线性回归的最优解 θ=(XTX)-1XTY octave: pwd()当前目录 ones() zeros( ...

  10. freemarker特殊字符输出

    期望输出: #{fefefefwewrerwerwrrrre}${fffqqqwwwwwwwwwwwwwwww} 但是以上解析ftl时候会报错!!!!!!!!!!!! 解决办法: 方法1:使用${r& ...