我们为什么要构建这个?在以太坊区块链上存储大量数据是非常昂贵的。根据以太坊的黄皮书,它是大约20,0000gas,256bit/8字节(1字)。基于02/28/2018 gas价格为4gwei/gas。请参阅:https://ethgasstation.info了解当前价格。
每个交易8个字节20,000gas*4gwei/gas=80,000gwei
。
8,000字节80,000gwei*1000bytes/8=10,000,000gwei/kB=
0.01`以太。
0.01以太/kB*1000kB=10以太
存储1Mb,价格为860美元/以太=8600.00美元!在以太坊区块链上存储1GB
文件需要花费8,600,000.00
美元!
存储以太坊的38页PDF黄皮书(520Kb)=4472美元。请参阅: http://eth-converter.com/进行转换计算。
如果我们只能在区块链上存储几Kb的数据,那么我们仍然需要依靠集中式服务器来存储数据。值得庆幸的是,可以使用称为InterPlanetary files system
星际文件系统IPFS
的去中心化网络上存储数据的解决方案。请参阅:https://ipfs.io/了解更多信息。在IPFS中查找文件时,你要求网络查找将内容存储在唯一哈希后面的节点。来自IPFS自己的网站:
“IPFS和Blockchain完美匹配!你可以使用IPFS处理大量数据,并将不可变的永久IPFS链接放入区块链交易中。这个时间戳和保护你的内容,而不必将数据放在链本身上。“
我们构建什么?
一个简单的DApp,用于将文档上载到IPFS,然后将IPFS哈希存储在以太坊区块链上。一旦IPFS哈希号被发送到以太坊区块链,用户将收到交易收据。我们将使用Create-React-App
框架来构建前端。此Dapp适用于在浏览器中安装了MetaMask
的任何用户。
这就是我们完成后DApp的样子:
如何建立它:
注意:如果你只是想要代码,请参阅我的github。
在我们开始之前,这些是我做出的假设:
- 关于用户的假设:用户安装了Metamask以与DApp交互。
- 关于你/开发人员的假设:你对JavaScript、React.js以及Node.js/NPM有一定的了解。重要说明:请确保你运行当前版本的Node和NPM。对于本教程,我正在运行:node v8.9.4和NPM 5.6.0。
- 安装MetaMask。如果尚未安装MetaMask,请访问https://metamask.io/并按照说明操作。此DApp将假定用户已安装MetaMask。
- 创建一个目录来存储我们的DApp。对于本教程,我将其称为
eth-ipfs
。 - 使用NPM安装
Create-React-App
和其他依赖项。使用NPM并安装以下内容:
npm i create-react-app
npm install react-bootstrap
npm install fs-extra
npm install ipfs-api
npm install web3@^1.0.0-beta.26
输入eth-ipfs
目录,键入npm start
,Create-React-App
应自动在http://localhost:3000/
上呈现。
注意:如果你到目前为止尚未使用create-react-app
,则可能必须先在全局安装它
-
sudo npm install -g create-react-app
或者npm install -g create-react-app
-
create-react-app eth-ipfs
-
cd
进入eth-ipfs
然后运行npm start
在Rinkeby testnet上使用Remix部署以下Solidity代码。请参阅https://remix.ethereum.org。你需要一些Rinkeby测试以太,如果你还没有Rinkeby faucet的一些免费测试以太话。https://www.rinkeby.io/#faucet。
pragma solidity ^0.4.17;
contract Contract {
string ipfsHash;
function sendHash(string x) public {
ipfsHash = x;
}
function getHash() public view