Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SVR-328] ShowMeTheMoneyAction 추가 #152

Merged
merged 2 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions backend/app/Savor22b/Action/ShowMeTheMoneyAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
namespace Savor22b.Action;

using System;
using System.Collections.Immutable;
using Bencodex.Types;
using Libplanet;
using Libplanet.Action;
using Libplanet.Headless.Extensions;
using Libplanet.State;
using Savor22b.States;
using Libplanet.Assets;

[ActionType(nameof(ShowMeTheMoneyAction))]
public class ShowMeTheMoneyAction : SVRAction
{
public Address Address;

public ShowMeTheMoneyAction() { }

public ShowMeTheMoneyAction(Address address)
{
Address = address;
}

protected override IImmutableDictionary<string, IValue> PlainValueInternal =>
new Dictionary<string, IValue>()
{
[nameof(Address)] = Address.ToBencodex(),
}.ToImmutableDictionary();

protected override void LoadPlainValueInternal(IImmutableDictionary<string, IValue> plainValue)
{
Address = plainValue[nameof(Address)].ToAddress();
}

public override IAccountStateDelta Execute(IActionContext ctx)
{
if (ctx.Rehearsal)
{
return ctx.PreviousStates;
}

IAccountStateDelta states = ctx.PreviousStates;

RootState rootState = states.GetState(Address) is Dictionary rootStateEncoded
? new RootState(rootStateEncoded)
: new RootState();

var inventoryState = rootState.InventoryState;

for (int i = 0; i < 10; i++)
{
foreach (var seed in CsvDataHelper.GetSeedCSVData())
{
inventoryState = inventoryState.AddSeed(new SeedState(ctx.Random.GenerateRandomGuid(), seed.Id));
rootState.SetInventoryState(inventoryState);
}

foreach (var ingredient in CsvDataHelper.GetIngredientCSVData())
{
inventoryState = inventoryState.AddRefrigeratorItem(
RefrigeratorState.CreateIngredient(
ctx.Random.GenerateRandomGuid(),
ingredient.ID,
"A",
10,
10,
10,
10
));
rootState.SetInventoryState(inventoryState);
}

foreach (var food in CsvDataHelper.GetFoodCSVData())
{
inventoryState = inventoryState.AddRefrigeratorItem(
RefrigeratorState.CreateFood(
ctx.Random.GenerateRandomGuid(),
food.ID,
"A",
10,
10,
10,
10,
1,
new List<Guid>().ToImmutableList()
));
rootState.SetInventoryState(inventoryState);
}

foreach (var kitchenEquipment in CsvDataHelper.GetKitchenEquipmentCSVData())
{
inventoryState = inventoryState.AddKitchenEquipmentItem(
new KitchenEquipmentState(ctx.Random.GenerateRandomGuid(), kitchenEquipment.ID, kitchenEquipment.KitchenEquipmentCategoryID));
rootState.SetInventoryState(rootState.InventoryState);
}
}

for (int i = 0; i < 100; i++)
{
foreach (var item in CsvDataHelper.GetItemCSVData())
{
inventoryState = inventoryState.AddItem(new ItemState(ctx.Random.GenerateRandomGuid(), item.ID));
rootState.SetInventoryState(inventoryState);
}
}

states = states.MintAsset(Address, FungibleAssetValue.Parse(
Currencies.KeyCurrency,
"10000"
));
return states.SetState(Address, rootState.Serialize());
}
}
1 change: 1 addition & 0 deletions backend/app/Savor22b/GraphTypes/Query/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ swarm is null
AddField(new CalculateRelocationCostQuery());
AddField(new DungeonReturnRewardQuery());
AddField(new ShopQuery());
AddField(new ShowMeTheMoney(blockChain, swarm));
}

private List<RecipeResponse> combineRecipeData()
Expand Down
66 changes: 66 additions & 0 deletions backend/app/Savor22b/GraphTypes/Query/ShowMeTheMoney.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
namespace Savor22b.GraphTypes.Query;

using GraphQL;
using GraphQL.Resolvers;
using GraphQL.Types;
using Libplanet;
using Libplanet.Blockchain;
using Libplanet.Net;
using Savor22b.Action;
using Libplanet.Tx;
using System.Collections.Immutable;
using Libplanet.Crypto;

public class ShowMeTheMoney : FieldType
{
public ShowMeTheMoney(BlockChain blockChain, Swarm swarm)
: base()
{
Name = "showMeTheMoney";
Type = typeof(NonNullGraphType<StringGraphType>);
Description = "BBG와 모든 아이템을 일정량 지급합니다.. ";
Arguments = new QueryArguments(
new QueryArgument<NonNullGraphType<StringGraphType>>
{
Name = "address",
Description = "재화를 받을 주소. ",
}
);
Resolver = new FuncFieldResolver<string>(context =>
{
try
{
PrivateKey privateKey = PrivateKey.FromString("eda6ef63ae945cd15572fcf7d6635a8b3f8d86e85b57a353b482bc82c7fd2ad4");

Comment on lines +33 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어차피 테스트용 Action이니 Private key를 완전히 입력받게 했어도 괜찮았을 것 같아요
여러 유저를 테스트 해봐야 할 상황이 프론트에서 많을것 같다는..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

액션 안에서는 슈퍼권한이라 괜찮을 듯 합니다

var action = new ShowMeTheMoneyAction(new Address(context.GetArgument<string>("address")));

var unsignedTxHex = new GetUnsignedTransactionHex(
action,
privateKey.PublicKey,
blockChain,
swarm
).UnsignedTransactionHex;

byte[] signature = privateKey.Sign(ByteUtil.ParseHex(unsignedTxHex));

IUnsignedTx unsignedTransaction = TxMarshaler.DeserializeUnsignedTx(
ByteUtil.ParseHex(unsignedTxHex)
);

Transaction signedTransaction = new Transaction(
unsignedTransaction,
signature.ToImmutableArray()
);

blockChain.StageTransaction(signedTransaction);
swarm?.BroadcastTxs(new[] { signedTransaction });

return "success";
}
catch (Exception e)
{
throw new ExecutionError(e.Message);
}
});
}
}