我刚找到一份合同。复制和改编。它正是我想要的。每笔交易的 1% 将被转发到捐赠钱包。但奇怪的是,每笔交易的代币总供应量增加了 1%。我一直在疯狂地浏览代码,我真的只是一个初学者,如果你能提供帮助将非常高兴。
这是一个问题的例子:
https://goerli.etherscan.io/token/tokenholderchart/0xfdb5cac9f9de78596f59959b9b743540b0c29a42
代码如下:
contract CoinToken is Context, IBEP20, Ownable {
using SafeMath for uint256;
using Address for address;
mapping (address => uint256) private _rOwned;
mapping (address => uint256) private _tOwned;
mapping (address => mapping (address => uint256)) private _allowances;
mapping (address => bool) private _isExcluded;
mapping (address => bool) private _isCharity;
address[] private _excluded;
string private _NAME;
string private _SYMBOL;
uint256 private _DECIMALS;
address public FeeAddress;
uint256 private _MAX = ~uint256(0);
uint256 private _DECIMALFACTOR;
uint256 private _GRANULARITY = 100;
uint256 private _tTotal;
uint256 private _rTotal;
uint256 private _tCharityTotal;
uint256 public _CHARITY_FEE;
// Track original fees to bypass fees for charity account
uint256 private ORIG_CHARITY_FEE;
constructor (string memory _name, string memory _symbol, uint256 _decimals, uint256 _supply, uint256 _charityFee,address _FeeAddress,address tokenOwner) {
_NAME = _name;
_SYMBOL = _symbol;
_DECIMALS = _decimals;
_DECIMALFACTOR = 10 ** uint256(_DECIMALS);
_tTotal =_supply * _DECIMALFACTOR;
_rTotal = (_MAX - (_MAX % _tTotal));
_CHARITY_FEE = _charityFee* 100;
ORIG_CHARITY_FEE = _CHARITY_FEE;
_isCharity[_FeeAddress] = true;
FeeAddress = _FeeAddress;
_owner = tokenOwner;
_rOwned[tokenOwner] = _rTotal;
emit Transfer(address(0),tokenOwner, _tTotal);
}
function name() public view returns (string memory) {
return _NAME;
}
function symbol() public view returns (string memory) {
return _SYMBOL;
}
function decimals() public view returns (uint256) {
return _DECIMALS;
}
function totalSupply() public view override returns (uint256) {
return _tTotal;
}
function balanceOf(address account) public view override returns (uint256) {
if (_isExcluded[account]) return _tOwned[account];
return tokenFromReflection(_rOwned[account]);
}
function transfer(address recipient, uint256 amount) public override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "TOKEN20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "TOKEN20: decreased allowance below zero"));
return true;
}
function isExcluded(address account) public view returns (bool) {
return _isExcluded[account];
}
function isCharity(address account) public view returns (bool) {
return _isCharity[account];
}
function totalCharity() public view returns (uint256) {
return _tCharityTotal;
}
function deliver(uint256 tAmount) public {
address sender = _msgSender();
require(!_isExcluded[sender], "Excluded addresses cannot call this function");
(uint256 rAmount,,,) = _getValues(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_rTotal = _rTotal.sub(rAmount);
}
function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
require(tAmount <= _tTotal, "Amount must be less than supply");
if (!deductTransferFee) {
(uint256 rAmount,,,) = _getValues(tAmount);
return rAmount;
} else {
(,uint256 rTransferAmount,,) = _getValues(tAmount);
return rTransferAmount;
}
}
function tokenFromReflection(uint256 rAmount) public view returns(uint256) {
require(rAmount <= _rTotal, "Amount must be less than total reflections");
uint256 currentRate = _getRate();
return rAmount.div(currentRate);
}
function excludeAccount(address account) external onlyOwner() {
require(!_isExcluded[account], "Account is already excluded");
if(_rOwned[account] > 0) {
_tOwned[account] = tokenFromReflection(_rOwned[account]);
}
_isExcluded[account] = true;
_excluded.push(account);
}
function includeAccount(address account) external onlyOwner() {
require(_isExcluded[account], "Account is already excluded");
for (uint256 i = 0; i < _excluded.length; i++) {
if (_excluded[i] == account) {
_excluded[i] = _excluded[_excluded.length - 1];
_tOwned[account] = 0;
_isExcluded[account] = false;
_excluded.pop();
break;
}
}
}
function setAsCharityAccount(address account) external onlyOwner() {
require(!_isCharity[account], "Account is already charity account");
_isCharity[account] = true;
FeeAddress = account;
}
function updateFee(uint256 _charityFee) onlyOwner() public{
_CHARITY_FEE = _charityFee* 100;
ORIG_CHARITY_FEE = _CHARITY_FEE;
}
function mint(address account, uint256 amount) onlyOwner() public {
_tTotal = _tTotal.add(amount);
_rOwned[account] = _rOwned[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _approve(address owner, address spender, uint256 amount) private {
require(owner != address(0), "TOKEN20: approve from the zero address");
require(spender != address(0), "TOKEN20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _transfer(address sender, address recipient, uint256 amount) private {
require(sender != address(0), "TOKEN20: transfer from the zero address");
require(recipient != address(0), "TOKEN20: transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
// Remove fees for transfers to and from charity account or to excluded account
bool takeFee = true;
if (_isCharity[sender] || _isCharity[recipient] || _isExcluded[recipient]) {
takeFee = false;
}
if (!takeFee) removeAllFee();
if (_isExcluded[sender] && !_isExcluded[recipient]) {
_transferFromExcluded(sender, recipient, amount);
} else if (!_isExcluded[sender] && _isExcluded[recipient]) {
_transferToExcluded(sender, recipient, amount);
} else if (!_isExcluded[sender] && !_isExcluded[recipient]) {
_transferStandard(sender, recipient, amount);
} else if (_isExcluded[sender] && _isExcluded[recipient]) {
_transferBothExcluded(sender, recipient, amount);
} else {
_transferStandard(sender, recipient, amount);
}
if (!takeFee) restoreAllFee();
}
function _transferStandard(address sender, address recipient, uint256 tAmount) private {
uint256 currentRate = _getRate();
(uint256 rAmount, uint256 rTransferAmount, uint256 tTransferAmount, uint256 tCharity) = _getValues(tAmount);
uint256 rCharity = tCharity.mul(currentRate);
_standardTransferContent(sender, recipient, rAmount, rTransferAmount);
_sendToCharity(tCharity, sender);
_reflectFee(rCharity,tCharity);
emit Transfer(sender, recipient, tTransferAmount);
}
function _standardTransferContent(address sender, address recipient, uint256 rAmount, uint256 rTransferAmount) private {
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
}
function _transferToExcluded(address sender, address recipient, uint256 tAmount) private {
uint256 currentRate = _getRate();
(uint256 rAmount, uint256 rTransferAmount, uint256 tTransferAmount, uint256 tCharity) = _getValues(tAmount);
uint256 rCharity = tCharity.mul(currentRate);
_excludedFromTransferContent(sender, recipient, tTransferAmount, rAmount, rTransferAmount);
_sendToCharity(tCharity, sender);
_reflectFee(rCharity, tCharity);
emit Transfer(sender, recipient, tTransferAmount);
}
function _excludedFromTransferContent(address sender, address recipient, uint256 tTransferAmount, uint256 rAmount, uint256 rTransferAmount) private {
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
}
function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private {
uint256 currentRate = _getRate();
(uint256 rAmount, uint256 rTransferAmount, uint256 tTransferAmount, uint256 tCharity) = _getValues(tAmount);
uint256 rCharity = tCharity.mul(currentRate);
_excludedToTransferContent(sender, recipient, tAmount, rAmount, rTransferAmount);
_sendToCharity(tCharity, sender);
_reflectFee(rCharity,tCharity);
emit Transfer(sender, recipient, tTransferAmount);
}
function _excludedToTransferContent(address sender, address recipient, uint256 tAmount, uint256 rAmount, uint256 rTransferAmount) private {
_tOwned[sender] = _tOwned[sender].sub(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
}
function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private {
uint256 currentRate = _getRate();
(uint256 rAmount, uint256 rTransferAmount, uint256 tTransferAmount,uint256 tCharity) = _getValues(tAmount);
uint256 rCharity = tCharity.mul(currentRate);
_bothTransferContent(sender, recipient, tAmount, rAmount, tTransferAmount, rTransferAmount);
_sendToCharity(tCharity, sender);
_reflectFee(rCharity, tCharity);
emit Transfer(sender, recipient, tTransferAmount);
}
function _bothTransferContent(address sender, address recipient, uint256 tAmount, uint256 rAmount, uint256 tTransferAmount, uint256 rTransferAmount) private {
_tOwned[sender] = _tOwned[sender].sub(tAmount);
_rOwned[sender] = _rOwned[sender].sub(rAmount);
_tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
_rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
}
function _reflectFee(uint256 rCharity, uint256 tCharity) private {
_rTotal = _rTotal.sub(rCharity);
_tCharityTotal = _tCharityTotal.add(tCharity);
}
function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256) {
(uint256 tCharity) = _getTBasics(tAmount,_CHARITY_FEE);
uint256 tTransferAmount = getTTransferAmount(tAmount, tCharity);
uint256 currentRate = _getRate();
(uint256 rAmount) = _getRBasics(tAmount, currentRate);
uint256 rTransferAmount = _getRTransferAmount(rAmount, tCharity, currentRate);
return (rAmount, rTransferAmount, tTransferAmount, tCharity);
}
function _getTBasics(uint256 tAmount, uint256 charityFee) private view returns (uint256) {
uint256 tCharity = ((tAmount.mul(charityFee)).div(_GRANULARITY)).div(100);
return (tCharity);
}
function getTTransferAmount(uint256 tAmount, uint256 tCharity) private pure returns (uint256) {
return tAmount.sub(tCharity);
}
function _getRBasics(uint256 tAmount, uint256 currentRate) private pure returns (uint256) {
uint256 rAmount = tAmount.mul(currentRate);
return (rAmount);
}
function _getRTransferAmount(uint256 rAmount, uint256 tCharity, uint256 currentRate) private pure returns (uint256) {
uint256 rCharity = tCharity.mul(currentRate);
uint256 rTransferAmount = rAmount.sub(rCharity);
return rTransferAmount;
}
function _getRate() private view returns(uint256) {
(uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
return rSupply.div(tSupply);
}
function _getCurrentSupply() private view returns(uint256, uint256) {
uint256 rSupply = _rTotal;
uint256 tSupply = _tTotal;
for (uint256 i = 0; i < _excluded.length; i++) {
if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal);
rSupply = rSupply.sub(_rOwned[_excluded[i]]);
tSupply = tSupply.sub(_tOwned[_excluded[i]]);
}
if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
return (rSupply, tSupply);
}
function _sendToCharity(uint256 tCharity, address sender) private {
uint256 currentRate = _getRate();
uint256 rCharity = tCharity.mul(currentRate);
_rOwned[FeeAddress] = _rOwned[FeeAddress].add(rCharity);
_tOwned[FeeAddress] = _tOwned[FeeAddress].add(tCharity);
emit Transfer(sender, FeeAddress, tCharity);
}
function removeAllFee() private {
if(_CHARITY_FEE == 0) return;
ORIG_CHARITY_FEE = _CHARITY_FEE;
_CHARITY_FEE = 0;
}
function restoreAllFee() private {
_CHARITY_FEE = ORIG_CHARITY_FEE;
}
}