创建自己的加密货币MNC——以太坊代币(二)

创建一个基于以太坊平台的分红币MNC,根据持有的代币数量,进行分红的算法。github地址:

https://github.com/lxr1907/MNC

1.使用以太坊根据比例换购token MNC

2.定期根据使用用户资金购买的矿机挖ETH,打入该合约,触发分红方法根据token持有比例分红

3.衰减,由于矿机有折旧衰减损坏的概率,token会随着持有时间而衰减。

代码如下

pragma solidity ^0.4.19;
contract owned {
    address public owner;
    function owned() public {
        owner = msg.sender;
    }
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
    function transferOwnership(address newOwner) onlyOwner public {
        owner = newOwner;
    }
}

contract LxrContract is owned{
    struct miner{
        //MNC余额
        uint256 balance;
        //挖矿份额
        uint256 mining;
        //上一次分红,衰减日期
        uint256 lastDate;
        //上一次收益
        uint256 lastBonus;
    }
    //虚拟币名称
    string public name;
    //虚拟币名称缩写
    string public symbol;
    //18 decimals 极力推荐使用默认值,尽量别改
    uint8 public constant decimals = 18;
    //和以太坊兑换的汇率
    uint32 public ethExchangeRate = 1000;
    //总发行
    uint256 public totalSupply;
    //创始人保留百分比
    uint8  constant ownerInitial=10;
    //合约拥有者
    address public owner;
    //创建所有账户余额数组
    mapping (address => miner) public miners;
    //挖矿需要募集的挖矿资金,100个eth,后续可以增加
    uint256 public collectAmountLeft=ethExchangeRate*100;
    //0.01个ETH起计算挖矿收益
    uint256  startMiningMin=ethExchangeRate/100;
    //挖矿人地址数组
    address[]  minersArray;
    //分红日期
    uint256 public bonusTimePoint;
    //分红历史总数
    uint256 public bonusTotal;
    //阶段分红累计数,分红后清零
    uint256 public bonusPeriodCumulative;
    //每日折旧率千分比,例如每日千分之2,一年后48.15%,3,一年后剩余33%,4一年后23.15%
    uint16 depreciationRate=3;
    //每次折旧时间,测试情况下设置为1分钟以便调试
    uint256 depreciationTime=1 minutes;
    //从挖矿账户提现手续费百分比
    uint miningDepositFee=30;
    // 在区块链上创建一个公共事件,它触发就会通知所有客户端
    event Transfer(address indexed from, address indexed to, uint256 value);
    event BalanceToMine(address indexed from, uint256 value);
    event MiningDeposit(address indexed from, uint256 value, uint256 fee);
    event TransferMining(address indexed from,address indexed to, uint256 value);
    event Bonus(address indexed to, uint256 value);
    event Burn(address indexed from, uint256 value);
    /**
     * 初始化合约,将最初的令牌中的一部分打入创建者的账户中
     * @param initialSupply 初始发行量
     * @param tokenName 虚拟币名称
     * @param tokenSymbol 虚拟币名称缩写
     */
    function LxrContract(
        uint256 initialSupply,
        string tokenName,
        string tokenSymbol
    ) public {
        //初始化合约所有人
        owner=msg.sender;
        //合约账户余额初始
        _mintToken(this,initialSupply-initialSupply * ownerInitial/100);
        //所有人账户余额初始
        _mintToken(owner,initialSupply * ownerInitial/100);
        // 设置显示名称
        name = tokenName;
        // 设置显示缩写,例如比特币是BTC
        symbol = tokenSymbol;
        //初始化分红时间点
        bonusTimePoint=now/depreciationTime;
    }

    /**
     * 内部转账,只能被该合约调用
     */
    function _transfer(address _from, address _to, uint _value) internal {
        // 检查发送者是否拥有足够的币
        require(miners[_from].balance >= _value);
        // 检查越界
        require(miners[_to].balance + _value > miners[_to].balance);
        // 从发送者扣币
        miners[_from].balance -= _value;
        // 给接收者加相同数量币
        miners[_to].balance += _value;
        //通知
        Transfer(_from, _to, _value);
    }
    /**
     * 账户余额兑换挖矿份额
     */
    function balanceToMining( uint256 _value) public {
        //检查挖矿募集剩余
        require(collectAmountLeft > 0);
        require(miners[msg.sender].balance > 0);
        uint256 effectValue=_value;
        //传0或不传则所有余额兑换挖矿份额
        if(effectValue==0){
            effectValue=miners[msg.sender].balance/(10**uint256(decimals));
        }
        // 检查越界
        require(miners[msg.sender].mining + effectValue > miners[msg.sender].mining);
        // 检查发送者是否拥有足够的币
        if(miners[msg.sender].balance < effectValue){
            effectValue=miners[msg.sender].balance/(10**uint256(decimals));
        }
        //检查挖矿募集剩余是否足够,不足只转一部分
        if(collectAmountLeft < _value){
            effectValue=collectAmountLeft;
        }
        //账户ETH余额不足,无法投资
        if(this.balance<effectValue* 10 ** uint256(decimals)/ethExchangeRate){
            return;
        }
        //如果不存在,将该挖矿地址加入数组,用于以后遍历访问
        addToMinersArray(msg.sender);
        // 从余额销毁
        burn(msg.sender,effectValue);
        // 给挖矿账户加相同数量币
        miners[msg.sender].mining += effectValue* 10 ** uint256(decimals);
        //募集剩余资金减少
        collectAmountLeft -=effectValue;
        //将挖矿所需以太坊转到拥有者账户,以便所有者使用这些eth购买矿机挖矿
        owner.transfer(effectValue* 10 ** uint256(decimals)/ethExchangeRate);
        //通知
        BalanceToMine(msg.sender, effectValue);
    }
    /**
     *
     * 将挖矿份额转换为账户余额,需要按百分比支付手续费
     *
     * @param _value 提出金额
     */
    function miningDeposit( uint256 _value) public {
        uint depositFee=_value* 10 ** uint256(decimals)*miningDepositFee/100;
        uint depositValue=_value* 10 ** uint256(decimals);
        // 检查发送者是否拥有足够的币
        require(miners[msg.sender].mining >= depositValue);
        // 检查越界
        require(miners[msg.sender].balance + depositValue > miners[msg.sender].balance);
        // 从挖矿余额扣除
        miners[msg.sender].mining -= depositValue;
        //挖矿余额剩余为0,全部提现,则时间重置
        if(miners[msg.sender].mining==0){
            miners[msg.sender].lastDate=0;
        }
        //给账户加相同数量币,扣除一定百分比手续费
        miners[msg.sender].balance += depositValue-depositFee;
        //将手续费支付给合约管理员
        miners[owner].balance += depositFee;
        //通知
        MiningDeposit(msg.sender, depositValue,depositFee);
    }
    //将该挖矿地址加入数组
    function addToMinersArray(address _miner) internal{
        //如果不存在,将该挖矿地址加入数组,用于以后遍历访问
        bool hasAdd=false;
        for (uint i = 0; i < minersArray.length; i++) {
            if(minersArray[i]==_miner){
                hasAdd=true;
                break;
            }
        }
        if(!hasAdd){
            minersArray.push(_miner);
        }
    }
    /**
     * 将挖矿份额转让
     */
    function transferMining(address _to, uint256 _value)  public {
         // 检查发送者是否拥有足够的币
        require(miners[msg.sender].mining >= _value);
        // 检查越界
        require(miners[_to].mining + _value > miners[_to].mining);
        //将该挖矿地址加入数组
        addToMinersArray(_to);
        // 从发送者扣币
        miners[msg.sender].mining -= _value;
        // 给接收者加相同数量币
        miners[_to].mining += _value;
        TransferMining(msg.sender,_to,  _value);
    }
    /**
     *计算总挖矿份额
     */
    function getMiningAmountTotal() public view returns ( uint256 _totalMinigAmount){
        for (uint i = 0; i < minersArray.length; i++) {
            uint256 miningAmount = miners[minersArray[i]].mining;
            _totalMinigAmount += miningAmount;
        }
        _totalMinigAmount=_totalMinigAmount/(10**uint256(decimals));
    }
    /**
     *根据挖矿份额给每个人分红 ,匿名方法,直接转账触发
     * bonusMNCtoMiner
     */
    function () payable public {
        //阶段收益MNC
        bonusPeriodCumulative += msg.value*ethExchangeRate;
        require(bonusPeriodCumulative>0);
        //该阶段已经分红过,只累加分红数量
        if(bonusTimePoint>=now/depreciationTime){
            return;
        }
        //更新分红时间点
        bonusTimePoint=now/depreciationTime;
        uint256 totalMinigAmount=getMiningAmountTotal();
        if(totalMinigAmount==0){
            return;
        }
        //加发行量
        _mintToken(this,bonusPeriodCumulative/(10**uint256(decimals)));
        //总历史收益增加
        bonusTotal += bonusPeriodCumulative;
        //计算每个人的收益
        for (uint i = 0; i < minersArray.length; i++) {
            uint256 miningAmount = miners[minersArray[i]].mining/(10**uint256(decimals));
            if(miningAmount<startMiningMin){
                continue;
            }
             //矿机折旧衰减
            if(miners[minersArray[i]].lastDate==0){
                //第一次不折旧,记录时间
                miners[minersArray[i]].lastDate=now/depreciationTime;
                //第一次也不分红
                continue;
            }else{
                //计算出衰减段数
                uint256 depreciationPeriods=now/depreciationTime-miners[minersArray[i]].lastDate;
                //每段衰减一次
                for(uint m=0;m<depreciationPeriods;m++)
                miners[minersArray[i]].mining=miners[minersArray[i]].mining* (1000-depreciationRate)/1000;
                //更新时间
                miners[minersArray[i]].lastDate=now/depreciationTime;
            }
            //分红数量
            uint256 oneBonus = bonusPeriodCumulative*miningAmount/totalMinigAmount;
            miners[minersArray[i]].lastBonus=oneBonus;
        }
        //阶段收益清零
        bonusPeriodCumulative=0;
         //发放收益
        for (uint j = 0; j < minersArray.length; j++) {
            bonusToken(minersArray[j]);
        }
    }
    /**
     *奖励挖矿收益MNC
     *
     */
    function bonusToken(address _to) internal{
        miners[_to].balance+= miners[_to].lastBonus ;
        Bonus(_to, miners[_to].lastBonus*(10**uint256(decimals)));
    }
    /**
     * 发送MNC
     *
     * 从你的账户发送个`_value` 令牌到 `_to`
     *
     * @param _to 接收地址
     * @param _value 发送数量
     */
    function transfer(address _to, uint256 _value) public {
        _transfer(msg.sender, _to, _value);
    }
    /**
     *增发MNC
     *
     */
    function _mintToken(address _to, uint256 mintedAmount) internal{
        totalSupply += mintedAmount*(10**uint256(decimals));
        miners[_to].balance+= mintedAmount*(10**uint256(decimals));
        Transfer(0, _to, mintedAmount*(10**uint256(decimals)));
    }
    //增发MNC
    function MintToken( uint256 mintedAmount) onlyOwner public{
        _mintToken(this,mintedAmount);
    }
    /**
     *销毁MNC
     *
     */
    function burn( address _from,uint256 mintedAmount) internal{
        totalSupply -= mintedAmount*(10**uint256(decimals));
        miners[_from].balance-= mintedAmount*(10**uint256(decimals));
        Burn(_from, mintedAmount*(10**uint256(decimals)));
    }
    /**
     *
     *增加募集金额
     * @param amount 需要的MNC数量
     */
    function addCollection( uint256 amount) onlyOwner  public{
        collectAmountLeft += amount;
    }

    /// 使用以太坊购买token
    function buy() payable public {
        uint amount = msg.value;
        //合约余额充足
        require(miners[this].balance>=amount * ethExchangeRate);
        _transfer( this,msg.sender, amount * ethExchangeRate);
    }
    //出售token换回以太坊
    function sell(uint256 amount)  public {
        _transfer(msg.sender, this, amount* 10 ** uint256(decimals));
        msg.sender.transfer(amount* 10 ** uint256(decimals)/ethExchangeRate);
    }
    //调整和以太坊的兑换比例
    function setEthMncRate(uint32 _rate) onlyOwner public{
        //调整幅度限制到原价20%
        require(_rate>ethExchangeRate*8/10);
        require(_rate<ethExchangeRate*12/10);
        ethExchangeRate=_rate;
    }
    //折旧率千分比调整
    function setDepreciationRate(uint16 _rate) onlyOwner public{
        //调整幅度限制到100%
        require(_rate>depreciationRate/2);
        require(_rate<depreciationRate*2);
        require(_rate<1000);
        depreciationRate=_rate;
    }
    //折旧时间调整
    function setDepreciationTime(uint8 _rate) onlyOwner public{
        require(_rate!=0);
        //天数
        depreciationTime=_rate*1 days;
        //初始化分红时间点
        bonusTimePoint=now/depreciationTime;
    }
    //-------------------------------------------一下为调试方法
    //获取当前分红时间
    function getBonusTimeNow() public view returns(uint256 _time){
       _time= now/depreciationTime;
    } /**
     *
     *获取合约余额
     */
    function getContractBalance( )  public view   returns (uint _contractBalance,uint _ethBanlance){
       _contractBalance=miners[this].balance/(10**uint256(decimals));
       _ethBanlance=this.balance/(10**uint256(decimals));
    }
    /**
     *
     *获取我的余额
     */
    function getMyBalance( )  public view   returns (uint _myBalance,uint _myMining,uint _lastBonus,uint _date){
       _myBalance=miners[msg.sender].balance/(10**uint256(decimals));
       _myMining=miners[msg.sender].mining/(10**uint256(decimals));
       _lastBonus=miners[msg.sender].lastBonus/(10**uint256(decimals));
       _date=miners[msg.sender].lastDate;
    }
}

给我的ETH捐赠地址:0xdc834D429b3098f0568Af873c2d73b08790BF677

创建自己的区块链游戏SLOT——以太坊代币(三)

原文地址:https://www.cnblogs.com/lixiaoran/p/9132576.html

时间: 2024-10-03 17:51:30

创建自己的加密货币MNC——以太坊代币(二)的相关文章

以太坊代币合约详析

以太坊代币 在以太坊系统中,存在作为基础货币的 Ether(以太),以及同样可以作为货币使用的 Token(代币). 以太坊与其他加密货币的主要不同在于,以太坊不是单纯的货币,而是一个环境/平台.在这个平台上,任何人都可以利用区块链的技术,通过智能合约来构建自己的项目和DAPPS(去中心化应用). 如果把以太坊理解成互联网,DAPPS则是在上面运行的网页.DAPPS是去中心化的,意味着它不属于某个人,而是属于一群人.DAPPS发布的方式通常是采用被称为 ICO 的众筹方式.简单来说,你需要用你的

以太坊代币开发虚拟币钱包交易平台开发

以太坊代币开发虚拟币钱包交易平台开发156-3841-3841 作为一种加密数字货币,比特币价格在过去几年里暴涨,到2017年底时曾达到近两万美元,令许多人感到不可思议. 然而自2018年以来,比特币价格开始下跌,特别是在近期上演"大跳水".11月20日,比特币重挫逾16%,跌破4100美元,为去年10月以来的最低水平.比特币的暴跌,也引发其他加密货币大幅下挫.CoinMarketCap数据显示,目前整个加密货币市场价值已跌至约1500亿美元左右,与今年初时的8500亿美元规模相比严重

虚拟币钱包以太坊代币技术开发

虚拟币钱包以太坊代币技术开发156-3841-3841 然而自2018年以来,比特币价格开始下跌,特别是在近期上演"大跳水".11月20日,比特币重挫逾16%,跌破4100美元,为去年10月以来的最低水平.比特币的暴跌,也引发其他加密货币大幅下挫.CoinMarketCap数据显示,目前整个加密货币市场价值已跌至约1500亿美元左右,与今年初时的8500亿美元规模相比严重缩水.市场的大幅波动,引发人们对"加密货币能否成为可靠保值手段"的质疑. 有业内人士认为,此次比

创建自己的区块链游戏SLOT——以太坊代币(三)

一个以太坊合约版本的轮盘游戏,向合约转账ETH,有几率获得3,5,10,100倍奖励 合约地址:0x53DA598E70a1505Ad95cBF17fc5DCA0d2c51174b 捐赠ETH地址:0xdc834D429b3098f0568Af873c2d73b08790BF677 github地址:https://github.com/lxr1907/slot-on-ethereum pragma solidity ^0.4.18; contract LxrContract{ //18 dec

创建自己的区块链合约java版web3接口——以太坊代币(四)

texas-web3j-solidity项目是一个java版本的,使用web3j包和eth网络交互的小程序. 主要实现了以下功能: 1.发布合约 2.发起转账 3.查询交易 4.调用智能合约方法 texas-web3j-solidity项目在官方例子基础上做了以下几点功能性修改: 1.增加texas合约,用于游戏充值提现等功能 2.以太坊测试网络切换为ropsten,该测试网络更容易获取测试eth,地址为:https://www.ropsten.io/#faucet 3.增加spring-boo

solidity开发以太坊代币智能合约

智能合约开发是以太坊编程的核心之一,而代币是区块链应用的关键环节,下面我们来用solidity语言开发一个代币合约的实例,希望对大家有帮助. 以太坊的应用被称为去中心化应用(DApp),DApp的开发主要包括两大部分: 智能合约的开发 用户界面的开发 在本文中,我们将介绍智能合约的开发语言solidity. 让我们先从一个非常基础的例子开始,不用担心你现在还一点都不了解,我们将逐步了解到更多的细节. contract SimpleStorage { uint storedData; functi

科普贴 | 以太坊代币钱包MyEtherWallet使用教程,一步步教你玩转MEW

MyEtherWallet 是一个以太坊的网页钱包,使用非常简单,打开网页就可以使用,源代码开源,不会在服务器上存储用户的钱包信息如私钥和密码.支持 Ledger Wallet.TREZOR 等硬件钱包,功能极为丰富.是一把我们经常会用到的瑞士军刀! Myetherwallet 支持符合 ERC20 标准的代币(即以太坊系代币). 官网:https://www.myetherwallet.com/ ,一定要认准网址. 创建钱包1. 打开官网,将页面切换为中文,设置一个钱包密码(不少于9位,一定要

以太坊代币与账户交易

以太的单位 以太币的最小单位是Wei.Wei是一个非常小的单位,1Ether= 1018 Wei,和无限可分也差不了多少了.除了基本单位Wei,为了使用方便还有其他的单位,他们的关系如下: Kwei = 103  Wei Mwei = 106  Wei Gwei = 109  Wei Microether = 1012  Wei Milliether = 1015  Wei Ether / SCC = 1018 Wei 我们一般记住wei , Gwei=109wei,Ether = 1018we

Erc20Tokens:以太坊代币数据集

Erc20Tokens数据集包含超过1000种主流的以太坊ERC20代币的描述数据清单和图标,可用于钱包等区块链应用的开发,支持使用Java.Python.Php.NodeJs.C#等各种开发语言查询主流ERC20代币的相关数据.下载链接:ERC20代币数据集. 1.数据集概述 以下是ERC20代币数据集中部分代币的图标示意: Erc20Tokens数据集的的当前版本为1.0.0,主要文件清单参见:http://sc.hubwiz.com/codebag/erc20-tokens-dataset