做者:黎躍春,孔壹學院創始人,區塊鏈、高可用架構師css
微信:liyc1215html
區塊鏈博客:http://liyuechun.org前端
基於以太坊Ethereum & IPFS的去中心化Ebay區塊鏈項目詳情連接node
在前面兩篇文章中,第一篇春哥給你們詳細介紹了IPFS
環境配置,第二篇介紹了IPFS
如何搭建我的博客,經過這兩篇文章相信你們已經對IPFS
有所瞭解,接下來的這篇文章,咱們將爲你們講解js-ipfs-api
的簡單使用,如何將數據上傳到IPFS
,以及如何從IPFS
經過HASH
讀取數據。npm
參考文檔:https://reactjs.org/tutorial/tutorial.htmljson
localhost:1123 yuechunli$ npm install -g create-react-app
localhost:1123 yuechunli$ create-react-app ipfs-http-demo localhost:ipfs-http-demo yuechunli$ ls README.md package.json src node_modules public yarn.lock localhost:ipfs-http-demo yuechunli$
localhost:ipfs-http-demo yuechunli$ npm start
Compiled successfully! You can now view ipfs-http-demo in the browser. Local: http://localhost:3000/ On Your Network: http://192.168.0.107:3000/ Note that the development build is not optimized. To create a production build, use yarn build.
瀏覽器瀏覽http://localhost:3000
。api
效果以下:跨域
ipfs-api
⚠️:在這裏我就不過多的去介紹React的使用以及開發,若是感興趣的能夠去看這套React的視頻,學完這套視頻你能夠直接進企業找React相關的前端開發工做。瀏覽器
ipfs-api
切換到項目根目錄,安裝ipfs-api
。
$ npm uninstall --save ipfs-api
localhost:ipfs-http-demo yuechunli$ ls README.md package.json src node_modules public yarn.lock localhost:ipfs-http-demo yuechunli$ pwd /Users/liyuechun/Desktop/1123/ipfs-http-demo localhost:ipfs-http-demo yuechunli$ npm uninstall --save ipfs-api
⚠️:ipfs安裝完後,如上圖所示,接下來刷新一下瀏覽器,看看項目是否有問題,正常來說,一切會正常,???,Continue,Continue,Continue......
拷貝下面的代碼,將src/App.js
裏面的代碼直接替換掉。
import React, { Component } from 'react'; import './App.css'; class App extends Component { constructor(props) { super(props); this.state = { strHash: null, strContent: null } } render() { return ( <div className="App"> <input ref="ipfsContent" style={{width: 200,height: 40,borderWidth:2}}/> <button onClick={() => { let ipfsContent = this.refs.ipfsContent.value; console.log(ipfsContent); }}>提交到IPFS</button> <p>{this.state.strHash}</p> <button onClick={() => { console.log('從ipfs讀取數據。') }}>讀取數據</button> <h1>{this.state.strContent}</h1> </div> ); } } export default App;
上面的代碼完成的工做是,當咱們在輸入框中輸入一個字符串時,點擊提交到IPFS按鈕,將文本框中的內容取出來打印,後續咱們須要將這個數據上傳到IPFS
。點擊讀取數據按鈕,咱們也只是隨便打印了一個字符串,後面須要從IPFS讀取數據,而後將讀取的數據存儲到狀態機變量strContent
中而且展現出來。
const ipfsAPI = require('ipfs-api'); const ipfs = ipfsAPI({host: 'localhost', port: '5001', protocol: 'http'});
saveTextBlobOnIpfs = (blob) => { return new Promise(function(resolve, reject) { const descBuffer = Buffer.from(blob, 'utf-8'); ipfs.add(descBuffer).then((response) => { console.log(response) resolve(response[0].hash); }).catch((err) => { console.error(err) reject(err); }) }) }
response[0].hash
返回的是數據上傳到IPFS
後返回的HASH
字符串。
this.saveTextBlobOnIpfs(ipfsContent).then((hash) => { console.log(hash); this.setState({strHash: hash}); });
ipfsContent
是從文本框中取到的數據,調用this.saveTextBlobOnIpfs
方法將數據上傳後,會返回字符串hash
,而且將hash
存儲到狀態機變量strHash
中。
目前完整的代碼:
import React, {Component} from 'react'; import './App.css'; const ipfsAPI = require('ipfs-api'); const ipfs = ipfsAPI({host: 'localhost', port: '5001', protocol: 'http'}); class App extends Component { constructor(props) { super(props); this.state = { strHash: null, strContent: null } } saveTextBlobOnIpfs = (blob) => { return new Promise(function(resolve, reject) { const descBuffer = Buffer.from(blob, 'utf-8'); ipfs.add(descBuffer).then((response) => { console.log(response) resolve(response[0].hash); }).catch((err) => { console.error(err) reject(err); }) }) } render() { return (<div className="App"> <input ref="ipfsContent" style={{ width: 200, height: 40, borderWidth: 2 }}/> <button onClick={() => { let ipfsContent = this.refs.ipfsContent.value; console.log(ipfsContent); this.saveTextBlobOnIpfs(ipfsContent).then((hash) => { console.log(hash); this.setState({strHash: hash}); }); }}>提交到IPFS</button> <p>{this.state.strHash}</p> <button onClick={() => { console.log('從ipfs讀取數據。') }}>讀取數據</button> <h1>{this.state.strContent}</h1> </div>); } } export default App;
測試:
跨域資源共享( CORS )
配置,依次在終端執行下面的代碼:
localhost:ipfs-http-demo yuechunli$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST", "OPTIONS"]' localhost:ipfs-http-demo yuechunli$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' localhost:ipfs-http-demo yuechunli$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]' localhost:ipfs-http-demo yuechunli$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]' localhost:ipfs-http-demo yuechunli$ ipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'
用正確的端口運行daemon:
localhost:ipfs-http-demo yuechunli$ ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001 localhost:ipfs-http-demo yuechunli$ ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001 localhost:ipfs-http-demo yuechunli$ ipfs daemon
ipfs.cat
ipfs.cat(this.state.strHash).then((stream) => { console.log(stream); let strContent = Utf8ArrayToStr(stream); console.log(strContent); this.setState({strContent: strContent}); });
stream
爲Uint8Array
類型的數據,下面的方法是將Uint8Array
轉換爲string
字符串。
Utf8ArrayToStr
function Utf8ArrayToStr(array) { var out, i, len, c; var char2, char3; out = ""; len = array.length; i = 0; while(i < len) { c = array[i++]; switch(c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx out += String.fromCharCode(c); break; case 12: case 13: // 110x xxxx 10xx xxxx char2 = array[i++]; out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); break; case 14: // 1110 xxxx 10xx xxxx 10xx xxxx char2 = array[i++]; char3 = array[i++]; out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); break; default: break; } } return out; }
import React, {Component} from 'react'; import './App.css'; const ipfsAPI = require('ipfs-api'); const ipfs = ipfsAPI({host: 'localhost', port: '5001', protocol: 'http'}); function Utf8ArrayToStr(array) { var out, i, len, c; var char2, char3; out = ""; len = array.length; i = 0; while (i < len) { c = array[i++]; switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx out += String.fromCharCode(c); break; case 12: case 13: // 110x xxxx 10xx xxxx char2 = array[i++]; out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); break; case 14: // 1110 xxxx 10xx xxxx 10xx xxxx char2 = array[i++]; char3 = array[i++]; out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); break; default: break; } } return out; } class App extends Component { constructor(props) { super(props); this.state = { strHash: null, strContent: null } } saveTextBlobOnIpfs = (blob) => { return new Promise(function(resolve, reject) { const descBuffer = Buffer.from(blob, 'utf-8'); ipfs.add(descBuffer).then((response) => { console.log(response) resolve(response[0].hash); }).catch((err) => { console.error(err) reject(err); }) }) } render() { return (<div className="App"> <input ref="ipfsContent" style={{ width: 200, height: 40, borderWidth: 2 }}/> <button onClick={() => { let ipfsContent = this.refs.ipfsContent.value; console.log(ipfsContent); this.saveTextBlobOnIpfs(ipfsContent).then((hash) => { console.log(hash); this.setState({strHash: hash}); }); }}>提交到IPFS</button> <p>{this.state.strHash}</p> <button onClick={() => { console.log('從ipfs讀取數據。') ipfs.cat(this.state.strHash).then((stream) => { console.log(stream); let strContent = Utf8ArrayToStr(stream); console.log(strContent); this.setState({strContent: strContent}); }); }}>讀取數據</button> <h1>{this.state.strContent}</h1> </div>); } } export default App;
這篇文章主要講解如何配置React環境,如何建立React項目,如何安裝js-ipfs-api
,如何上傳數據,如何設置開發環境,如何下載數據等等內容。經過這篇文章的系統學習,你會掌握js-ipfs-api
在項目中的使用流程。
這是【IPFS + 區塊鏈 系列】 入門篇 - IPFS + Ethereum (上篇)-js-ipfs-api
,下篇講解如何將IPFS和以太坊智能合約結合進行數據存儲。
這是【IPFS + 區塊鏈 系列】 入門篇 - IPFS + Ethereum (上篇)-js-ipfs-api
,下篇講解如何將IPFS和以太坊智能合約結合進行數據存儲。
348924182
liyc1215