Beispiel #1
0
        /// <summary>
        /// 获取转账的这笔钱能分到的分红  [start,end)
        /// </summary>
        /// <param name="blockHeight">上次claim的高度</param>
        /// <param name="value">账户拥有的nnc数量</param>
        /// <returns>可以领取的值</returns>
        private static Info updateCanClaim(BigInteger curHeight, Info info, BigInteger balance, BigInteger value)
        {
            //获取上一个有完整记录的块的记录值
            CoinPoolInfo coinPoolInfo    = getCoinPoolInfo();
            var          fullblockHeight = coinPoolInfo.fullblock;
            var          lastblockHeight = coinPoolInfo.lastblock;
            var          endHeight       = fullblockHeight;

            if (curHeight > lastblockHeight) //如果当前高度大于lastblock  证明lastblock的记录已经完成  把last赋值给full
            {
                endHeight = lastblockHeight;
            }

            var key_EndHeight = new byte[] { 0x12 }.Concat(endHeight.AsByteArray().Concat(quadZero).Range(0, 4));
            var totalMoney_end = Storage.Get(Storage.CurrentContext, key_EndHeight).AsBigInteger();
            //获取上一次领奖的块的总系统费
            var key_StartHeight = new byte[] { 0x12 }.Concat(((BigInteger)info.block).AsByteArray().Concat(quadZero).Range(0, 4));

            //start == end  不领取
            if (key_EndHeight == key_StartHeight)
            {
                return(info);
            }
            var totalMoney_start = Storage.Get(Storage.CurrentContext, key_StartHeight).AsBigInteger();
            //(totalMoneyB-totalMoneyA)*info.balance/发行量 就是这个块现在的余额可以领取的分红
            var canclaim = (totalMoney_end - totalMoney_start) * balance / totalCoin;


            info.cancaim += canclaim;
            info.block    = (uint)endHeight;
            return(info);
        }
Beispiel #2
0
        public static bool transfer(byte[] from, byte[] to, BigInteger value)
        {
            if (value <= 0)
            {
                return(false);
            }

            if (from == to)
            {
                return(true);
            }

            //获得当前块的高度
            var height = Blockchain.GetHeight();

            //为了保护每个有交易的区块高度都有系统费的值   多了1.x个gas
            var          curMoney     = getCurMoney(height);
            CoinPoolInfo coinPoolInfo = getCoinPoolInfo();

            if (curMoney == 0)
            {
                curMoney = getCurMoney(coinPoolInfo.lastblock);
                var bytes_CurHeight = ((BigInteger)height).AsByteArray().Concat(quadZero).Range(0, 4);
                var key_CurHeight = new byte[] { 0x12 }.Concat(bytes_CurHeight);
                Storage.Put(Storage.CurrentContext, key_CurHeight, curMoney);
                //这个地方可以不更新coinpoolinfo的值   不更新没有影响
                updateCoinPoolInfo(coinPoolInfo, height);
            }

            //付款方
            if (from.Length > 0)
            {
                var  keyFrom = new byte[] { 0x11 }.Concat(from);
                Info fromInfo   = getInfo(from);
                var  from_value = fromInfo.balance;
                if (from_value < value)
                {
                    return(false);
                }
                fromInfo         = updateCanClaim(height, fromInfo, from_value, value);
                fromInfo.balance = from_value - value;
                Storage.Put(Storage.CurrentContext, keyFrom, Helper.Serialize(fromInfo));
            }
            //收款方
            if (to.Length > 0)
            {
                var  keyTo = new byte[] { 0x11 }.Concat(to);
                Info toInfo   = getInfo(to);
                var  to_value = toInfo.balance;
                toInfo         = updateCanClaim(height, toInfo, to_value, value);
                toInfo.balance = to_value + value;
                Storage.Put(Storage.CurrentContext, keyTo, Helper.Serialize(toInfo));
            }
            //notify
            Transferred(from, to, value);
            return(true);
        }
Beispiel #3
0
        public static object getTotalMoney(byte[] height)
        {
            var key_Height = new byte[] { 0x12 }.Concat(height.Concat(quadZero).Range(0, 4));
            var totalmoney = Storage.Get(Storage.CurrentContext, key_Height).AsBigInteger();

            if (totalmoney == 0)
            {
                CoinPoolInfo coinPoolInfo = getCoinPoolInfo();
                var          lastblock = coinPoolInfo.lastblock;
                var          key_fullblock = new byte[] { 0x12 }.Concat(lastblock.AsByteArray().Concat(quadZero).Range(0, 4));
                totalmoney = Storage.Get(Storage.CurrentContext, key_fullblock).AsBigInteger();
            }
            return(totalmoney);
        }
Beispiel #4
0
 private static CoinPoolInfo getCoinPoolInfo()
 {
     byte[] data = Storage.Get(Storage.CurrentContext, "CoinPoolInfo");
     if (data.Length > 0)
     {
         return(Helper.Deserialize(data) as CoinPoolInfo);
     }
     else
     {
         var coinPoolInfo = new CoinPoolInfo();
         coinPoolInfo.fullblock = 0;
         coinPoolInfo.lastblock = 0;
         return(coinPoolInfo);
     }
 }
Beispiel #5
0
        /**
         * 奖池信息查询
         **/
        public static CoinPoolInfo getCoinPoolInfo(BigInteger coinId)
        {
            byte[]       key  = "coin_".AsByteArray().Concat(coinId.AsByteArray());
            byte[]       data = Storage.Get(Storage.CurrentContext, key);
            CoinPoolInfo info = null;

            if (data.Length > 0)
            {
                info = Helper.Deserialize(data) as CoinPoolInfo;
            }
            else
            {
                info = new CoinPoolInfo();
            }
            info.nowBlock = Blockchain.GetHeight();
            return(info);
        }
Beispiel #6
0
        /*
         * 每一个块存储的是目前为止所有收到的系统费用    先判断当前高度大于lastblock的高度  就把lastblock赋值给fullblock  lastblock=当前高度
         * 如果没有则加上之前的所有费用记录下来
         * 如果有记录 就直接+=
         */
        private static bool useGas(byte[] txid)
        {
            TransferInfo transferInfo = getTxInfo(txid);

            if (transferInfo.value <= 0)
            {
                return(false);
            }
            if (transferInfo.to.AsBigInteger() != ExecutionEngine.ExecutingScriptHash.AsBigInteger())
            {
                return(false);
            }

            //获取当前块的高度
            uint cur_height = Blockchain.GetHeight();
            var  bytes_CurHeight = ((BigInteger)cur_height).AsByteArray().Concat(quadZero).Range(0, 4);
            var  key_CurHeight = new byte[] { 0x12 }.Concat(bytes_CurHeight);
            //先获取当前块所能统计到的总系统费
            var curMoney = getCurMoney((BigInteger)cur_height);
            //获取当前的coinpoolinfo的值
            CoinPoolInfo coinPoolInfo = getCoinPoolInfo();

            //如果curmoney是0  代表是新高度   总系统费拿coinpool里的lastblock的高度
            if (curMoney == 0)
            {
                curMoney = getCurMoney(coinPoolInfo.lastblock);
                //新高度就需要更新coinpool的值
                updateCoinPoolInfo(coinPoolInfo, (BigInteger)cur_height);
            }

            BigInteger totalMoney = curMoney + transferInfo.value;

            //记录当前高度的系统费
            Storage.Put(Storage.CurrentContext, key_CurHeight, totalMoney);
            //标记这个txid 已经处理过了
            Storage.Put(Storage.CurrentContext, new byte[] { 0x13 }.Concat(txid), 1);
            //更新coinpoolinfo的值
            Storage.Put(Storage.CurrentContext, "CoinPoolInfo", Helper.Serialize(coinPoolInfo));
            return(true);
        }
Beispiel #7
0
 private static void updateCoinPoolInfo(CoinPoolInfo coinPoolInfo, BigInteger height)
 {
     coinPoolInfo.fullblock = coinPoolInfo.lastblock;
     coinPoolInfo.lastblock = height;
     Storage.Put(Storage.CurrentContext, "CoinPoolInfo", Helper.Serialize(coinPoolInfo));
 }
Beispiel #8
0
        /**
         * 购买解禁BPEC
         */
        public static bool transferBPEC(byte[] sender, BigInteger value)
        {
            bool bol = false;

            if (sender.Length != 20 || value <= 0)
            {
                Runtime.Log("Owner error.");
                return(false);
            }
            if (Runtime.CheckWitness(sender))
            {
                var          height       = Blockchain.GetHeight();
                CoinPoolInfo coinPoolInfo = getCoinPoolInfo(0);
                if (coinPoolInfo.coinCode == 0)
                {
                    coinPoolInfo.coinCode   = 1;
                    coinPoolInfo.lastBlock  = height;
                    coinPoolInfo.nowBlock   = height;
                    coinPoolInfo.nextBlock  = height + BASE_BLOCK;
                    coinPoolInfo.coinPool   = 0;
                    coinPoolInfo.claimState = 0;
                    coinPoolInfo.claimEnd   = 0;
                }
                //
                if (height > coinPoolInfo.nextBlock)
                {
                    if (coinPoolInfo.claimState == 0)
                    {
                        object[] args = new object[0] {
                        };
                        object[] res  = (object[])bpecCall("getBPECPoolInfo", args);
                        if (res.Length > 0)
                        {
                            BigInteger claimCode  = (BigInteger)res[4];
                            byte[]     endAddress = (byte[])res[5];
                            byte       obpecOver  = (byte)res[6];
                            BigInteger coin       = 0;
                            object[]   args2      = new object[1] {
                                claimCode
                            };
                            object[] res2 = (object[])bpecCall("getClaimPoolInfo", args2);
                            if (res2.Length > 0)
                            {
                                byte[] endBuyAddress = (byte[])res2[7];
                                if (coinPoolInfo.claimEnd == 0)
                                {
                                    if (obpecOver == 0)
                                    {
                                        coin = coinPoolInfo.coinPool;
                                        coinPoolInfo.claimEnd   = 1;
                                        coinPoolInfo.winAddress = endAddress;
                                    }
                                    else
                                    {
                                        coin = coinPoolInfo.coinPool / 2;
                                        coinPoolInfo.winAddress = endBuyAddress;
                                    }
                                }
                                else
                                {
                                    coin = coinPoolInfo.coinPool / 2;
                                    coinPoolInfo.winAddress = endBuyAddress;
                                }

                                //创建保存最新的奖池
                                CoinPoolInfo coinPoolInfoTemp = new CoinPoolInfo();
                                coinPoolInfoTemp.coinCode   = coinPoolInfo.coinCode + 1;
                                coinPoolInfoTemp.lastBlock  = height;
                                coinPoolInfo.nowBlock       = height;
                                coinPoolInfoTemp.nextBlock  = height + BASE_BLOCK;
                                coinPoolInfoTemp.coinPool   = coinPoolInfo.coinPool - coin;
                                coinPoolInfoTemp.claimState = 0;
                                coinPoolInfoTemp.claimEnd   = coinPoolInfo.claimEnd;
                                coinPoolInfoTemp.winAddress = endBuyAddress;
                                BigInteger n   = 0;
                                var        key = "coin_".AsByteArray().Concat(n.AsByteArray());
                                Storage.Put(Storage.CurrentContext, key, Helper.Serialize(coinPoolInfoTemp));
                                //分离奖池并开奖
                                coinPoolInfo.claimState = 1;
                                coinPoolInfo.coinPool   = coinPoolInfoTemp.coinPool;
                                byte[] key2 = "coin_".AsByteArray().Concat(coinPoolInfo.coinCode.AsByteArray());
                                Storage.Put(Storage.CurrentContext, key2, Helper.Serialize(coinPoolInfo));
                                //发放奖励
                                UserInfo userInfo = getUserInfo(coinPoolInfo.winAddress);
                                userInfo.balance += coin;
                                var keyWho = new byte[] { 0x11 }.Concat(coinPoolInfo.winAddress);
                                Storage.Put(Storage.CurrentContext, keyWho, Helper.Serialize(userInfo));
                                //notify
                                TransferBPECed(2, sender, coinPoolInfo.coinPool, coinPoolInfo.coinCode);
                                bol = true;
                            }
                        }
                    }
                }
                else
                {
                    BigInteger cgas     = value * CGAS_CLAIM_RATE / 100;
                    BigInteger claimV   = cgas * CLAIM_RATE / 100;
                    BigInteger coinV    = cgas * COIN_RATE / 100;
                    BigInteger feeV     = cgas - claimV - coinV;
                    UserInfo   userInfo = getUserInfo(sender);
                    if (userInfo.balance >= cgas)
                    {
                        object[] args = new object[4] {
                            sender, 2, value, claimV
                        };
                        bool res = (bool)bpecCall("transferOpen", args);
                        if (res)
                        {
                            //
                            _subTotal(feeV);
                            //
                            coinPoolInfo.coinPool  += coinV;
                            coinPoolInfo.nextBlock += ADD_BLOCK;
                            coinPoolInfo.nowBlock   = height;
                            //判断最大值
                            if (height > coinPoolInfo.nextBlock)
                            {
                                coinPoolInfo.nextBlock = coinPoolInfo.lastBlock + MAX_BLOCK;
                            }
                            BigInteger n   = 0;
                            var        key = "coin_".AsByteArray().Concat(n.AsByteArray());
                            Storage.Put(Storage.CurrentContext, key, Helper.Serialize(coinPoolInfo));
                            //
                            userInfo.balance -= cgas;
                            var keyWho = new byte[] { 0x11 }.Concat(sender);
                            Storage.Put(Storage.CurrentContext, keyWho, Helper.Serialize(userInfo));
                            bol = true;
                        }
                    }
                    if (bol == true)
                    {
                        TransferBPECed(1, sender, value, coinPoolInfo.coinCode);
                    }
                    else
                    {
                        TransferBPECed(0, sender, value, coinPoolInfo.coinCode);
                    }
                }
            }
            return(bol);
        }