From 3b691766d0e8c9a3a6cf3081888d116a181126c1 Mon Sep 17 00:00:00 2001 From: myh <95896306+Anchor-x@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:13:17 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/ManageDevice.js | 357 +++++++++++++++++++++++ frontend/src/components/ManageDevices.js | 78 +++++ 2 files changed, 435 insertions(+) create mode 100644 frontend/src/components/ManageDevice.js create mode 100644 frontend/src/components/ManageDevices.js diff --git a/frontend/src/components/ManageDevice.js b/frontend/src/components/ManageDevice.js new file mode 100644 index 0000000..6a9f334 --- /dev/null +++ b/frontend/src/components/ManageDevice.js @@ -0,0 +1,357 @@ +import getWeb3 from '../utils/web3'; +import DeviceManager, { getDefaultAccount } from '../DeviceManager'; +import { addHexPrefix } from 'ethereumjs-util'; + +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import { Tag, Button, Input, Card, Timeline, Divider, Spin, Alert, Icon, notification, message } from 'antd'; + +const openNotificationWithIcon = (type, message, description) => { + notification[type]({ + message, + description + }); +}; + +const eventsToSave = ['DeviceCreated', 'DevicePropertyUpdated', 'DeviceTransfered', 'DeviceSigned', 'SignatureRevoked']; + +class ManageDevice extends Component { + constructor(props) { + super(props); + + this.state = { + deviceId: this.props.match.params.deviceId, + loading: true, + showError: false, + showEditIdentifier: false, + showEditMetadata: false, + showEditFirmware: false, + showEditOwner: false + } + + this.commonChange = this.commonChange.bind(this); + this.watchForChanges = this.watchForChanges.bind(this); + this.updateDeviceData = this.updateDeviceData.bind(this); + } + + componentWillReceiveProps({ match }) { + this.setState({ + ...this.state, + showError: false, + deviceId: match.params.deviceId + }, () => this.updateDeviceData()); + } + + async componentWillMount() { + try { + let web3 = (await getWeb3).web3; + let instance = await DeviceManager; + + this.setState({ + web3, + instance + }); + + this.updateDeviceData(); + } catch (error) { + console.log(error); + //message.error(error.message); + this.setState({ + loading: false, + showError: true + }) + } + } + + async updateDeviceData() { + try { + const { instance, deviceId } = this.state; + let device = await instance.devices(deviceId); + let signatureCount = await instance.deviceSignatureCount(deviceId); + let allEvents = instance.allEvents({ fromBlock: 0, toBlock: 'latest' }); + allEvents.get((error, logs) => { + let filteredData = logs.filter(el => eventsToSave.includes(el.event) && el.args.deviceId.toNumber() === parseInt(deviceId, 10)); + if (!error) { + this.setState({ + data: filteredData, + loading: false, + owner: device[0], + identifier: device[1], + metadataHash: device[2], + firmwareHash: device[3], + signatureCount: signatureCount.toNumber() + }) + } + + let { identifier, metadataHash, firmwareHash, owner } = this.state; + this.setState({ + identifierNew: identifier, + metadataHashNew: metadataHash, + firmwareHashNew: firmwareHash, + ownerNew: owner + }) + }); + } catch (error) { + console.log(error); + //message.error(error.message); + this.setState({ + loading: false, + showError: true + }) + } + } + + toggleEdit(property) { + const { showEditFirmware, showEditIdentifier, showEditMetadata, showEditOwner } = this.state; + + switch (property) { + case 'identifier': + this.setState({ + showEditIdentifier: !showEditIdentifier + }) + break; + case 'metadata': + this.setState({ + showEditMetadata: !showEditMetadata + }) + break; + case 'firmware': + this.setState({ + showEditFirmware: !showEditFirmware + }) + break; + case 'transfer': + this.setState({ + showEditOwner: !showEditOwner + }) + break; + default: + } + } + + watchForChanges(property) { + let filter = this.state.web3.eth.filter('latest', (error, result) => { + if (!error) { + openNotificationWithIcon('success', 'Transaction mined', `Property ${property} has been updated.`); + this.state.filter.stopWatching(); + this.updateDeviceData(); + } else { + console.error(error); + } + }); + + this.setState({ + filter + }) + } + + async saveData(property) { + const { instance, deviceId, identifier, identifierNew, metadataHash, metadataHashNew, firmwareHash, firmwareHashNew, owner, ownerNew } = this.state; + + try { + switch (property) { + case 'identifier': + if (identifier !== identifierNew) { + await instance.updateIdentifier(deviceId, addHexPrefix(identifierNew), { from: getDefaultAccount() }); + this.watchForChanges(property); + openNotificationWithIcon('info', 'Transaction sent', 'Once mined, identifier for this device will be updated.'); + this.setState({ + loading: true, + }); + } + break; + case 'metadata': + if (metadataHash !== metadataHashNew) { + await instance.updateMetadataHash(deviceId, addHexPrefix(metadataHashNew), { from: getDefaultAccount() }); + this.watchForChanges(property + ' hash'); + openNotificationWithIcon('info', 'Transaction sent', 'Once mined, metadata hash for this device will be updated.'); + this.setState({ + loading: true, + }); + } + break; + case 'firmware': + if (firmwareHash !== firmwareHashNew) { + await instance.updateFirmwareHash(deviceId, addHexPrefix(firmwareHashNew), { from: getDefaultAccount() }); + this.watchForChanges(property + ' hash'); + openNotificationWithIcon('info', 'Transaction sent', 'Once mined, firmware hash for this device will be updated.'); + this.setState({ + loading: true, + }); + } + break; + case 'transfer': + if (owner !== ownerNew) { + await instance.transferDevice(deviceId, addHexPrefix(ownerNew), { from: getDefaultAccount() }); + this.watchForChanges('owner'); + openNotificationWithIcon('info', 'Transaction sent', 'Once mined, owner for this device will be updated.'); + this.setState({ + loading: true, + }); + } + break; + default: + } + + this.toggleEdit(property); + } catch (error) { + console.log(error); + message.error(error.message); + this.toggleEdit(property); + } + + } + + commonChange(e) { + this.setState({ + [e.target.name]: e.target.value + }); + } + + render() { + const { web3, loading, showError, owner, identifier, metadataHash, firmwareHash, signatureCount, showEditFirmware, showEditIdentifier, showEditMetadata, showEditOwner } = this.state; + + let identifierContent = () => { + if (showEditIdentifier) { + return ( +
+ + +
+ ) + } + return ( +
+ Identifier {identifier}  + {owner === getDefaultAccount() && + this.toggleEdit('identifier')} /> + } +
+ ) + } + + let metadataContent = () => { + if (showEditMetadata) { + return ( +
+ + +
+ ) + } + return ( +
+ Metadata hash {metadataHash.length > 0 ? metadataHash : 'empty'}  + {owner === getDefaultAccount() && + this.toggleEdit('metadata')} /> + } +
+ ) + } + + let firmwareContent = () => { + if (showEditFirmware) { + return ( +
+ + +
+ ) + } + return ( +
+ Firmware hash {firmwareHash.length > 0 ? firmwareHash : 'empty'}  + {owner === getDefaultAccount() && + this.toggleEdit('firmware')} /> + } +
+ ) + } + + let transferContent = () => { + if (showEditOwner) { + return ( +
+ + +
+ ) + } + return ( +
+ {owner === getDefaultAccount() && + + } + {owner !== getDefaultAccount() && +
+ Owned by {owner} +
+ } +
+ ) + } + + return ( +
+ + {loading === false && showError === false && typeof metadataHash !== 'undefined' && +
+

{identifierContent()}

+ +
{metadataContent()}
+
{firmwareContent()}
+ {transferContent()} + + {signatureCount > 0 && +
+
This device has {signatureCount} active signature(s). Devices that have been signed can't be updated.
+ +
+ } + + {this.state.data.length !== 0 ? +
+

Events that are filtered are {eventsToSave.join(', ')}

+ + {this.state.data.map(el => { + if (el.event === 'DeviceCreated') + return Device created by  {el.args.owner}with  ID {el.args.deviceId.toNumber()}, identifier {el.args.identifier}, metadata hash {el.args.metadataHash} and firmware hash {el.args.firmwareHash} + if (el.event === 'DevicePropertyUpdated') + return Property {web3.toUtf8(el.args.property)} updated to {el.args.newValue} + if (el.event === 'DeviceTransfered') + return Device transfered to  {el.args.newOwner} + if (el.event === 'DeviceSigned') + return Signature with  ID {el.args.signatureId.toNumber()}created by {el.args.signer} + if (el.event === 'SignatureRevoked') + return Signature with  ID {el.args.signatureId.toNumber()}revoked + else + return null + })} + +
+ : +

empty

+ } +
+
+ } + {/* + {loading === false && owner !== getDefaultAccount() && + + } + */} + {loading === false && showError && + + } +
+
+ ); + } +} + +export default ManageDevice; \ No newline at end of file diff --git a/frontend/src/components/ManageDevices.js b/frontend/src/components/ManageDevices.js new file mode 100644 index 0000000..2ed05ba --- /dev/null +++ b/frontend/src/components/ManageDevices.js @@ -0,0 +1,78 @@ +import DeviceManager, { getDefaultAccount } from '../DeviceManager'; + +import React, { Component } from 'react'; +import { Spin, List, message } from 'antd'; +import { Link } from 'react-router-dom'; + +class ManageDevices extends Component { + constructor(props) { + super(props); + this.state = { + loading: true, + instance: null, + devices: [] + } + } + + async componentDidMount() { + try { + let instance = await DeviceManager; + let deviceIds = (await instance.getDevicesByOwner(getDefaultAccount())).map(el => el.toNumber()); + + let devicePromises = []; + for (let deviceId of deviceIds) { + let devicePromise = instance.devices(deviceId); + devicePromises.push(devicePromise); + } + + let devices = await Promise.all(devicePromises); + + this.setState({ + instance, + devices, + deviceIds, + loading: false + }); + } catch (error) { + console.log(error); + message.error(error.message); + } + } + + render() { + const { devices, loading } = this.state; + + return ( +
+ + {devices.length > 0 && !loading && +
+

+ Below you can find your devices. Click to see more details and manage. +

+ ( + + }*/ + title={{`Device ID ${this.state.deviceIds[index]}`}} + description={`Identifier ${device[1]}`} + /> + + )} + /> +
+ } + {devices.length === 0 && !loading && +

You don't have any devices registered.

+ } +
+
+ ) + } +} + +export default ManageDevices; \ No newline at end of file