Web3 叙述交易所授权置换概念 编写transferFrom与approve函数

前文
Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约
中 我们通过ERC-20一种开发者设计的不成文规定 也将我们的代币开发的很像个样子了
我们打开 ERC-20文档
我们transfer后面的函数就是transferFrom
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第1张图片
这个也是 一个账号 from 发送给另一个账号 to 数量 value
他是一个不成文规定
transfer取的是 msg.sender 意思是 谁操作触发了这个函数 from 就代表谁

而 transferFrom 则是 我们之后交易所来调用的
也就说是 你授权的交易所 就会有能力通过调用 transferFrom 转走你授权数量的代币
所有授权 相对来说还是个较为危险的操作
那么 也就是说 approve 是调用transferFrom的基础 你要先授权
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第2张图片
approve方法的话 你可以授权多个机构 例如 你的代币 10000 你可以授权 A机构 3000 B机构 3000
C机构 3000 但当你操作授权后真的会有这么多代币进入 A B C机构中 不然别人怎么用呢?
被授权后他就有这个额度的使用权
你也可以 简单理解为 我们分配给银行 你可以自己留在手里 或者 放在银行里
例如 给ABC银行各3000代币,都是一年定期,在这个期间中 银行对你的代币是有一个支配权的。在这一年中你的代币怎么被流通,你是不知道的,反正到最后能把钱取出来就完事了。
然后,之前被我们比作银行的交易所,他们就会发布订单,例如 你愿意用 1000GRtoken 换 1 ETH吗?
如果此时 我们操作愿意
这里 就像买一个商品一样,此时 A交易所的代币就会少一千,但你的账号就会多1ETH

所以 之后 我们就要用 模拟出来的区块链环境账号 分配给 ABC三个交易所 一定数量的代币 然后 在ABC交易所中就会有对应的订单池
在这个池子中 就会有别人创建的订单
你就可以看合不合适 如果合适 就直接下单

当然 这一块 光看描述 确实换谁来了都没那么好理解
还是先通过代码 将方法创建好

这里这个approve函数 我们直接整个复制过来
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第3张图片
直接放到我们自己的这个代币合约上去
函数的一个专属花括号 我们还是得自己加一下
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第4张图片
这个方法 有三个重要的值
第一个是 msg.sender 这个要取当前登录的用户
这个参数 代表当前登录的用户 因为 肯定要用户来和交易所授权给定代币
然后 就是这个函数中的两个参数 _spender 交易所的地址 _value 给定授权的代币数量

但 approve中还需要像一个 js对象一样的数据结构
例如这样

{
    a机构: 300,
    b机构: 400
}

机构对应授权代表数量
但在solidity中对象显然不是这样的

我们先要定义一个对象

mapping(address => mapping(address=>uint256)) public allowance;

这里 我们定义 一个 mapping 对象 键对应的值 又是一个对象类型 然后 这里面这个对象 键对应的值 是一个uint256数字类型的 然后 public 表示这是一个公共的 变量名叫 allowance
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第5张图片
然后 我们编写approve方法如下

function approve(address _spender, uint256 _value) public returns (bool success) {
     require(_spender!=address(0));
    allowance[msg.sender][_spender] = _value;

    return true;
}

这里 我们先用require判断_spender 交易所的地址是否有问题 当然这里只是个很弱的判断
address(0) 就类似于 null只是这个类型的 空 相当于这是个非空的格式判断
然后 在我们刚刚创建的allowance 下键为msg.sender下的键为_spender的值 复制微 对应 value
例如 当前登录的账号是 t1 在allowance 下找到键等于t1 下的一个对象 然后在这个对象中找到 和操作的交易所相同的键 将value赋值上去

数据结果或许可以理解为这样

{
    t1用户: {
        A交易所: 1000
    }
}

当然这是一个js的展现形式 方便大家理解
然后 返回了一个ture 因为 这个函数设置了returns (bool success) 要求返回一个布尔类型的值

这里需要强调一下require的好处 除了会将错误日志记录在区块链的日志中
还可以规避燃料费无故消耗
如果中间错误 你用的require 执行不成功 燃料费会退回

approve在官方文档中介绍 还要触发一个Approval事件
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第6张图片
我们直接整个复制到自己的合约上
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第7张图片
直接在approve函数中 返回true之前 调用一下

emit Approval(msg.sender,_spender,_value);

Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第8张图片
这里 我们传入 当前账号 交易所地址 数量

好啦 那么 approve这个授权的方法都写好了 那么 自然我们前面说的 transferFrom 就可以开始了
先从文档中拿过来
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第9张图片
花括号自己加一下

这个方法是被授权的交易所来调用的
而 这里三个参数 _from 付款账号 _to 收款账号 _value 数量
而在这个方法中 msg.sender拿到的是调用这个方法的交易所地址

但是这里有个问题 我们要将transfer改一下
我们改成
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第10张图片
这里 我们直接将transfer原本的逻辑 抽离成一个_transfer函数
这样方便外界调用

这样 我们就可以这样写 transferFrom

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value);
    _transfer(_from,_to,_value);
    return true;
}

这里 我们现在allowance中 找到 付款账号对应对象下的 交易所对应下的值的 value 调用sub将他减去
然后 我们两个账号之间的转入 我们直接用刚刚拆出来的 _transfer 就好了
因为 如果你不拆
原本那种用msg.sender的
msg.sender拿到的不是 付款账号 而是交易所地址 因为transferFrom是交易所调用的 然后 transferFrom中调用的_transfer 所有 你如果取msg.sender 取到的是交易所

当然 这前面还是得加个判断 如果你授权给交易所的代币都不大于value 那么 交易肯定是没办法执行的
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第11张图片
我们在合约中写的这两个对象 可以理解为 他们是一个变量 但其实 在去中心化的区块链中 他们就是数据库存储 他们将数据挂到了区块链上
Web3 叙述交易所授权置换概念 编写transferFrom与approve函数_第12张图片
且这种数据也不能随意更改 公开透明的

你可能感兴趣的:(区块链)