如何使用HyperledgeFabric网络react.js来构建Web应用程序

区块链

580人已加入

描述

在本节中,我们将介绍如何通过RESTful API将HyperledgeFabric网络与Web应用程序集成,并使用react.js作为前端。本教程中构建的Web应用程序仅是保单持有者应用程序。

应用执行

在继续下面操作步骤时,请按照第一节内容进行搭建后,再继续以下操作。

在insurance_application文件夹中,运行以下命令以创建保单持有人Web应用程序的框架:

npx create-react-app policyholder_app

cd policyholder_app

打开src/app.js并删除函数app返回中的代码,只需添加hello world作为占位符,这样app.js文件现在看起来如下

import React from ‘react’;

import ‘。/App.css’;

function App() {

return (

《p》Hello World《/p》

);

}

export default App;

用以下内容替换src / App.css中的代码:

* {

box-sizing: border-box;

margin: 0;

padding: 0;

}

body {

font-family: Arial, Helvetica, sans-serif;

line-height: 1.4;

background: #5B5B5B;

font-family: monospace;

font-size: 150%

}

a {

color: #333;

text-decoration: none;

font-family: monospace;

}

.container {

padding: 0 1rem;

}

.btn {

display: inline-block;

border: none;

background: #555;

color: #fff;

padding: 7px 20px;

cursor: pointer;

}

.btn:hover {

background: #666;

}

React应用程序的默认端口号是3000,因此需要更改它以使其不与REST API端口冲突。要执行此操作,请将package.json的scripts部分更改为以下内容以创建端口3001:

“scripts”: {

“start”: “PORT=3001 react-scripts start”,

“build”: “react-scripts build”,

“test”: “react-scripts test”,

“eject”: “react-scripts eject”

},

此外,我们需要在文件的底部添加一个代理,该代理将连接到Hyperledger Composer Network,因此只需在结束大括号之前添加以下行:

“proxy”: “http://localhost:3000/”

在此文件夹中创建以下新文件夹src/components和以下新文件header.js。这将为我们的应用程序创建一个简单的标题,其中包含指向主页的链接:

import React, { Component } from ‘react’

import { Link } from ‘react-router-dom’;

class Header extends Component {

render() {

return (

《header style={headerStyle}》

《h1 style={titleStyle}》Policyholder Blockchain Insurance《/h1》

《Link style={linkStyle} to=“/”》Home《/Link》

《/header》

}

}

const headerStyle = {

background: ‘#333’,

color: ‘#fff’,

textAlign: ‘right’,

padding: ‘10px’

}

const linkStyle = {

color: ‘#fff’,

textDecoration: ‘none’

}

const titleStyle = {

textAlign: ‘left’

}

export default Header;

现在修改app.js,以便导入:

import { BrowserRouter as Router, Route } from ‘react-router-dom’;

import Header from ‘。/components/Header’

它实现了组件Header.js,如下所示:

《Router》

《Header/》

《/Router》

App.js现在看起来应该是这样的:

import React from ‘react’;

import { BrowserRouter as Router, Route } from ‘react-router-dom’;

import ‘。/App.css’;

import Header from ‘。/components/Header’

function App() {

return (

《Router》

《Header/》

《/Router》

);

}

export default App;

您可能需要安装react-router-dom:

npm install --save react-router-dom

此外,您可能还需要安装react-responsive-modal:

npm install react-responsive-modal --save

现在运行应用程序以通过从policyholder_app文件夹运行以下命令来测试所有工作正常

npm start

如果一切正常,应用程序应如下所示:

创建一个与Blockchain RESTful API连接的函数。使用以下代码创建src / Connection.js:

function search(query, cb) {

return new Promise( (resolve,reject) =》 {

return fetch(`api/${query}`, {

accept: “application/json”

})

.then(parseJSON)

.then(data =》 resolve(data));

})

}

function create(type, data){

return new Promise((resolve, reject) =》 {

return fetch(`api/${type}`, {

headers: {

‘Accept’: ‘application/json’,

‘Content-Type’: ‘application/json’

},

method: ‘post’,

body: JSON.stringify(data)

})

.then(parseJSON)

.then(() =》 resolve())

})

}

function parseJSON(response) {

return response.json();

}

const Connection = { search, create };

export default Connection;

在components文件夹中创建一个类组件Homepage.js. 这将显示主页上的所有组件:

import React, { Component } from ‘react’

class Homepage extends Component {

render() {

return (

《div》

《/div》);

}

}

//PropTypes

Homepage.propTypes = {

}

export default Homepage

要导入用户资产并在主页上显示它们,需要另一个类组件。创建一个类组件usersassets.js并包含以下代码:

import React, { Component } from ‘react’

import PropTypes from ‘prop-types’;

import UserAssetsItems from ‘。/UserAssetsItems’

class UserAssets extends Component {

render() {

return (

《div》

{this.props.assets.map((asset) =》 (

《UserAssetsItems key={asset.id} asset={asset}/》

))}

《/div》

)}

}

//PropTypes

UserAssets.propTypes = {

assets: PropTypes.array.isRequired

}

export default UserAssets

这将需要以props数组的形式传递资产。要显示资源,请使用map循环遍历数组,并将项目传递给名为UserAssetsItems.js的类组件。

创建单独处理资产的类组件UserAssetsItems.js。这只是创建一张具有资产类型和价值的卡片。请注意,我已经在这里完成了内联样式,但如果您更喜欢使用CSS,则可以使用CSS执行此操作。

import React, { Component } from ‘react’

import PropTypes from ‘prop-types’;

class UserAssetsItems extends Component {

render() {

let assetStyle = {

card: {

display: ‘inline-block’,

background: ‘#333’,

width: ‘350px’,

height: ‘160px’,

textAlign: ‘left’,

padding: ‘20px’,

margin: ‘20px’,

border: ‘5px solid #333’,

color: ‘white’

}

}

return (

《div style = { assetStyle.card }》

《p》Description: {this.props.asset.assetType}《/p》

《p》 Value: {this.props.asset.value}《/p》

《/div》

}

}

//PropTypes

UserAssetsItems.propTypes = {

asset: PropTypes.object.isRequired

}

export default UserAssetsItems

通过在文件顶部添加以下行,将userassetsitems导入到userassets

import UserAssetsItems from ‘。/UserAssetsItems’

将UserAssets导入主页并更新主页代码,如下所示。这只是显示用户资产并为其设置样式。现在主页还要求将资产数组作为prop传递,以便将其传递给UserAssets.js

import React, { Component } from ‘react’

import UserAssets from ‘。/UserAssets’

import PropTypes from ‘prop-types’;

class Homepage extends Component {

render() {

let style = {

UserAssetsStyle: {

position: ‘relative’,

top: ‘10px’,

width: ‘58%’,

borderRight: ‘1px solid black’,

}

}

return (

《div》

《div style = { style.UserAssetsStyle }》

《UserAssets assets = { this.props.assets } /》

《/div》

《/div》);

}

}

//PropTypes

Homepage.propTypes = {

assets: PropTypes.array.isRequired

}

export default Homepage

回到app.js中,添加一个状态,以便包括用户的名称和一个空的资产数组,如下所示:

state = {

name: “joe”,

assets: []

}

该名称将用作硬编码值,因为该网站尚未登录。

通过在文件顶部添加以下行,将connection.js导入app.js。

import Connection from ‘。/Connection’

为了能够获取用户资产,需要在执行此操作的区块链网络中创建查询。因此,在文件夹risk-analysis-tutorial中,将以下行添加到将返回用户资产的queries.qry:

query selectAssetByPolicyholder {

description: “Select an asset based on the owner”

statement:

SELECT org.acme.riskanalysis.PrivateAsset

WHERE (policyholder == _$policyholder)

}

现在将package.json更新到版本4并重新部署您的网络:

composer archive create --sourceType dir --sourceName 。 -a risk-analysis-tutorial@0.0.4.bna

composer network install --card PeerAdmin@hlfv1 --archiveFile risk-analysis-tutorial@0.0.4.bna

composer network upgrade -c PeerAdmin@hlfv1 -n risk-analysis-tutorial -V 0.0.4

运行composer rest服务器

composer-rest-server -c admin@risk-analysis-tutorial -n never -u true -w true

向App.js添加一个函数以从区块链网络中检索用户资产,如下所示:

getAssets = () =》 {

// Search for the users assets

Connection.search(‘queries/selectAssetByPolicyholder?policyholder=resource%3Aorg.acme.riskanalysis.Policyholder%23’ + this.state.name)

.then(data =》 {

//store the assets in the assets array

this.setState({

assets: data

})

// Retrieve the user object from the state

let user = this.state.user

// Add the number of assets to the object

user.numAssets = this.state.assets.length

// Update the state

this.setState({

user

})

let assets = this.state.assets

for (let i = 0; i 《 assets.length; i++) {

// Set insurance status

if (assets[i].insuranceCompany == null) {

assets[i].insured = false

}

else {

assets[i].insured = true

}

}

// Update the state

this.setState({

assets: assets

})

})

}

通过将以下行添加到文件顶部,将主页导入App.js

import Homepage from ‘。/components/Homepage’

既然我们有了这些资产,就可以将它们传递到我们的主页,所以在app.js中的路由器中添加以下行,将这些资产作为props传递。

《Route exact path={“/”} render={props =》 (

《React.Fragment》

《h1》My Assets《/h1》

《Homepage assets={this.state.assets} /》

《/React.Fragment》

)}

/》

您的完整app.js文件现在应该如下所示:componentwillmount():

import React, { Component } from ‘react’;

import { BrowserRouter as Router, Route } from ‘react-router-dom’;

import ‘。/App.css’;

import Header from ‘。/components/Header’

import Connection from ‘。/Connection’

import Homepage from ‘。/components/Homepage’

class App extends Component {

state = {

name: “joe”,

assets: []

}

componentWillMount() {

this.getAssets()

}

getAssets = () =》 {

// Search for the users assets

Connection.search(‘queries/selectAssetByPolicyholder?policyholder=resource%3Aorg.acme.riskanalysis.Policyholder%23’ + this.state.name)

.then(data =》 {

//store the assets in the assets array

this.setState({

assets: data

})

// Retrieve the user object from the state

let user = this.state.user

// Add the number of assets to the object

user.numAssets = this.state.assets.length

// Update the state

this.setState({

user

})

let assets = this.state.assets

for (let i = 0; i 《 assets.length; i++) {

// Set insurance status

if (assets[i].insuranceCompany == null) {

assets[i].insured = false

}

else {

assets[i].insured = true

}

}

// Update the state

this.setState({

assets: assets

})

})

}

render() {

return (

《Router》

《Header /》

《Route exact path={“/”} render={props =》 (

《React.Fragment》

《h1》My Assets《/h1》

《Homepage assets={this.state.assets} /》

《/React.Fragment》

)}

/》

《/Router》

);

}

}

export default App;

如果一切正常,您应该在Web应用程序中看到以下内容。 注意此处显示的资产是本教程第1部分中创建的资产。

为了可以添加新资产,我们需要App.js中的一个函数来实现这一点,所以在App.js中创建AddAsset函数:

addAsset = (assetType, value, durationInMonths) =》 {

// Create the data object

const data = {

“$class”: “org.acme.riskanalysis.CreateNewAsset”,

“policyholder”: “org.acme.riskanalysis.Policyholder#” + this.state.name,

“assetType”: assetType,

“value”: Number(value),

“durationInMonths”: Number(durationInMonths)

}

// Send this data to the Hyperledger Network

Connection.create(‘CreateNewAsset’, data)

.then((err) =》 {

if (err) {

console.log(err)

}

// Get the new asset

this.getAssets()

})

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分