委托转账原理分析:
假设:【A账号】有10000个token代币,【B账号】没有token代币,【C账号】也没有token代币
那么:【A账号】委托【B账号】转给【C账号】100个token代币,怎么来实现呢?
首先:【A账号】和【B账号】建立一种委托关联,登录【A账户】执行 approve(B, 100) 方法。
结果:_allowances[A][B] = 100token
然后:登录【B账户】执行 transferFrom(A, C, 100),这里的B就是委托账号发送者,gas从B扣,必须确保token数量小于_allowances[A][B]
总结:其实就是A转入C,但是要经过B的账号来发送交易
contract ERC20 {
using SafeMath for uint256;
mapping (address => uint256) internal _balances;
mapping (address => mapping (address => uint256)) internal _allowances;
// 委托转账,执行这个方法之前必须先执行approve建立委托关联数据加入_allowances中
function transferFrom(address from, address to, uint256 amount) public returns (bool) {
_transfer(from, to, amount);
uint256 currentAllowance = _allowances[from][msg.sender];
require(currentAllowance >= amount, "实际转账数量超过了委托数量");
_approve(from, msg.sender, currentAllowance - amount);
return true;
}
// 建立一种委托关联(这个方法也就是在maping对象_allowances中)
// 添加【需要发送token的人】和委托者【实际转账的人】之间的关系(后续的委托操作会查询这个maping中的数据记录)
function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
// 委托关联执行的逻辑
function _approve(address owner, address spender, uint256 value) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = value;
emit Approval(owner, spender, value);
}
// 转账交易执行的逻辑
function _transfer(address from, address to, uint256 value) internal {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
uint256 senderBalance = _balances[from];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[from] = senderBalance - value;
_balances[to] += value;
emit Transfer(from, to, value);
}
}