区块链阿凡达泰山众筹商城系统开发(正式版)丨区块链阿凡达泰山众筹商城开发源码系统

简介: “新零售”的核心要义在于推动线上与线下的一体化进程,其关键在于使线上的互联网力量和线下的实体店终端形成真正意义上的合力,从而完成电商平台和实体零售店面在商业维度上的优化升级。同时,促成价格消费时代向价值消费时代的全面转型。

  “新零售”的核心要义在于推动线上与线下的一体化进程,其关键在于使线上的互联网力量和线下的实体店终端形成真正意义上的合力,从而完成电商平台和实体零售店面在商业维度上的优化升级。同时,促成价格消费时代向价值消费时代的全面转型。

  pragma solidity=0.5.16;

  import'./interfaces/IUniswapV2Pair.sol';

  import'./UniswapV2ERC20.sol';

  import'./libraries/Math.sol';

  import'./libraries/UQ112x112.sol';

  import'./interfaces/IERC20.sol';

  import'./interfaces/IUniswapV2Factory.sol';

  import'./interfaces/IUniswapV2Callee.sol';

  contract UniswapV2Pair is IUniswapV2Pair,UniswapV2ERC20{

  using SafeMath for uint;

  using UQ112x112 for uint224;

  //最低流动性

  uint public constant MINIMUM_LIQUIDITY=10**3;

  //获取transfer方法的bytecode前四个字节

  bytes4 private constant SELECTOR=bytes4(keccak256(bytes('transfer(address,uint256)')));

  address public factory;

  address public token0;

  address public token1;

  uint112 private reserve0;//uses single storage slot,accessible via getReserves==使用单个存储槽,可通过getReserves访问

  uint112 private reserve1;//uses single storage slot,accessible via getReserves

  uint32 private blockTimestampLast;//uses single storage slot,accessible via getReserves

  uint public price0CumulativeLast;//最后价格累计的0价格?

  uint public price1CumulativeLast;
  //紧接最近一次流动性事件之后

  uint public kLast;//reserve0*reserve1,as of immediately after the most recent liquidity event

  uint private unlocked=1;

  //防止递归迭代出现问题,所以要上锁

  //一个锁,使用该modifier的函数在unlocked==1时才可以进入,

  //第一个调用者进入后,会将unlocked置为0,此使第二个调用者无法再进入

  //执行完_部分的代码后,才会再将unlocked置1,重新将锁打开

  modifier lock(){

  require(unlocked==1,'UniswapV2:LOCKED');

  unlocked=0;

  _;

  unlocked=1;

  }

  //获取储备:返回:_reserve0,_reserve1,_blockTimestampLast

  //用于获取两个token在池子中的数量和最后更新的时间

  function getReserves()public view returns(uint112 _reserve0,uint112 _reserve1,uint32 _blockTimestampLast){

  _reserve0=reserve0;

  _reserve1=reserve1;

  //时间戳

  _blockTimestampLast=blockTimestampLast;

  }

  //转账,安全校验

  function _safeTransfer(address token,address to,uint value)private{

  //调用transfer方法,把地址token中的value个coin转账给to

  (bool success,bytes memory data)=token.call(abi.encodeWithSelector(SELECTOR,to,value));

  //检查返回值,必须成功否则报错

  require(success&&(data.length==0||abi.decode(data,(bool))),'UniswapV2:TRANSFER_FAILED');

  }

  event Mint(address indexed sender,uint amount0,uint amount1);

  event Burn(address indexed sender,uint amount0,uint amount1,address indexed to);

  event Swap(address indexed sender,uint amount0In,uint amount1In,uint amount0Out,uint amount1Out,address indexed to);

  event Sync(uint112 reserve0,uint112 reserve1);

  //部署此合约时将msg.sender设置为factory,后续初始化时会用到这个值

  constructor()public{

  factory=msg.sender;

  }

  //called once by the factory at time of deployment

  //在UniswapV2Factory.sol的createPair中调用过

  function initialize(address _token0,address _token1)external{

  require(msg.sender==factory,'UniswapV2:FORBIDDEN');//sufficient check

  token0=_token0;

  token1=_token1;

  }

  //update reserves and,on the first call per block,price accumulators

  //更新储备,并在每个区块的第一次调用时更新价格累加器

  /**

  更新变量:

  blockTimestampLast

  reserve0

  reserve1

  price0CumulativeLast

  price1CumulativeLast

  */

  //这个函数是用来更新价格oracle的,计算累计价格

  function _update(uint balance0,uint balance1,uint112 _reserve0,uint112 _reserve1)private{

  //溢出校验

  require(balance0<=uint112(-1)&&balance1<=uint112(-1),'UniswapV2:OVERFLOW');

  uint32 blockTimestamp=uint32(block.timestamp%2**32);

  uint32 timeElapsed=blockTimestamp-blockTimestampLast;//overflow is desired

  //计算时间加权的累计价格,256位中,前112位用来存整数,后112位用来存小数,多的32位用来存溢出的值

  if(timeElapsed>0&&_reserve0!=0&&_reserve1!=0){

  //*never overflows,and+overflow is desired

  price0CumulativeLast+=uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0))*timeElapsed;

  price1CumulativeLast+=uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1))*timeElapsed;

  }

  //更新reserve值

  reserve0=uint112(balance0);

  reserve1=uint112(balance1);

  blockTimestampLast=blockTimestamp;

  emit Sync(reserve0,reserve1);

  }

  //if fee is on,mint liquidity equivalent to 1/6th of the growth in sqrt(k)

  //如果收费,增发流动性相当于sqrt(k)增长的1/6

  function _mintFee(uint112 _reserve0,uint112 _reserve1)private returns(bool feeOn){

  //获取接收手续费的地址

  address feeTo=IUniswapV2Factory(factory).feeTo();

  //手续费接收者不为0地址

  feeOn=feeTo!=address(0);

  uint _kLast=kLast;//gas savings

  //手续费接收者不为0地址

  if(feeOn){

  if(_kLast!=0){

  uint rootK=Math.sqrt(uint(_reserve0).mul(_reserve1));

  uint rootKLast=Math.sqrt(_kLast);

  if(rootK>rootKLast){

  uint numerator=totalSupply.mul(rootK.sub(rootKLast));

  uint denominator=rootK.mul(5).add(rootKLast);

  uint liquidity=numerator/denominator;

  if(liquidity>0)_mint(feeTo,liquidity);

  }

  }

  }

  //手续费接收者为0,并且kLast不为0

  else if(_kLast!=0){

  kLast=0;

  }

  }

  //this low-level function should be called from a contract which performs important safety checks

  //这个低级函数应该从执行重要安全检查的合约中调用

  function mint(address to)external lock returns(uint liquidity){

  (uint112 _reserve0,uint112 _reserve1,)=getReserves();//gas savings

  //合约里两种token的当前的balance

  uint balance0=IERC20(token0).balanceOf(address(this));

  uint balance1=IERC20(token1).balanceOf(address(this));

  //获得当前balance和上一次缓存的余额的差值

  //因为balance是动态变化的,reserve是静态变化的

  uint amount0=balance0.sub(_reserve0);

  uint amount1=balance1.sub(_reserve1);

  //计算手续费

  bool feeOn=_mintFee(_reserve0,_reserve1);

  //gas节省,必须在此处定义,因为totalSupply可以在_mintFee中更新

  //totalSupply是pair的凭证

  uint _totalSupply=totalSupply;//gas savings,must be defined here since totalSupply can update in _mintFee

  if(_totalSupply==0){

  //第一次铸币,也就是第一次注入流动性,值为根号k减去MINIMUM_LIQUIDITY,防止数据溢出

  liquidity=Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);

  //把MINIMUM_LIQUIDITY赋给地址0,永久锁住

  _mint(address(0),MINIMUM_LIQUIDITY);//permanently lock the first MINIMUM_LIQUIDITY tokens

  }else{

  //计算增量的token占总池子的比例,作为新铸币的数量

  //木桶法则,按最少的来,按当前投入的占池子总的比例增发

  liquidity=Math.min(amount0.mul(_totalSupply)/_reserve0,amount1.mul(_totalSupply)/_reserve1);

  }

  require(liquidity>0,'UniswapV2:INSUFFICIENT_LIQUIDITY_MINTED');

  //铸币,修改to的token数量及totalsupply

  //给to地址发凭证,同时pair合约的totalSupply增发同等的凭证

  _mint(to,liquidity);

  //更新时间加权平均价格

  _update(balance0,balance1,_reserve0,_reserve1);

  if(feeOn)kLast=uint(reserve0).mul(reserve1);//reserve0 and reserve1 are up-to-date

  emit Mint(msg.sender,amount0,amount1);

  }

  //this low-level function should be called from a contract which performs important safety checks

  function burn(address to)external lock returns(uint amount0,uint amount1){

  (uint112 _reserve0,uint112 _reserve1,)=getReserves();//gas savings

  address _token0=token0;//gas savings

  address _token1=token1;//gas savings

  uint balance0=IERC20(_token0).balanceOf(address(this));

  uint balance1=IERC20(_token1).balanceOf(address(this));

  uint liquidity=balanceOf[address(this)];

  bool feeOn=_mintFee(_reserve0,_reserve1);

  uint _totalSupply=totalSupply;//gas savings,must be defined here since totalSupply can update in _mintFee

  //计算返回的amount0/1

  amount0=liquidity.mul(balance0)/_totalSupply;//using balances ensures pro-rata distribution

  amount1=liquidity.mul(balance1)/_totalSupply;//using balances ensures pro-rata distribution

  require(amount0>0&&amount1>0,'UniswapV2:INSUFFICIENT_LIQUIDITY_BURNED');

  _burn(address(this),liquidity);

  //_token0/1给to转amount0/1

  _safeTransfer(_token0,to,amount0);

  _safeTransfer(_token1,to,amount1);

  //获取转账后的balance

  balance0=IERC20(_token0).balanceOf(address(this));

  balance1=IERC20(_token1).balanceOf(address(this));

  //更新reserve0,reserve1和时间戳

  _update(balance0,balance1,_reserve0,_reserve1);

  if(feeOn)kLast=uint(reserve0).mul(reserve1);//reserve0 and reserve1 are up-to-date

  emit Burn(msg.sender,amount0,amount1,to);

  }

  //this low-level function should be called from a contract which performs important safety checks

  //交易函数

  //可以是token0-->token1,

  //也可以是token1-->token0

  //但参数中:amount0Out和amount1Out中有一个值是0

  function swap(

  uint amount0Out,

  uint amount1Out,

  address to,

  bytes calldata data

  )external lock

  {

  require(amount0Out>0||amount1Out>0,'UniswapV2:INSUFFICIENT_OUTPUT_AMOUNT');

  (uint112 _reserve0,uint112 _reserve1,)=getReserves();//gas savings

  require(amount0Out<_reserve0&&amount1Out<_reserve1,'UniswapV2:INSUFFICIENT_LIQUIDITY');

  uint balance0;

  uint balance1;

  {//scope for _token{0,1},avoids stack too deep errors

  address _token0=token0;

  address _token1=token1;

  require(to!=_token0&&to!=_token1,'UniswapV2:INVALID_TO');

  //划转操作

  if(amount0Out>0)_safeTransfer(_token0,to,amount0Out);//optimistically transfer tokens

  if(amount1Out>0)_safeTransfer(_token1,to,amount1Out);//optimistically transfer tokens

  if(data.length>0)IUniswapV2Callee(to).uniswapV2Call(msg.sender,amount0Out,amount1Out,data);

  balance0=IERC20(_token0).balanceOf(address(this));

  balance1=IERC20(_token1).balanceOf(address(this));

  }

  uint amount0In=balance0>_reserve0-amount0Out?balance0-(_reserve0-amount0Out):0;

  uint amount1In=balance1>_reserve1-amount1Out?balance1-(_reserve1-amount1Out):0;

  require(amount0In>0||amount1In>0,'UniswapV2:INSUFFICIENT_INPUT_AMOUNT');

  {//scope for reserve{0,1}Adjusted,avoids stack too deep errors

  //防止数据溢出校验

  uint balance0Adjusted=balance0.mul(1000).sub(amount0In.mul(3));

  uint balance1Adjusted=balance1.mul(1000).sub(amount1In.mul(3));

  require(balance0Adjusted.mul(balance1Adjusted)>=uint(_reserve0).mul(_reserve1).mul(1000**2),'UniswapV2:K');

  }

  //更新

  _update(balance0,balance1,_reserve0,_reserve1);

  emit Swap(msg.sender,amount0In,amount1In,amount0Out,amount1Out,to);

  }

  //force balances to match reserves

  //强制balance以匹配储备

  function skim(address to)external lock{

  address _token0=token0;//gas savings

  address _token1=token1;//gas savings

  _safeTransfer(_token0,to,IERC20(_token0).balanceOf(address(this)).sub(reserve0));

  _safeTransfer(_token1,to,IERC20(_token1).balanceOf(address(this)).sub(reserve1));

  }

  //force reserves to match balances

  //强制储备以匹配balance

  function sync()external lock{

  _update(IERC20(token0).balanceOf(address(this)),IERC20(token1).balanceOf(address(this)),reserve0,reserve1);

  }

  }

相关文章
|
5月前
|
物联网 区块链 vr&ar
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
|
2月前
|
存储 开发框架 安全
揭秘区块链:以太坊智能合约开发的奥秘与挑战,你准备好迎接未来了吗?
【10月更文挑战第25天】本文介绍了区块链技术的基本概念及其核心特点,重点讲解了以太坊智能合约的开发流程和实际开发中的注意事项。通过安装 Truffle、Ganache 和 Remix 等工具,读者可以快速上手编写、编译、部署和测试智能合约。文章还对比了以太坊去中心化应用与传统集中式应用的优势和挑战,帮助读者全面了解以太坊智能合约开发。
47 0
|
4月前
|
供应链 物联网 区块链
|
5月前
|
区块链 C# 存储
链动未来:WPF与区块链的创新融合——从智能合约到去中心化应用,全方位解析开发安全可靠DApp的最佳路径
【8月更文挑战第31天】本文以问答形式详细介绍了区块链技术的特点及其在Windows Presentation Foundation(WPF)中的集成方法。通过示例代码展示了如何选择合适的区块链平台、创建智能合约,并在WPF应用中与其交互,实现安全可靠的消息存储和检索功能。希望这能为WPF开发者提供区块链技术应用的参考与灵感。
73 0
|
22天前
|
供应链 安全 分布式数据库
探索区块链技术在供应链管理中的应用
【10月更文挑战第21天】 本文深入探讨了区块链技术如何在供应链管理中发挥关键作用,通过具体案例分析,揭示了区块链提高透明度、降低成本和增强安全性的潜力。文章首先概述了区块链技术的基本原理及其对传统供应链模式的挑战,接着详细讨论了区块链如何在不同供应链环节中实施,并分析了其带来的变革。最后,文章提出了企业在采纳区块链技术时可能面临的挑战和应对策略,为供应链管理者提供了宝贵的参考。
|
2月前
|
存储 供应链 分布式数据库
深入理解区块链技术:原理、应用与挑战
本文旨在探讨区块链技术的基本原理、主要应用及其面临的挑战。通过分析区块链的分布式账本技术、加密算法和共识机制,我们揭示了其如何在无需中心化权威的情况下确保数据的不可篡改性和透明性。此外,文章还讨论了区块链在金融、供应链管理、智能合约等领域的应用案例,并指出了当前区块链技术面临的可扩展性、隐私保护和法律监管等挑战。通过对这些内容的深入分析,我们希望为读者提供一个全面而深入的区块链技术概览。
170 16
|
1月前
|
存储 安全 物联网
未来已来:区块链技术在物联网与虚拟现实中的应用
随着科技的不断进步,新兴技术如区块链、物联网(IoT)和虚拟现实(VR)正在逐渐改变我们的生活和工作方式。本文将探讨这些技术的发展趋势和应用场景,以及它们如何相互融合,为我们带来更便捷、安全和沉浸式的体验。
|
1月前
|
存储 供应链 算法
深入探索区块链技术:原理、应用与未来展望
本文将带你深入了解区块链技术的基本原理,探讨其在金融、供应链、医疗等多个领域的应用案例,并展望其未来的发展趋势。通过本文,你将对区块链技术有一个全面的认识,理解其背后的技术逻辑和应用场景。
|
2月前
|
供应链 安全 区块链
探索区块链技术在数据安全中的应用
本文深入探讨了区块链技术如何革新数据安全领域,特别是在保护个人隐私、增强数据完整性和透明度方面的作用。通过分析区块链的去中心化特性、加密技术以及智能合约的功能,文章阐述了这一技术如何有效防止数据篡改、确保交易记录的不可逆性,并促进跨组织间的信任建立。此外,还讨论了当前区块链技术面临的挑战及未来发展趋势,为理解其在数据安全领域的潜力提供了全面视角。
|
1月前
|
存储 供应链 监控
深入探索区块链技术在供应链管理中的应用####
本文旨在探讨区块链技术如何革新供应链管理,通过分析其核心特性与实际案例,揭示该技术如何增强透明度、提升效率并降低成本。我们将从区块链的基本原理入手,逐步剖析其在供应链各环节中的具体应用,最终展望其未来发展趋势。 ####
79 3