以太坊ipfs
by Niharika Singh
由Niharika Singh
There are a lot of pain points being faced by blockchain which may be solved by Infura and/or the InterPlanetary File System (IPFS), to some extent. These are the main challenges:
区块链面临很多难题,Infura和/或行星际文件系统(IPFS)可以在一定程度上解决这些难题。 这些是主要挑战:
If you use Infura, access to the Ethereum network and the IPFS becomes a lot faster. It no longer takes hours to sync up the geth client which uses up a huge chunk of memory and bandwidth while the entire blockchain gets downloaded.
如果您使用Infura,则访问以太坊网络和IPFS的速度将大大提高。 同步geth客户端不再花费数小时,该客户端在下载整个区块链时会占用大量内存和带宽。
Here are some other advantages that come with using Infura:
以下是使用Infura的其他一些优点:
Our dApp will take a file as input from a user and upload it to the IPFS by invoking an Ethereum contract. The hash of the file will be stored on Ethereum.
我们的dApp将从用户那里获取文件作为输入,并通过调用以太坊合约将其上传到IPFS。 文件的哈希值将存储在以太坊上。
This is the process we’ll go through:
这是我们要经历的过程:
React — Front end library
React —前端库
Solidity — The language used to build smart contracts that runs on Ethereum
坚固性 -用于构建在以太坊上运行的智能合约的语言
IPFS — Decentralized storage
IPFS —分散存储
Infura —API access to Ethereum network and IPFS
Infura-对以太坊网络和IPFS的API访问
Make sure you already have Metamask downloaded. If not, download it from here.
确保您已经下载了Metamask。 如果没有,请从此处下载。
Also, keep your Node and NPM up to date.
另外,保持您的节点和NPM为最新。
$ npm i -g create-react-app$ npm install react-bootstrap$ npm install fs-extra$ npm install ipfs-api$ npm install web3
After you’re done, run the following command on your CLI to create a sample React project. I’ll name my project ipfs.
完成后,在CLI上运行以下命令以创建示例React项目。 我将项目命名为ipfs 。
$ create-react-app ipfs
.Make sure you’re on Ropsten testnet on metamask.
确保在元掩码上使用Ropsten测试网。
To deploy the smart contract, we need ether. To get ether for Ropsten testnet, go to https://faucet.metamask.io/.
要部署智能合约,我们需要以太币。 要获取Ropsten测试网的以太币,请访问https://faucet.metamask.io/ 。
To deploy the smart contract, go to https://remix.ethereum.org.
要部署智能合约,请访问https://remix.ethereum.org 。
pragma solidity ^0.4.17;
contract Contract { string ipfsHash; function setHash(string x) public { ipfsHash = x; } function getHash() public view returns (string x) { return ipfsHash; }
}
Save the address of smart contract. Mine is: 0x610DD75057738B73e3F17A9D607dB16A44f962F1
保存智能合约的地址。 我的是:0x610DD75057738B73e3F17A9D607dB16A44f962F1
Also, save the Application Binary Interface (ABI) in JSON. It can be found in the ‘compile’ tab, under ‘details’.
另外,将应用程序二进制接口(ABI)保存为JSON。 可以在“详细信息”下的“编译”选项卡中找到。
Mine is the following:
我的是:
[ { "constant": false, "inputs": [ { "name": "x", "type": "string" } ], "name": "sendHash", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getHash", "outputs": [ { "name": "x", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }]
In the “ipfs/src” directory, create the following files: web3.js, ipfs.js, and storehash.js.
在“ ipfs / src”目录中,创建以下文件: web3.js , ipfs.js和storehash.js 。
import Web3 from 'web3';
const web3 = new Web3(window.web3.currentProvider);
export default web3;
import web3 from './web3';
//Your contract addressconst address = '0x610dd75057738b73e3f17a9d607db16a44f962f1';
//Your contract ABIconst abi = [ { "constant": false, "inputs": [ { "name": "x", "type": "string" } ], "name": "sendHash", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getHash", "outputs": [ { "name": "x", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }]
export default new web3.eth.Contract(abi, address);
const IPFS = require('ipfs-api');const ipfs = new IPFS({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' });
export default ipfs;
import React from 'react';import ReactDOM from 'react-dom';import './index.css';import App from './App';import registerServiceWorker from './registerServiceWorker';import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(<App />, document.getElementById('root'));registerServiceWorker();
import React, { Component } from 'react';import web3 from './web3';import ipfs from './ipfs';import storehash from './storehash';import { Button } from 'reactstrap';
class App extends Component {
state = { ipfsHash:null, buffer:'', ethAddress:'', transactionHash:'', txReceipt: '' };
//Take file input from usercaptureFile =(event) => { event.stopPropagation() event.preventDefault() const file = event.target.files[0] let reader = new window.FileReader() reader.readAsArrayBuffer(file) reader.onloadend = () => this.convertToBuffer(reader) };
//Convert the file to buffer to store on IPFS convertToBuffer = async(reader) => { //file is converted to a buffer for upload to IPFS const buffer = await Buffer.from(reader.result); //set this buffer-using es6 syntax this.setState({buffer}); };
//ES6 async functiononClick = async () => {try{ this.setState({blockNumber:"waiting.."}); this.setState({gasUsed:"waiting..."});
await web3.eth.getTransactionReceipt(this.state.transactionHash, (err, txReceipt)=>{ console.log(err,txReceipt); this.setState({txReceipt}); }); }catch(error){ console.log(error); }}
onSubmit = async (event) => { event.preventDefault();
//bring in user's metamask account address const accounts = await web3.eth.getAccounts(); //obtain contract address from storehash.js const ethAddress= await storehash.options.address; this.setState({ethAddress}); //save document to IPFS,return its hash#, and set hash# to state await ipfs.add(this.state.buffer, (err, ipfsHash) => { console.log(err,ipfsHash); //setState by setting ipfsHash to ipfsHash[0].hash this.setState({ ipfsHash:ipfsHash[0].hash }); // call Ethereum contract method "sendHash" and .send IPFS hash to etheruem contract //return the transaction hash from the ethereum contract storehash.methods.sendHash(this.state.ipfsHash).send({ from: accounts[0] }, (error, transactionHash) => { console.log(transactionHash); this.setState({transactionHash}); }); }) };
render() {
return ( <div className="App"> <header className="App-header"> <h1>Ethereum and IPFS using Infura</h1> </header>
<hr/><grid> <h3> Choose file to send to IPFS </h3> <form onSubmit={this.onSubmit}> <input type = "file" onChange = {this.captureFile} /> <Button bsStyle="primary" type="submit"> Send it </Button> </form><hr/> <Button onClick = {this.onClick}> Get Transaction Receipt </Button> <hr/> <table bordered responsive> <thead> <tr> <th>Tx Receipt Category</th> <th> </th> <th>Values</th> </tr> </thead>
<tbody> <tr> <td>IPFS Hash stored on Ethereum</td> <td> : </td> <td>{this.state.ipfsHash}</td> </tr> <tr> <td>Ethereum Contract Address</td> <td> : </td> <td>{this.state.ethAddress}</td> </tr> <tr> <td>Tx # </td> <td> : </td> <td>{this.state.transactionHash}</td> </tr> </tbody> </table> </grid> </div> ); }}export default App;
And that is all!
仅此而已!
Access your dApp at localhost:3000. Upload a file and you will see a hash generated. To make sure your file is uploaded, access it via the IPFS gateway. Make sure you accept the Metamask requests.
通过localhost:3000访问您的dApp。 上载文件,您将看到生成的哈希。 要确保文件已上传,请通过IPFS网关访问它。 确保您接受Metamask请求。
Access your file at: https://gateway.ipfs.io/ipfs/your IPFS hash
通过以下网址访问文件:https://gateway.ipfs.io/ipfs/您的IPFS哈希
Mine is at: https://gateway.ipfs.io/ipfs/QmbyizSHLirDfZhms75tdrrdiVkaxKvbcLpXzjB5k34a31
我的是在: https : //gateway.ipfs.io/ipfs/QmbyizSHLirDfZhms75tdrrdiVkaxKvbcLpXzjB5k34a31
To know more about IPFS, see my other articles:
要了解有关IPFS的更多信息,请参阅其他文章:
Learn by doing: a nice and easy intro to the Inter Planetary File SystemPrimer on IPFSmedium.freecodecamp.orgIPFS ? and Merkle Forest?What is IPFS?hackernoon.com
边做边学: IPFS medium.freecodecamp.org IPFS 上 “ Inter Planetary File System Primer”的 一个很好的简单介绍 。 和默克尔·森林(Merkle Forest)? 为 W h 是IPFS?哈哈 ckernoon.com
以太坊ipfs