好 经过上文 Web3 solidity编写cancelorder取消订单函数 并梳理讲述逻辑 我们成功编写了 cancelorder 取消订单函数
其实 做了取消订单 填充订单 已经是非常简单的事了
我们还是先起来ganache 虚拟环境
这里 我们 模仿 orderCancel 在做一存储结构
//存储被填充订单
mapping(uint256=>bool) public orderFill;
在上面定义一个 mapping结构 用于存储 被填充订单
然后 除了 容器 还有一个事件
我们还是模仿之前 发布/取消订单的事件 来做一个 填充订单的事件
//记录填充订单
event Fill(uint256 id,address user,address tokenGet,uint256 amountGet,address tokenGive,uint256 amountGive,uint256 timestamp);
然后 我们可以直接把删除订单的代码拿过来
然后改一下 变成这样
//填充订单 方法接受一个参数 订单id 代理名叫 _id
function fillorder(uint256 _id) public {
//根据传进来的订单id 获取到当前订单的对象
_Order memory myorder = orders[_id];
//判断id有没有取错
require(myorder.id == _id);
//将填充的数据的id 存入orderFill 值赋值为 true 表示已经填充
orderFill[_id] = true;
//最后 调用函数记录一下填充订单的事件
emit Fill(myorder.id,msg.sender,myorder.tokenGet,myorder.amountGet,myorder.tokenGive,
myorder.amountGive,block.timestamp);
}
可以看到 我们目前替换的地方 方法名 改成了 fillorder
然后 存储的容器 使用了我们刚刚定义的orderFill
然后 记录事件也改成了我们刚刚的 Fill
但是 这里还有个问题 就是 msg.sender
这个东西 拿到的是当前操作这个事件的对象 像我们 之前 发布和取消订单 可以 你用 msg.sender 因为 msg.sender对象代表的就是订单的创建者
但是 你调用填充订单 操作人 基本不可能是创建订单的人呀是不是
所以这里你用 msg.sender 肯定是有问题的 但放过来想 被调用填充订单 说明订单已经有了 那我们直接拿它原来的不就行了吗?
是不是
我们直接改成
myorder.user
但是 问题显然不止这一个 你没有真的进行交换呀 你不交换 这叫什么订单呀?
而 我们交易所 也可以从中获取一些燃料 这也是交易所价值所在了
这里 我们将fillorder 填充订单代码更改如下
//填充订单 方法接受一个参数 订单id 代理名叫 _id
function fillorder(uint256 _id) public {
//根据传进来的订单id 获取到当前订单的对象
_Order memory myorder = orders[_id];
//判断id有没有取错
require(myorder.id == _id);
//将填充的数据的id 存入orderFill 值赋值为 true 表示已经填充
orderFill[_id] = true;
//fuelConsumption 获取消耗的燃料 比如 100转换 就 100 乘以 feePercent 再除以 100
uint256 fuelConsumption = myorder.amountGet.mul(feePercent).div(100);
/*
通过msg.sender拿到当前操作用户 去掉amountGet指定的tokenGet
加上我们计算出的燃料fuelConsumption 也要从这里去减
这里我们设计的燃料由交易订单的人承担 你们也可设计为发布订单的人承担
这个具体要看怎么设计逻辑
*/
tokens[myorder.tokenGet][msg.sender] = tokens[myorder.tokenGet][msg.sender].sub(myorder.amountGet.add(fuelConsumption));
//定订单的发起者 加上amountGet指定的 tokenGet
tokens[myorder.tokenGet][myorder.user] = tokens[myorder.tokenGet][myorder.user].add(myorder.amountGet);
//通过msg.sender拿到当前操作用户 加上指定的 tokenGive
tokens[myorder.tokenGive][msg.sender] = tokens[myorder.tokenGive][msg.sender].add(myorder.amountGive);
//定订单的发起者 去掉tokenGive指定的amountGive
tokens[myorder.tokenGive][myorder.user] = tokens[myorder.tokenGive][myorder.user].sub(myorder.amountGive);
//feeAccout我们初始化交易所时就会传进来 代表收一收获益的账号 把燃料fuelConsumption加进来
tokens[myorder.tokenGet][feeAccout] = tokens[myorder.tokenGet][feeAccout].add(fuelConsumption);
//最后 调用函数记录一下填充订单的事件
emit Fill(myorder.id,myorder.user,myorder.tokenGet,myorder.amountGet,myorder.tokenGive,
myorder.amountGive,block.timestamp);
}
我们主要是加了中间处理的逻辑
我自认为自己的注释写的挺好的
还是带着大家来读一下
首先 我们这里
我们定义了一个数字类型的 fuelConsumption
他是我们定义的燃料消耗 这里 我们拿到 myorder.amountGet
就是当前订单定义的消耗token
例如 我们这个订单是 100自己定义的token 转 1E
那么 这里指定的 就是 自己定义的token
然后 用它 调用mul 乘以 我们的feePercent
这个不知道大家还是否记得 之前我带大家创建交易所时 就定义了这个构造函数
他存储的就是我们的汇率
然后 在 div 除以 100
加上 我们是 100GRTOKEN 对 1E 交易所汇率 3
那么 这个逻辑就是 fuelConsumption = 100 乘以 3 除以 100
就是3 直接百分之三 这样看着 其实多少还是有点坑爹啊
然后 当前填充订单的 除了承担当前订单的值还要承担燃料 这个是发起订单的人还是 填充订单的人承担 是看我们具体自己怎么设计 大家喜欢发起订单的人自己去承担 也是没问题的
最后 feeAccout 这个我不知道大家还是否记得 他也是我们设计在构造函数中的
你们也可以理解为它指向的就是 交易所控制或发布者的账号指向
我们将燃料add给它
这些都还是在交易所的
但大大家别忘了 我们写过
这样 我们填充订单的方法就写好了
然后我们编译一下
也是没有任何问题