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


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

本文由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('http://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('http://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原力区官网:http://ipfsforce.com

IPFSER社区: http://ipfser.org

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


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

原文始发于微信公众号(IPFS原力区):【IPFS相关】构建可加载图片的分布式应用程序

本文由 Ipfs币 作者:ipfs币 发表,其版权均为 Ipfs币 所有,文章内容系作者个人观点,不代表 Ipfs币 对观点赞同或支持。如需转载,请注明文章来源。
14

发表评论