Пример #1
0
        public IAccountStateDelta MinerReward(IActionContext ctx, IAccountStateDelta states)
        {
            // 마이닝 보상
            // https://www.notion.so/planetarium/Mining-Reward-b7024ef463c24ebca40a2623027d497d
            Currency           currency            = states.GetGoldCurrency();
            FungibleAssetValue defaultMiningReward = currency * 10;
            var countOfHalfLife             = (int)Math.Pow(2, Convert.ToInt64((ctx.BlockIndex - 1) / 12614400));
            FungibleAssetValue miningReward =
                defaultMiningReward.DivRem(countOfHalfLife, out FungibleAssetValue _);

            if (miningReward >= FungibleAssetValue.Parse(currency, "1.25"))
            {
                states = states.TransferAsset(
                    GoldCurrencyState.Address,
                    ctx.Miner,
                    miningReward
                    );
            }

            return(states);
        }
Пример #2
0
        public IAccountStateDelta GenesisGoldDistribution(IActionContext ctx, IAccountStateDelta states)
        {
            IEnumerable <GoldDistribution> goldDistributions = states.GetGoldDistribution();
            var      index        = ctx.BlockIndex;
            Currency goldCurrency = states.GetGoldCurrency();
            Address  fund         = GoldCurrencyState.Address;

            foreach (GoldDistribution distribution in goldDistributions)
            {
                BigInteger amount = distribution.GetAmount(index);
                if (amount <= 0)
                {
                    continue;
                }

                // We should divide by 100 for only mainnet distributions.
                // See also: https://github.com/planetarium/lib9c/pull/170#issuecomment-713380172
                FungibleAssetValue fav = goldCurrency * amount;
                var testAddresses      = new HashSet <Address>(
                    new []
                {
                    new Address("F9A15F870701268Bd7bBeA6502eB15F4997f32f9"),
                    new Address("Fb90278C67f9b266eA309E6AE8463042f5461449"),
                }
                    );
                if (!testAddresses.Contains(distribution.Address))
                {
                    fav = fav.DivRem(100, out FungibleAssetValue _);
                }
                states = states.TransferAsset(
                    fund,
                    distribution.Address,
                    fav
                    );
            }
            return(states);
        }
Пример #3
0
        public void DivRem()
        {
            FungibleAssetValue foo7 = FungibleAssetValue.FromRawValue(FOO, 7);
            FungibleAssetValue foo6 = FungibleAssetValue.FromRawValue(FOO, 6);
            FungibleAssetValue foo3 = FungibleAssetValue.FromRawValue(FOO, 3);
            FungibleAssetValue foo2 = FungibleAssetValue.FromRawValue(FOO, 2);
            FungibleAssetValue foo1 = FungibleAssetValue.FromRawValue(FOO, 1);
            FungibleAssetValue foo0 = new FungibleAssetValue(FOO);
            FungibleAssetValue rem;

            Assert.Equal((foo6, foo0), foo6.DivRem(1));
            Assert.Equal(foo6, foo6.DivRem(1, out rem));
            Assert.Equal(foo0, rem);
            Assert.Equal(foo0, foo6 % 1);

            Assert.Equal((foo2, foo0), foo6.DivRem(3));
            Assert.Equal(foo2, foo6.DivRem(3, out rem));
            Assert.Equal(foo0, rem);
            Assert.Equal(foo0, foo6 % 3);

            Assert.Equal((foo2, foo1), foo7.DivRem(3));
            Assert.Equal(foo2, foo7.DivRem(3, out rem));
            Assert.Equal(foo1, rem);
            Assert.Equal(foo1, foo7 % 3);

            Assert.Equal((foo0, foo6), foo6.DivRem(7));
            Assert.Equal(foo0, foo6.DivRem(7, out rem));
            Assert.Equal(foo6, rem);
            Assert.Equal(foo6, foo6 % 7);

            Assert.Equal((foo0, foo0), foo0.DivRem(2));
            Assert.Equal(foo0, foo0.DivRem(2, out rem));
            Assert.Equal(foo0, rem);
            Assert.Equal(foo0, foo0 % 2);

            Assert.Equal((6, foo0), foo6.DivRem(foo1));
            Assert.Equal(6, foo6.DivRem(foo1, out rem));
            Assert.Equal(foo0, rem);
            Assert.Equal(foo0, foo6 % foo1);

            Assert.Equal((2, foo0), foo6.DivRem(foo3));
            Assert.Equal(2, foo6.DivRem(foo3, out rem));
            Assert.Equal(foo0, rem);
            Assert.Equal(foo0, foo6 % foo3);

            Assert.Equal((2, foo1), foo7.DivRem(foo3));
            Assert.Equal(2, foo7.DivRem(foo3, out rem));
            Assert.Equal(foo1, rem);
            Assert.Equal(foo1, foo7 % foo3);

            Assert.Equal((0, foo6), foo6.DivRem(foo7));
            Assert.Equal(0, foo6.DivRem(foo7, out rem));
            Assert.Equal(foo6, rem);
            Assert.Equal(foo6, foo6 % foo7);

            Assert.Equal((0, foo0), foo0.DivRem(foo2));
            Assert.Equal(0, foo0.DivRem(foo2, out rem));
            Assert.Equal(foo0, rem);
            Assert.Equal(foo0, foo0 % foo2);

            Assert.Throws <DivideByZeroException>(() => foo1.DivRem(0));
            Assert.Throws <DivideByZeroException>(() => foo1.DivRem(0, out rem));
            Assert.Throws <DivideByZeroException>(() => foo1 % 0);
            Assert.Throws <DivideByZeroException>(() => foo1.DivRem(foo0));
            Assert.Throws <DivideByZeroException>(() => foo1.DivRem(foo0, out rem));
            Assert.Throws <DivideByZeroException>(() => foo1 % foo0);

            FungibleAssetValue bar1 = FungibleAssetValue.FromRawValue(BAR, 1);

            Assert.Throws <ArgumentException>(() => bar1.DivRem(foo1));
            Assert.Throws <ArgumentException>(() => bar1.DivRem(foo1, out rem));
            Assert.Throws <ArgumentException>(() => bar1 % foo1);
        }
Пример #4
0
        public void Execute(params ShopItemData[] productDatas)
        {
            var buyerAvatarState = _initialState.GetAvatarState(_buyerAvatarAddress);

            var goldCurrency = _initialState.GetGoldCurrency();
            var shopState    = _initialState.GetShopState();
            var buyCount     = 0;
            var itemsToBuy   = new List <BuyMultiple.PurchaseInfo>();

            foreach (var product in productDatas)
            {
                var(sellerAvatarState, sellerAgentState) =
                    CreateAvatarState(product.SellerAgentAddress, product.SellerAvatarAddress);

                INonFungibleItem nonFungibleItem;
                if (product.ItemType == ItemType.Equipment)
                {
                    var itemUsable = ItemFactory.CreateItemUsable(
                        _tableSheets.EquipmentItemSheet.First,
                        product.ItemId,
                        product.RequiredBlockIndex);
                    nonFungibleItem = itemUsable;
                }
                else
                {
                    var costume = ItemFactory.CreateCostume(_tableSheets.CostumeItemSheet.First, product.ItemId);
                    costume.Update(product.RequiredBlockIndex);
                    nonFungibleItem = costume;
                }

                // Case for backward compatibility of `Buy`
                if (product.ContainsInInventory)
                {
                    sellerAvatarState.inventory.AddItem2((ItemBase)nonFungibleItem);
                }

                var shopItemId = Guid.NewGuid();

                var shopItem = new ShopItem(
                    sellerAgentState.address,
                    sellerAvatarState.address,
                    shopItemId,
                    new FungibleAssetValue(_goldCurrencyState.Currency, product.Price, 0),
                    product.RequiredBlockIndex,
                    nonFungibleItem);
                shopState.Register(shopItem);

                if (product.Buy)
                {
                    ++buyCount;
                    var purchaseInfo = new BuyMultiple.PurchaseInfo(
                        shopItem.ProductId,
                        shopItem.SellerAgentAddress,
                        shopItem.SellerAvatarAddress);
                    itemsToBuy.Add(purchaseInfo);
                }
            }

            Assert.NotNull(shopState.Products);
            Assert.Equal(3, shopState.Products.Count);

            _initialState = _initialState
                            .SetState(_buyerAvatarAddress, buyerAvatarState.Serialize())
                            .SetState(Addresses.Shop, shopState.Serialize());

            var priceData = new PriceData(goldCurrency);

            foreach (var avatarState in _sellerAgentStateMap.Keys)
            {
                var agentState = _sellerAgentStateMap[avatarState];
                priceData.TaxedPriceSum[agentState.address] = new FungibleAssetValue(goldCurrency, 0, 0);

                _initialState = _initialState
                                .SetState(avatarState.address, avatarState.Serialize());
            }

            IAccountStateDelta previousStates = _initialState;

            var buyerGold    = previousStates.GetBalance(_buyerAgentAddress, goldCurrency);
            var priceSumData = productDatas
                               .Where(i => i.Buy)
                               .Aggregate(priceData, (priceSum, next) =>
            {
                var price         = new FungibleAssetValue(goldCurrency, next.Price, 0);
                var tax           = price.DivRem(100, out _) * Buy.TaxRate;
                var taxedPrice    = price - tax;
                priceData.TaxSum += tax;

                var prevSum = priceData.TaxedPriceSum[next.SellerAgentAddress];
                priceData.TaxedPriceSum[next.SellerAgentAddress] = prevSum + taxedPrice;
                priceData.PriceSum += price;
                return(priceData);
            });

            var buyMultipleAction = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = itemsToBuy,
            };
            var nextState = buyMultipleAction.Execute(new ActionContext()
            {
                BlockIndex     = 1,
                PreviousStates = previousStates,
                Random         = new TestRandom(),
                Rehearsal      = false,
                Signer         = _buyerAgentAddress,
            });

            var nextShopState = nextState.GetShopState();

            Assert.Equal(productDatas.Length - buyCount, nextShopState.Products.Count);

            var nextBuyerAvatarState = nextState.GetAvatarState(_buyerAvatarAddress);

            foreach (var product in productDatas.Where(i => i.Buy))
            {
                Assert.True(
                    nextBuyerAvatarState.inventory.TryGetNonFungibleItem(
                        product.ItemId,
                        out INonFungibleItem outNonFungibleItem)
                    );
                Assert.Equal(product.RequiredBlockIndex, outNonFungibleItem.RequiredBlockIndex);
            }

            Assert.Equal(buyCount, nextBuyerAvatarState.mailBox.Count);

            goldCurrency = nextState.GetGoldCurrency();
            var nextGoldCurrencyGold = nextState.GetBalance(Addresses.GoldCurrency, goldCurrency);

            Assert.Equal(priceSumData.TaxSum, nextGoldCurrencyGold);

            foreach (var product in productDatas)
            {
                var nextSellerGold = nextState.GetBalance(product.SellerAgentAddress, goldCurrency);
                Assert.Equal(priceSumData.TaxedPriceSum[product.SellerAgentAddress], nextSellerGold);
            }

            var nextBuyerGold = nextState.GetBalance(_buyerAgentAddress, goldCurrency);

            Assert.Equal(buyerGold - priceSumData.PriceSum, nextBuyerGold);

            previousStates = nextState;
        }