Abi*_*yal 1 ethereum solidity erc20
我通过在 ERC20.sol 文件中实现 OpenZeppelin 创建了一个基本的 ERC20 令牌,如下所示:
pragma solidity ^0.6.4;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC20/ERC20.sol";
contract Token is ERC20 {
constructor(string memory _name, string memory _symbol)
public
ERC20(_name, _symbol)
{
_mint(msg.sender, 10000000000000000000000000000);
}
}
Run Code Online (Sandbox Code Playgroud)
然后实现另一个合约Contract.sol,如下:
import "./ERC20.sol";
pragma solidity ^0.6.4;
contract SimpleBank{
Token tokenContract;
constructor(Token _tokenContract) public {
tokenContract = _tokenContract;
}
function deposit(uint amt) public returns (bool) {
require(amt != 0 , "deposit amount cannot be zero");
tokenContract.transfer(address(this),amt);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
因为,我已经从地址0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2部署了两个合约,所以它持有 10000000000000000000000000000 个代币。
但是当我deposit从同一地址调用函数时,出现以下错误:
交易到 SimpleBank.deposit 时出错:虚拟机错误:恢复。revert 事务已恢复到初始状态。合约给出的原因:“ERC20:转账金额超过余额”。调试事务以获取更多信息。
deploy那么,与已部署的 ERC20 代币交互以使该功能正常运行的正确方法是什么?
用户地址0xAb8483...发送一个执行SimpleBank函数的交易deposit(),这使得in0xAb8483...的值。msg.senderSimpleBank
然后SimpleBank发送一个内部事务来执行Token函数transfer()。这使得SimpleBank地址(而不是0xAb8483...)msg.sender成为in的值Token。
因此 SimpleBank 中的代码片段tokenContract.transfer(address(this),amt);正在尝试发送 的SimpleBank代币。不是用户的 ( 0xAb8483...) 令牌。
此代币转移(从第 2 点开始)会恢复,因为 SimpleBank 不拥有任何代币。这使得顶级事务(从第 1 点开始)也会恢复。
如果您希望SimpleBank能够转移 的0xAb8483...代币,0xAb8483...则需要approve()先将代币花掉SimpleBank。直接来自他们的地址,以便他们在合同msg.sender中Token。
然后SimpleBank才能执行transferFrom(0xAb8483..., address(this), amt)(from、to、amount)。
TLDR:你的合约不能花费它不拥有的代币,除非所有者手动批准你的合约花费它们。
如果它可以在未经批准的情况下花费别人的代币,那么就很容易从那些无法/不验证您的源代码的人那里窃取(通过花费他们的 USDT、WETH 和其他广泛使用的代币)。
| 归档时间: |
|
| 查看次数: |
3953 次 |
| 最近记录: |