IPFS 和区块链(三)-js-ipfs-api

2019-07-08  本文已影响0人  花爬满篱笆

在B站看了黎跃春老师的教学视频,结合网上的资源和自己的操作整理的笔记,知识无价,感谢分享!

IPFS 和区块链(三)-js-ipfs-api

https://segmentfault.com/a/1190000012138804

Ebay项目

基于以太坊Ethereum & IPFS的去中心化Ebay区块链项目

image.png

目录

1. 内容简介

在前面两篇文章中,第一篇春哥给大家详细介绍了IPFS环境配置,第二篇介绍了IPFS如何搭建个人博客,通过这两篇文章相信大家已经对IPFS有所了解,接下来的这篇文章,我们将为大家讲解js-ipfs-api的简单使用,如何将数据上传到IPFS,以及如何从IPFS通过HASH读取数据。

2. IPFS-HTTP效果图

3. 实现步骤

3.1 安装create-react-app

参考文档:https://reactjs.org/tutorial/tutorial.html

$ mkdir 1123

$ cd 1123

$ npm install -g create-react-app

3.2 React项目创建

$ create-react-app ipfs-http-demo

$ ls

image.png

3.3 运行React项目

$ cd ipfs-http-demo

$ ls

atom ./

image.png

node_modules 依赖包

index.html 是一个入口

App.js入口

$ npm start 启动项目

3.4 浏览项目

浏览器浏览http://localhost:3000

效果如下:

image.png

3.5 安装ipfs-api

⚠️:在这里我就不过多的去介绍React的使用以及开发,如果感兴趣的可以去看这套React的视频,学完这套视频你可以直接进企业找React相关的前端开发工作。

image.png

切换到项目根目录,安装ipfs-api。

$ cd ipfs-http-demo

$ npm install --save ipfs-api

$ ls

$ pwd

image.png image.png

⚠️:ipfs安装完后,如上图所示,接下来刷新一下浏览器,看看项目是否有问题,正常来讲,一切会正常,???,Continue,Continue,Continue......

如果不正常就卸载

$ npm uninstall --save ipfs-api

重新安装

$ npm install --save-dev ipfs-api

3.6 完成UI逻辑

拷贝下面的代码,将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中并且展示出来。

3.7 导入IPFS

const ipfsAPI = require('ipfs-api');

const ipfs = ipfsAPI({host: 'localhost', port: '5001', protocol: 'http'});

拷贝到App.js上面。

3.8 编写上传大文本字符串到IPFS的Promise函数

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);

})

})

}

拷贝到App.js的render()函数上面。

image.png

response[0].hash返回的是数据上传到IPFS后返回的HASH字符串。

3.9 上传数据到IPFS

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;

3.10 跨域资源共享CORS配置

跨域资源共享( CORS )配置,依次在终端执行下面的代码:

$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST", "OPTIONS"]'

$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'

$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]'

$ ipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'

用正确的端口运行daemon:

$ ipfs config Addresses.API

/ip4/127.0.0.1/tcp/5001

$ ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001

$ ipfs daemon

3.11 再次刷新网页提交数据并在线查看数据

3.12 从IPFS读取数据

ipfs.cat(this.state.strHash).then((stream) => {

console.log(stream);

let strContent = Utf8ArrayToStr(stream);

console.log(strContent);

this.setState({strContent: strContent});

});
image.png image.png

stream为Uint8Array类型的数据,下面的方法是将Uint8Array转换为string字符串。

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;
image.png

3.13 总结

这篇文章主要讲解如何配置React环境,如何创建React项目,如何安装js-ipfs-api,如何上传数据,如何设置开发环境,如何下载数据等等内容。通过这篇文章的系统学习,你会掌握js-ipfs-api在项目中的使用流程。

这是【IPFS + 区块链 系列】 入门篇 - IPFS + Ethereum (上篇)-js-ipfs-api,下篇讲解如何将IPFS和以太坊智能合约结合进行数据存储。

上一篇下一篇

猜你喜欢

热点阅读