1. IPFSER首页
  2. IPFS

【IPFS相关】构建可加载图片的分布式应用程序

分布式应用程序(DApps)是在计算机的P2P网络上运行的应用程序,而不是单个计算机,其代码库是公开开放的,作为可供访问和定制的开源。DApps分布在多个服务器上,而不是位于集中式服务器上,这有助于管理大量数据和流量需求。

本文由IPFS原力区收集译制

 

分布式应用程序(DApps)是在计算机的P2P网络上运行的应用程序,而不是单个计算机,其代码库是公开开放的,作为可供访问和定制的开源。DApps分布在多个服务器上,而不是位于集中式服务器上,这有助于管理大量数据和流量需求。

 

【IPFS相关】构建可加载图片的分布式应用程序

 

比特币是分布式应用程序的一个例子,由于最近获得的兴趣,我们将更多地讨论它。

 

【IPFS相关】构建可加载图片的分布式应用程序

Blockchain并不是关于Cryptocurrencies(加密货币)和ICO(代币发行)人们认为的,围绕它的技术是令人着迷的。

“区块链是一个不可摧毁的经济交易数字分类账,可编程记录不仅仅是金融交易,而是几乎所有有价值的东西。”Don&Alex Tapscott,作者Blockchain Revolution(2016)

这正是区块链的所在。区块链上的信息作为共享 – 并且不断调和 – 数据库存在,这意味着互联网上的每个人都可以访问数据。

使用区块链存储大型文件或数据是很昂贵的,我们在InterPlanetary文件系统(IPFS)上保存大型文件,之后我们将哈希存储在区块链上。

InterPlanetary文件系统是一种协议和网络,旨在创建一种内容可寻址的点对点方法,用于在分布式文件系统中存储和共享超媒体

 

【IPFS相关】构建可加载图片的分布式应用程序

 

“IPFS和Blockchain完美匹配!您可以使用IPFS处理大量数据,并将不可变的永久IPFS链接放入区块链事务中。这个时间戳和保护您的内容,而不必将数据放在链本身上。“作者Michael Chan

现在我们了解所有区块链的全部内容。让我们构建一些东西!我们将构建一个允许用户上传图片的移动应用程序,该图片保存在IPFS上,并将IPFS哈希值保存在以太坊区块链上。

如何构建它:

Prequisite:

  1. Node.js  :它是基于谷歌Chrome的JavaScript引擎(V8引擎)构建的服务器端平台

  2. MetaMask:它是一个桥梁,允许您今天在浏览器中访问明天的分布式网络。它允许您直接在浏览器中运行Ethereum dApp,而无需运行完整的以太坊节点

  3. 松露:它是以太坊的一个开发环境,它提供了一系列工具,如ganache-core,它模拟了localhost中的以太网网络,非常适合入门。

  4. Web3:它是一组库,允许您使用HTTP或IPC连接与本地或远程以太它节点进行交互 。此处提供了更多信息。

因此,服务器将构建在Node.js和具有React-native的移动应用程序上。

我们将从编写一个获取并保存哈希的简单智能合约开始。

【IPFS相关】构建可加载图片的分布式应用程序


既然我们已经需要将可靠性代码转换为Javascript,我们将使用名为solc的npm模块。

 

【IPFS相关】构建可加载图片的分布式应用程序

在solc定义的模块的帮助下,将可靠性代码转换为Javascript对象,并将其导入我们的文件中。然后使用web3它与智能合约进行交互。

const code =fs.readFileSync('./contracts/StoreHash.sol').toString();const solc = require('solc');const compiledCode = solc.compile(code);const abi =JSON.parse(compiledCode.contracts[':SaveAddress'].interface);const SavingContract = new web3.eth.Contract(abi, '0xb1caf625d9d29421dfd8dae4a7a9083b4175f80a');// where 0xb1caf625d9d29421dfd8dae4a7a9083b4175f80a is the ethereum address

 

现在,我们有我们的智能合同规定,让我们继续前进,上传file.Going通过定义images.js 在这里 ,我主要做的是:

1.从移动应用程序获取我们的文件

exports.uploadFile = async (req, res, next) => {    if (!req.file) {        return res.status(422).json({            error: 'File needs to be provided.',        });    }    const mime = req.file.mimetype;    if (mime.split('/')[0] !== 'image') {        fs.unlink(req.file.path);        return res.status(422).json({            error: 'File needs to be an image.',        });    }    const fileSize = req.file.size;    if (fileSize > MAX_SIZE) {        fs.unlink(req.file.path);        return res.status(422).json({            error: `Image needs to be smaller than ${MAX_SIZE} bytes.`,        });    }    const data = fs.readFileSync(req.file.path);    return ipfs.add(data)        .then((file) => {            if (file) {                req.data = file;                next();            } else {                res.status(400).send('Error processing file');            }        })        .catch((err) => {            res.status(500).send(err.message);        });};

2.将其上传到IPFS

3.将哈希值保存在以太坊区块链上

exports.postData = async (req, res, next) => {    try {        const { hash } = req.data[0];        const accounts = await web3.eth.getAccounts();        const resp = await SavingContract.methods.saveHash(hash)            .send({                from: accounts[0],            });        const data = Object.assign({ ipfsHash: hash }, resp);        req.data = data;        next();    } catch (err) {        res.status(500).send(err.message);    }};

 

4.在我们的mongo数据库中保存区块链哈希和IPFS哈希

exports.create = async (req, res) => {    try {        const data = {            label: req.body.label,            ipfsHash: req.data.ipfsHash,            ipfsAddress: `https://gateway.ipfs.io/ipfs/${req.data.ipfsHash}`,            transactionHash: req.data.ipfsHash,            blockHash: req.data.blockHash,        };        const resp = await Image.create(data);        res.send(resp);    } catch (err) {        res.status(500).send(err.message);    }};

 

完整的后端源代码可以在这里找到https://github.com/linux08/Dapp/tree/master/backend

让我们移动到移动应用程序,我们使用创建一个新的应用程序

react-native init dapp

这将为您创建一个新的react-native应用程序。从这里https://github.com/linux08/Dapp/blob/master/frontend/dapp/App.js我们可以看到我们正在启动API调用我们的API服务器已启动以获取上传的所有图像

componentDidMount() {    const config = {      method: 'GET',      headers: {        Accept: 'application/json'      },    };    fetch('https://10.0.2.2:5000/images', config)      .then((resp) => resp.json())      .then((res) => {        this.setState({          images: res,          fetchLoading: false        })      })      .catch((err) => {        console.log('err', err.message)        this.setState({          fetchLoading: false,          error: err.message        });      })  }

 

如果没有可用的图像,我们可以上传新的图像。我们将使用

 

【IPFS相关】构建可加载图片的分布式应用程序

在我们的本机应用程序中上传图像。我们声明了两个函数:

1.从我们的手机阅读图像

selectImage = async () => {    ImagePicker.showImagePicker(options, async (response) => {      if (response.didCancel) {        this.setState({ error: 'Image upload failed', loading: null });      } else if (response.error) {        this.setState({ error: 'Image upload failed', loading: null });      } else if (response.customButton) {        this.setState({ error: 'Image upload failed', loading: null });      } else {        const source = { uri: response.uri };        this.setState({          uploadStatus: true,          avatarSource: source,          uri: response.uri,          type: response.type,          name: response.fileName,          originalName: response.fileName        });        global.data = new FormData();        data.append('file', {          uri: response.uri,          type: response.type,          name: response.fileName,          originalname: response.fileName,        });        const config = {          method: 'POST',          headers: {            Accept: 'application/json',            'Content-Type': 'multipart/form-data',          },          body: data,        };      }    })  }

2.将图像上传到本地服务器

 upload = async () => {    this.setState({      loading: true    });    if (!this.state.uploadStatus) {      this.setState({ loading: null })      return alert('Image yet to be uploaded')    }    if (this.state.label === '') {      this.setState({ loading: null })      return alert('Enter image label')    }    else {      data.append('label', this.state.label);      const config = {        method: 'POST',        headers: {          Accept: 'application/json',          'Content-Type': 'multipart/form-data',        },        body: data,      };      fetch('https://10.0.2.2:5000/upload', config)        .then((resp) => resp.json())        .then((res) => {          this.setState((prevState) => ({            label: res.label,            hash: res.ipfsHash,            address: res.ipfsAddress,            transactionHash: res.transactionHash,            blockHash: res.blockHash,            loading: false,            images: prevState.images.concat(res),          }))        })        .catch((err) => {          this.setState({            loading: false,            error: err.message          });        })    }

【IPFS相关】由IPFS原力区译制整理,收集外网中各领域人士在使用或开发IPFS及其相关应用时所分享的文章内容。

 

IPFS原力区官网:https://ipfsforce.com

IPFSER社区: https://ipfser.org

微博:https://weibo.com/ipfsforce

【IPFS相关】构建可加载图片的分布式应用程序

原创文章,作者:IPFSforce,如若转载,请注明出处:https://ipfser.org/2018/12/04/build-a-decentralized-react-native-application/

发表评论

登录后才能评论

联系我们

在线咨询:点击这里给我发消息

邮件:ipfsforce@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code