web3 React Dapp书写订单 买入/取消操作

好 上文web3 前端dapp从redux过滤出 (我创建与别人创建)正在执行的订单 并展示在Table上中 我们过滤出了 我创建的 与 别人创建的 且 未完成 未取消的订单数据
这边 我们起一下 ganache 环境

ganache -d

在这里插入图片描述
然后 我们项目 发布一下智能合约

truffle migrate --reset

在这里插入图片描述
然后 登录一下 MetaMask
在这里插入图片描述
在 运行一下测试脚本

truffle exec .\scripts\test.js

然后 打开我们的项目 在根目录下的 scripts 目录中 创建一个文件 我这里叫 createOrder.js
编写代码如下

//指定以token grtoken合约
const GrToken = artifacts.require("grToken.sol")
//交易所合约
const Exchange = artifacts.require("Exchange.sol")
//定义E代理地址
const ETHER_ADDRESS = '0x0000000000000000000000000000000000000000';const toWei = (bn) => {return web3.utils.toWei(bn.toString(), "ether");
}module.exports = async function(callback) {const grTokenDai = await GrToken.deployed();const exchage = await Exchange.deployed();//获取用户列表const accounts = await web3.eth.getAccounts();//循环用 accounts 用户列表中第一个用户创建 五个订单for (let i = 1; i <= 5; i++) {await exchage.makeOrder(grTokenDai.address,toWei(101), ETHER_ADDRESS ,toWei(0.01),{from: accounts[0]});}//循环用 accounts 用户列表中第二个用户创建 五个订单for (let i = 1; i <= 5; i++) {await exchage.makeOrder(grTokenDai.address,toWei(101), ETHER_ADDRESS ,toWei(0.01),{from: accounts[1]});}callback()
}

这里 我们直接脚本执行 第一和第二个用户 分别创建出 五个订单 方便 我们后期操作
然后 我们终端运行

truffle exec .\scripts\createOrder.js

在这里插入图片描述
然后 启动我们的dapp
这里 我们第一个用户 已经可用看到非常多订单信息了
在这里插入图片描述
然后 我们 MetaMask 切换一下当前账户
在这里插入图片描述
我们切换成第二个用户
然后刷新dapp
在这里插入图片描述
也是能看到自己的订单和第一个用户创建的订单

然后 我们将 src目录下的 components 下的 Order.jsx 组件代码更改如下

import React from 'react';
import { Card, Col, Row ,Table,Button } from 'antd';
import {useSelector} from "react-redux"
import moment from "moment"function converTime(t){return moment(t*1000).format("YYYY/MM/DD")
}function convert(unit) {return window.WebData ? unit&&window.WebData.web3.utils.fromWei(unit, "ether") : ""
}function getRenderOrder(order,type) {if(!window.WebData) {return []}const account = window.WebData.account//收集起所有 已完成 或 已取消的数据idlet filterIds = [...order.Cancelorders,...order.Fillorders].map(item=>item.id)let makeorders = order.Allorders.filter(item=> !filterIds.includes(item.id))if (type === 1) {return makeorders.filter(item=>item.user === account)} else {return makeorders.filter(item=>item.user !== account)}
}export default function Order() {const order = useSelector(state => state.order)const columns = [{title: 'ETH',dataIndex: 'amountGive',render:(amountGive)=><b>{ convert(amountGive) }</b>,key: 'amountGive'},{title: 'GrToken',dataIndex: 'amountGet',render:(amountGet)=><b>{ convert(amountGet) }</b>,key: 'amountGet'},{title: '创建时间',dataIndex: 'timestamp',render:(timestamp)=><div>{ converTime(timestamp) }</div>,key: 'timestamp'},];const columns1 = [...columns,{title: '操作',render:(item)=><Button type = "text">取消</Button>}]const columns2 = [...columns,{title: '操作',render:(item)=><Button type = "text">买入</Button>}]return (<div style = {{marginTop:'10px'}}><Row><Col span={8}><Card title="已完成" bordered={false} style = {{ margin: '10px' }}><Table dataSource={order.Fillorders} columns={columns} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="我创建的" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,1)} columns={columns1} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="其他交易中订单" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,2)} columns={columns2} rowKey={item=> item.id}/></Card></Col></Row></div>);
}

这里 我们引入了 Button 按钮
然后 重新加了 两个 表头数据 columns1 和 columns2
他们都合并了 columns 原本的数据结果 然后多加了一列 叫操作 对应一个Button按钮
我创建的 叫取消
另一个叫 买入 买入别人创建的订单

然后 这里 我们先找到 antd 文档中的 对话框
在这里插入图片描述
首先 这里 我们需要 从react中引入 useState 然后从antd中 引入 Modal对话框组件
在这里插入图片描述
然后 定义一下 对话框开关 和当前操作的订单id 以及逻辑函数

//控制对话框的 布尔值
const [isModalOpen, setIsModalOpen] = useState(false);
//记录当前正在操作的订单id
const [currentId, setCurrentId] = useState(null);//点击取消订单时触发
const triggerCancellation = (id) => {setIsModalOpen(true);setCurrentId(id);
}
//对话框点击 确定 时触发
const handleOk = () => {setIsModalOpen(false);
};
//取消 或 关闭 对话框时触发
const handleCancel = () => {setIsModalOpen(false);
};

在这里插入图片描述
然后 在元素中写出这个Modal对话框组件
在这里插入图片描述
最后 在取消订单的按钮 绑定上 onClick 开启对话框函数
在这里插入图片描述
item.id 表示 我们调用函数时 将当前订单的id 传进来
然后 我们运行项目 点击取消订单
对话框 就弹出来了
在这里插入图片描述
至于取消订单的具体逻辑 我们直接来看交易所代码 我们之前写了个cancelorder函数 用来取消订单 它只需要一个参数 订单的id 然后其他的具体逻辑 我们会自己调事件的
在这里插入图片描述
这里 我们先换回第一个账号吧
在这里插入图片描述
然后 我们将刚才在 src下 components 下的 Order.jsx中 的 handleOk编写代码如下

//对话框点击 确定 时触发const handleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.cancelorder(currentId).send({from: account})setIsModalOpen(false);};

这里 我们函数也写了注释了 他是只有用户点击确认之后才触发的 就表示 用户已经确定 要取消这个订单了
然后 我们通过我们存在window上的 WebData对象 拿到 交易所智能合约Exchange对象 和 account当前登录用户
然后通过Exchange 调用我们自己写的 取消订单 cancelorder函数 传入 我们之前存起来的 当前订单id currentId 然后 指定 send 因为 我们这个操作是要上链的
然后 我们传入当前用户为from 字段
然后 我们运行代码 点击取消订单
在这里插入图片描述
然后点击确定
在这里插入图片描述
然后 页面右侧 就会弹出这个操作提示按钮 因为这设计到了 燃料操作
在这里插入图片描述
我们直接点击确认
在这里插入图片描述
一路确认 最后完成之后 我们的数据并不会自动更新 因为我们没有订阅 但是 当你手动刷新界面 会发现 我们取消的那条 3ETH 的订单就没有了 因为已经被取消掉了
在这里插入图片描述
然后 我们也可以看MetaMask下面这个活动 会将你取消订单的动作记录下来
在这里插入图片描述
这样 就确认了 我们取消订单的功能 确实是好用的 然后 我们来看买入
我们先加上 逻辑层的一些控制对话框代码

//控制买入弹出开启
const [buy, setBuy] = useState(false);
//取消 或 关闭 对话框时触发
const buyCancel = () => {setBuy(false);
};
//对话框点击 确定 时触发
const buyleOk = () => {setIsModalOpen(false);
};
//点击买入订单时触发
const startBuying = (id) => {setBuy(true);setCurrentId(id);
}

在这里插入图片描述
然后 我们在元素层 加上 买入确定的对话框
在这里插入图片描述
这样 我们点击买入 提示弹窗就出来了
在这里插入图片描述
然后 我们交易所中 也写了一个 fillorder 函数 他也是 只需要一个参数id
通过id完成订单买入
在这里插入图片描述
这样 我们直接将 刚才写的 buyleOk 函数 改成这样就好了

//对话框点击 确定 时触发
const buyleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.fillorder(currentId).send({from: account})setBuy(false);
};

逻辑还是跟取消订单差不多 用户确定之后 从我们挂在 window上的WebData 对象中 结构出 当前用户和交易所合约对象
然后 我们通过交易所对象 调用fillorder函数 传入当前操作订单的id
他也会改变链上结构 要用send
当前用户为from字段

然后 我们运行代码
然后 我们记好 自己在交易所 ETH的数量 因为我们的grtoken存在燃料的概念 所以 可能有点额外扣除 我们就看ETH
然后 我们点击买入
在这里插入图片描述
然后我们选择确定
在这里插入图片描述
然后 界面右侧 会弹出操作提示 这里 我们点击确定
在这里插入图片描述
因为没有订阅 所以 我们界面并不会自动更新 但我们刷新界面 我们看三个点
当前用户 在交易所的 ETH 加了 0.01 然后 我们完成的订单多了一条 别人的订单 少了一条 还有就是 在交易所的 grToken 减少了
这就说明 我们操作成功了
在这里插入图片描述
最后 我们订单组件的代码是这样

import React, { useState } from 'react';import { Card, Col, Row ,Table,Button, Modal } from 'antd';
import {useSelector} from "react-redux"
import moment from "moment"function converTime(t){return moment(t*1000).format("YYYY/MM/DD")
}function convert(unit) {return window.WebData ? unit&&window.WebData.web3.utils.fromWei(unit, "ether") : ""
}function getRenderOrder(order,type) {if(!window.WebData) {return []}const account = window.WebData.account//收集起所有 已完成 或 已取消的数据idlet filterIds = [...order.Cancelorders,...order.Fillorders].map(item=>item.id)let makeorders = order.Allorders.filter(item=> !filterIds.includes(item.id))if (type === 1) {return makeorders.filter(item=>item.user === account)} else {return makeorders.filter(item=>item.user !== account)}
}export default function Order() {//控制对话框的 布尔值const [isModalOpen, setIsModalOpen] = useState(false);//记录当前正在操作的订单idconst [currentId, setCurrentId] = useState(null);//点击取消订单时触发const triggerCancellation = (id) => {setIsModalOpen(true);setCurrentId(id);}//对话框点击 确定 时触发const handleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.cancelorder(currentId).send({from: account})setIsModalOpen(false);};//取消 或 关闭 对话框时触发const handleCancel = () => {setIsModalOpen(false);};//控制买入弹出开启const [buy, setBuy] = useState(false);//取消 或 关闭 对话框时触发const buyCancel = () => {setBuy(false);};//对话框点击 确定 时触发const buyleOk = () => {const {account,Exchange} = window.WebData;Exchange.methods.fillorder(currentId).send({from: account})setBuy(false);};//点击买入订单时触发const startBuying = (id) => {setBuy(true);setCurrentId(id);}const order = useSelector(state => state.order)const columns = [{title: 'ETH',dataIndex: 'amountGive',render:(amountGive)=><b>{ convert(amountGive) }</b>,key: 'amountGive'},{title: 'GrToken',dataIndex: 'amountGet',render:(amountGet)=><b>{ convert(amountGet) }</b>,key: 'amountGet'},{title: '创建时间',dataIndex: 'timestamp',render:(timestamp)=><div>{ converTime(timestamp) }</div>,key: 'timestamp'},];const columns1 = [...columns,{title: '操作',render:(item)=><Button type = "text" onClick={()=>{triggerCancellation(item.id)}}>取消</Button>}]const columns2 = [...columns,{title: '操作',render:(item)=><Button type = "text" onClick={()=>{startBuying(item.id)}}>买入</Button>}]return (<div style = {{marginTop:'10px'}}><Row><Col span={8}><Card title="已完成" bordered={false} style = {{ margin: '10px' }}><Table dataSource={order.Fillorders} columns={columns} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="我创建的" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,1)} columns={columns1} rowKey={item=> item.id}/></Card></Col><Col span={8}><Card title="其他交易中订单" bordered={false} style = {{ margin: '10px' }}><Table dataSource={getRenderOrder(order,2)} columns={columns2} rowKey={item=> item.id}/></Card></Col></Row><Modaltitle="操作提示"open={isModalOpen}okText="确定"cancelText="取消"onOk={handleOk}onCancel={handleCancel}><p>您确定要取消当前订单吗?</p></Modal><Modaltitle="操作提示"open={buy}okText="确定"cancelText="取消"onOk={buyleOk}onCancel={buyCancel}><p>您确认要买入当前订单吗?</p></Modal></div>);
}

但是 目前体验比较差 因为我们操作完成 不会自动更新 需要手动刷新界面数据才会更新
因为 我们需要对这些事件进行订阅
那么 我们下文继续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/189216.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Yum配置、相关命令和常见问题

搭建光盘源 将系统盘读取出来&#xff0c;找到系统盘下存放软件包的目录 2.配置yun仓库 输入命令进入仓库编辑 #必须以.repo结尾 :wq 回车保存退出 3.命令行输入yum repolist 查看yum仓库 配置硬盘源 1.将硬盘源拷贝到目录&#xff0c;或者挂载到目录 2.指定repo文件baseu…

TCSVT(IEEE Transactions on Circuits and Systems for Video Technology)期刊投稿指南

目录 TCSVT 期刊简介 TCSVT 期刊影响因子和分区​ 期刊官方网站 期刊投稿网址 投稿指南网址 稿件格式要求 稿件提交指南 A. 提交稿件 B. 手稿格式 C. 摘要指南 D. 提交图形的指南 E. 页面和彩色图形费用 TCSVT 期刊简介 IEEE Transactions on Circuits and Systems…

No183.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

伦敦金股票代码是什么?

伦敦金是跟踪实时的现货黄金价格走势的差价合约交易&#xff0c;它的代码一般是LLG、GOLD&#xff0c;但也有一些货币交易平台会显示为XAU。伦敦金不是股票交易&#xff0c;因此没有四位数或六位数的股票代码&#xff0c;但伦敦金交易品种单一&#xff0c;投资者不用在数千支股…

深度学习之基于Pytorch框架的MNIST手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 MNIST是一个手写数字识别的数据集&#xff0c;是深度学习中最常用的数据集之一。基于Pytorch框架的MNIST手写数字识…

关于视频封装格式和视频编码格式的简介

文章目录 简介视频封装格式&#xff08;Video Container Format&#xff09;视频编码格式&#xff08;Video Compression Format&#xff09;两者关系总结webm 格式简介webm视频编码格式webm音频编码格式webm总结 简介 视频封装格式&#xff08;Video Container Format&#x…

思科9300交换机使用USB进行升级ISO

一、下载ISO 一、网址 Software Download - Cisco Systems 二、找到型号 四、选择XE 软件 五、进行下载 二、COPY 进 U盘 一、、请注意&#xff01;如果你的U盘不是Fat32文件格式则交换机读取不了&#xff0c;请先格式化再复制文件。 二、下载后将 bin文件复制到U盘。 1.扩展…

C 语言函数

C 语言函数 在本教程中&#xff0c;将向您介绍C语言编程中的函数&#xff08;用户定义函数和标准库函数&#xff09;。此外&#xff0c;您还将学习为什么在编程中使用函数。 函数是执行特定任务的代码块。 假设您需要创建程序来创建一个圆并为其着色。您可以创建两个函数来解…

Failed to connect to github.com port 443:connection timed out

解决办法&#xff1a; 步骤1&#xff1a; 在这里插入图片描述 步骤2&#xff1a; -步骤3 &#xff1a;在git终端中执行如下命令&#xff1a; git config --global http.proxy http:ip:port git config --global https.proxy http:ip:port git config --global http.proxy htt…

HTTP-FLV详解及分析

文章目录 前言一、HTTP-FLV 简介1、市场上使用 http-flv 的商家2、http-flv、rtmp 和 hls 直播的优缺点3、http-flv 技术实现 二、Nginx 配置 http-flv1、Windows 安装 nginx&#xff0c;已经集成 nginx-http-flv-module2、nginx.conf 配置文件3、运行 nginx 服务器4、ffmpeg 推…

【Redis】String字符串类型

上一篇&#xff1a;Redis-key的使用 https://blog.csdn.net/m0_67930426/article/details/134361821?spm1001 .2014.3001.5501 目录 appen (附加&#xff09; strlen(获取字符串的长度&#xff09; incr decr getRange(获取字符串&#xff09; setRange&#xff08;替…

浅析移动端车牌识别技术的工作原理及其过程

随着社会经济的发展与汽车的日益普及带来巨大的城市交通压力,在此背景下,智能交通系统成为解决这一问题的关键。而在提出发展无线智能交通系统后,作为智能交通的核心,车牌识别系统需要开始面对车牌识别移动化的现实需求。基于实现车牌识别移动化这一目标,一种基于Android移动终…

Python之函数进阶-函数执行原理

Python之函数进阶-函数执行原理 函数执行流程 C语言中&#xff0c;函数的活动和栈有关。栈是后进先出的数据结构。栈是由底端向顶端生长&#xff0c;栈顶加入数据成为压栈、入栈、栈顶弹出数据称为出栈。 def add(x, y):r x yprint(r)return rdef main():a 1r add(a, 2)r…

【python】sys-psth和模块搜索路径

我们在导入一个模块的时候&#xff0c;比如说&#xff1a; import math它必然是有搜索路径的&#xff0c;那到底是在哪个目录下面找呢&#xff1f;Python解释器去哪里找这个文件呢&#xff1f;只有找到这个文件才能读取、装载运行该模块文件。 它一般按照如下路径寻找模块文件…

暴力递归转动态规划(十五)

题目 给定一个正数n&#xff0c;求n的裂开方法数&#xff0c; 规定&#xff1a;后面的数不能比前面的数小 比如4的裂开方法有&#xff1a; 1111、112、13、22、04 。 5种&#xff0c;所以返回5 暴力递归 用暴力递归方法进行尝试&#xff0c;整体思路是这样&#xff1a; 暴力递…

最终前端后端小程序还有nginx配置

前端 前端 build 代码及其 放置位置 后端 nginx.conf 配置 user root;worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/nginx/mime.types;default_type a…

一文图解爬虫(spider)

—引导语 互联网&#xff08;Internet&#xff09;进化到今天&#xff0c;已然成为爬虫&#xff08;Spider&#xff09;编制的天下。从个体升级为组合、从组合联结为网络。因为有爬虫&#xff0c;我们可以更迅速地触达新鲜“网事”。 那么爬虫究竟如何工作的呢&#xff1f;允许…

【Java 进阶篇】Java 中 JQuery 对象和 JS 对象:区别与转换

在前端开发中&#xff0c;经常会涉及到 JavaScript&#xff08;JS&#xff09;和 jQuery 的使用。这两者都是前端开发中非常重要的工具&#xff0c;但它们之间存在一些区别。本文将详细介绍 Java 中的 JQuery 对象和 JS 对象的区别&#xff0c;并讨论它们之间的转换方法。 1. …

无需公网IP,贝锐花生壳内网穿透远程访问NAS

群晖DSM 7.0及以上版本 1.1 安装运行花生壳套件 &#xff08;1&#xff09;通过浏览器输入群晖NAS的内网地址&#xff0c;登录进去后&#xff0c;点击【套件中心】&#xff0c;搜索【花生壳】&#xff0c;并点击【安装套件】&#xff1b; &#xff08;2&#xff09; 勾选我接…

Linux服务器上搭建JupyterNotebook教程

搭建需知 1.确保是Linux服务器&#xff1b; 2.已经在linux服务器上安装好anaconda3&#xff1b; 搭建教程 请按照顺序依次执行下面的命令&#xff1a; 1、安装Jupyter Notebook 执行以下命令&#xff0c;安装jupyter notebook conda install jupyter【注】 如果anaconda3…