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); }
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); }
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); }
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; }