史上最も完全なスマートコントラクト - 税金控除、配当、プール追加、リフロー、ブラックリストとホワイトリスト、ボット対策、追加発行、権限喪失に対する配当、プール追加

前章ではスマートコントラクトの税控除の原理と税控除を実現する方法について説明しましたが、次の記事ではプールに自動配当を追加する方法と注意点について説明します。
早速、最初にコードに進みましょう。

//feihongpool这个变量是指预留在合约中的预分红的币的数量。_maxfeihong这个变量是指预留在合约的币达到什么样的数量之后分红。
if(fenhongpool>=_maxfenhong ){
    
    
  //这个例子是对所有的lp分红,那么,在fenhongpool变量之后,为什么要多乘以一个10的18次方呢,这里要特别说明一下,如果lp总的有1万个,fenhongpool是200个,那么,如果除了之后,就变成一个小于1的值了,在solidity中,不支持小数点,所以,如果不乘以一个比较大的参数,会导致分红失败,这个本人失败过几次,得出来的经验。
  uint256 tmp=fenhongpool.mul(10**18).div(ERC20(pooladdress).totalSupply());
  //分了之后,将分红池置空。然后在fenhongdetail内push当次分红的具体数量。这里特别说明一下,因为除了数据之后,肯定会有精度的问题,这个要自己心里弄清楚。fenhongdetail是一个初始化为0的数组。当每次分红之后,将每个lp分红的数额记录在这里。
  fenhongpool=0;
  fenhongdetail.push(tmp);
}

//当用户发生转帐或者加撤池子的时候,首先取出来该钱包地址,拥有的lp数量大于0,并且没有被初始化,这里用的是isinclude[sender]==false来判断的,如果是第一次,那么初始化用户开始分红的时间节点,就是将feihongdetail的长度赋值给userfeihong[sender]
if(lpvalue>0 && isinclude[sender]==false){
    
    
 //    includelp.push(sender);
      isinclude[sender]=true;
      userfeihong[sender]=feihongdetail.length-1;
  }
//当触发发分发条件,那么从用户未分红的lp开始,将用户该分的币值计算出来,并分给用户,然后userfenhong[sender]=fenhongdetail.length-1,修改用户的分红时间节点。达到合约内自动分红的目的。
if(userfenhong[sender]<feihongdetail.length-1){
    
    
   for(uint256 i=userfenhong[sender]+1;i<fenhongdetail.length;i++){
    
    
           tmp=fenhongdetail[i]*lpvalue;
    }
    _balances[sender]=_balances[sender].add(tmp);
    userfenhong[sender]=fenhongdetail.length-1;
 }

配当金は、比較的理解しやすい単純なデータ手法のみを使用していますが、インターネット上の地犬契約とは異なり、高度な手法が多く用いられており、理解できない学生も多いと思います。他人のオープンソース契約に基づいて変更するだけでも、多くの間違いを引き起こす可能性があります。
次に、プールの追加の問題を変更してみましょう (ここには多くの落とし穴があります。本当に理解できない場合は、Web サイトでプライベート メッセージを送信するか、V:54516204 を追加して通信できます)。
プールを追加するためのコードは他にもありますが、比較的単純です。

//下面这两个接口,是必须要引入的,至于每个函数有什么用,那就靠自己百度了,我这里就不做过多的讲解了。
 interface IUniswapV2Router01 {
    
    
     function factory() external pure returns (address);
     function WETH() external pure returns (address);
 
     function addLiquidity(
         address tokenA,
         address tokenB,
         uint amountADesired,
         uint amountBDesired,
         uint amountAMin,
         uint amountBMin,
         address to,
         uint deadline
     ) external returns (uint amountA, uint amountB, uint liquidity);
     function addLiquidityETH(
         address token,
         uint amountTokenDesired,
         uint amountTokenMin,
         uint amountETHMin,
         address to,
         uint deadline
     ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
     function removeLiquidity(
         address tokenA,
         address tokenB,
         uint liquidity,
         uint amountAMin,
         uint amountBMin,
         address to,
         uint deadline
     ) external returns (uint amountA, uint amountB);
     function removeLiquidityETH(
         address token,
         uint liquidity,
         uint amountTokenMin,
         uint amountETHMin,
         address to,
         uint deadline
     ) external returns (uint amountToken, uint amountETH);
     function removeLiquidityWithPermit(
         address tokenA,
         address tokenB,
         uint liquidity,
         uint amountAMin,
         uint amountBMin,
         address to,
         uint deadline,
         bool approveMax, uint8 v, bytes32 r, bytes32 s
     ) external returns (uint amountA, uint amountB);
     function removeLiquidityETHWithPermit(
         address token,
         uint liquidity,
         uint amountTokenMin,
         uint amountETHMin,
         address to,
         uint deadline,
         bool approveMax, uint8 v, bytes32 r, bytes32 s
     ) external returns (uint amountToken, uint amountETH);
     function swapExactTokensForTokens(
         uint amountIn,
         uint amountOutMin,
         address[] calldata path,
         address to,
         uint deadline
     ) external returns (uint[] memory amounts);
     function swapTokensForExactTokens(
         uint amountOut,
         uint amountInMax,
         address[] calldata path,
         address to,
         uint deadline
     ) external returns (uint[] memory amounts);
     function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
     external
     payable
     returns (uint[] memory amounts);
     function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
     external
     returns (uint[] memory amounts);
     function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
     external
     returns (uint[] memory amounts);
     function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
     external
     payable
     returns (uint[] memory amounts);
 
     function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
     function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
     function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
     function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
     function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
 }
 

 interface IUniswapV2Router02 is IUniswapV2Router01 {
    
    
     function removeLiquidityETHSupportingFeeOnTransferTokens(
         address token,
         uint liquidity,
         uint amountTokenMin,
         uint amountETHMin,
         address to,
         uint deadline
     ) external returns (uint amountETH);
     function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
         address token,
         uint liquidity,
         uint amountTokenMin,
         uint amountETHMin,
         address to,
         uint deadline,
         bool approveMax, uint8 v, bytes32 r, bytes32 s
     ) external returns (uint amountETH);
 
     function swapExactTokensForTokensSupportingFeeOnTransferTokens(
         uint amountIn,
         uint amountOutMin,
         address[] calldata path,
         address to,
         uint deadline
     ) external;
     function swapExactETHForTokensSupportingFeeOnTransferTokens(
         uint amountOutMin,
         address[] calldata path,
         address to,
         uint deadline
     ) external payable;
     function swapExactTokensForETHSupportingFeeOnTransferTokens(
         uint amountIn,
         uint amountOutMin,
         address[] calldata path,
         address to,
         uint deadline
     ) external;
 }

以下がポイントです。
// コンストラクターで、次の変数を構築します。
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
uniswapV2Router = _uniswapV2Router;

//变量就不具体讲了,只讲重要的函数。
  function swapAndLiquify(uint256 contractTokenBalance) private lockTheSwap {
    
    

        uint256 marketingTokenBalance = contractTokenBalance.div(2);
        uint256 liquidityTokenBalance = contractTokenBalance.sub(marketingTokenBalance);
        uint256 tokenBalanceToLiquifyAsBNB = liquidityTokenBalance.div(2);
        uint256 tokenBalanceToLiquify = liquidityTokenBalance.sub(tokenBalanceToLiquifyAsBNB);

        uint256 initialBalance = address(this).balance;
        uint256 tokensToSwapToBNB = tokenBalanceToLiquifyAsBNB.add(marketingTokenBalance);

        // swap tokens for BNB
        //注释见下面。
        swapTokensForEth(tokensToSwapToBNB);

       
        uint256 bnbSwapped = address(this).balance.sub(initialBalance);
        uint256 bnbToLiquify = bnbSwapped.div(3);

		//注释见下面
        addLiquidity(tokenBalanceToLiquify, bnbToLiquify);

        emit SwapAndLiquify(tokenBalanceToLiquifyAsBNB, bnbToLiquify, tokenBalanceToLiquify);
        uint256 marketingBNBToDonate = bnbSwapped.sub(bnbToLiquify);
        huiliuad.transfer(marketingBNBToDonate);
        emit DonateToMarketing(marketingBNBToDonate);
    }
    function swapTokensForEth(uint256 tokenAmount) private {
    
    
        // 初始化交易的币对。
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();
		//授权,这个授权,是将本合约或者叫本币的数量,授权给交易接口。
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // 调用接口用币兑换eth.第一个参数是兑换的数量,第二个参数是预期要兑换的数量,如果小于这个数量,则兑换失败,所以这里写0,第三个是交易的币对,第四个是兑换的eth转入的地址,第五个,限定的过期日期。
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }
	//这个是加池子函数。
    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
    
    
        // approve token transfer to cover all possible scenarios
        //同样是授权,不多赘述。
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // 直接加池子。
        uniswapV2Router.addLiquidityETH{
    
    value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            huiliuad,
            block.timestamp
        );
    }

おすすめ

転載: blog.csdn.net/weixin_38532278/article/details/127533357