Skip to content

Commit

Permalink
Merge pull request #201 from eforest-finance/release/2.26.0
Browse files Browse the repository at this point in the history
Mini app
  • Loading branch information
fyannch authored Nov 11, 2024
2 parents 88af9ad + 0e60ea3 commit cfff711
Show file tree
Hide file tree
Showing 6 changed files with 483 additions and 0 deletions.
11 changes: 11 additions & 0 deletions contract/Forest/ForestContractState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ public partial class ForestContractState : ContractState
public SingletonState<int> MaxBatchCancelOfferCount { get; set; }

public SingletonState<int> MaxBatchCancelListCount { get; set; }

public SingletonState<string> TreePointsHashVerifyKey { get; set; }
/// Address -> TreePointsInfo
public MappedState<Address, TreePointsInfo> TreePointsMap { get; set; }
/// Address -> timestamp 13
public MappedState<Address, long> TreePointsAddTimeMap { get; set; }
/// Address -> activityId -> timestamp 13
public MappedState<Address, string, long> TreePointsActivityClaimTimeMap { get; set; }
/// Address -> timestamp 13
public MappedState<Address, long> TreePointsLevelUpgradeTimeMap { get; set; }


}
}
8 changes: 8 additions & 0 deletions contract/Forest/ForestContract_Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,4 +452,12 @@ private void AssertBalanceEnoughForList(string symbol, Address address, long cur
var listedAmount = GetEffectiveNFTListedTotalAmount(address, symbol);
Assert(currentBalance >= (listedAmount + amount), $"The balance is not enough. Please reset it.");
}

private void CheckPointsRequestHash(string request, string hash)
{
var key = State.TreePointsHashVerifyKey.Value;
Assert(!string.IsNullOrEmpty(key), "Need SetTreePointsHashVerifyKey");
var requestHash = HashHelper.ComputeFrom(string.Concat(request, key));
Assert(hash.Equals(requestHash.ToHex()), "Unverified requests");
}
}
163 changes: 163 additions & 0 deletions contract/Forest/ForestContract_Tree.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
using AElf;
using AElf.Contracts.MultiToken;
using AElf.Sdk.CSharp;
using Google.Protobuf.WellKnownTypes;

namespace Forest;

public partial class ForestContract
{
public override Empty AddTreePoints(AddTreePointsInput input)
{
AssertContractInitialized();
Assert(input != null, "Invalid param");
Assert(!input.Address.Value.IsNullOrEmpty(), "Invalid param Address");
Assert(input.Points > 0, "Invalid param Points");
Assert(!string.IsNullOrEmpty(input.RequestHash), "Invalid param RequestHash");
Assert(input.OpTime != null && input.OpTime > 0, "Invalid param OpTime");
Assert(Context.Sender == input.Address, "Param Address is not Sender");

var requestStr = string.Concat(input.Address.ToBase58(), input.Points, input.PointsType, input.OpTime);
CheckPointsRequestHash(requestStr, input.RequestHash);

var lastAddTime = State.TreePointsAddTimeMap[input.Address];
Assert(input.OpTime > lastAddTime, "Invalid param OpTime");

var treePointsInfo = State.TreePointsMap[input.Address];
if (treePointsInfo != null)
{
treePointsInfo.Points += input.Points;
}
else
{
treePointsInfo = new TreePointsInfo()
{
Owner = input.Address,
Points = input.Points,
Level = 1
};
}

State.TreePointsMap[input.Address] = treePointsInfo;
State.TreePointsAddTimeMap[input.Address] = input.OpTime;

//event
Context.Fire(new TreePointsAdded()
{
Owner = input.Address,
Points = input.Points,
PointsType = input.PointsType,
OpTime = input.OpTime,
TotalPoints = treePointsInfo.Points,
RequestHash = input.RequestHash
});
return new Empty();
}
public override Empty ClaimTreePoints(ClaimTreePointsInput input)
{
AssertContractInitialized();
Assert(input != null, "Invalid param");
Assert(!input.Address.Value.IsNullOrEmpty(), "Invalid param Address");
Assert(input.Points >= 0, "Invalid param Points");
Assert(!string.IsNullOrEmpty(input.ActivityId), "Invalid param ActivityId");
Assert(!string.IsNullOrEmpty(input.RequestHash), "Invalid param RequestHash");
Assert(input.OpTime != null && input.OpTime > 0, "Invalid param OpTime");
Assert(input.Reward != null && !string.IsNullOrEmpty(input.Reward.Symbol) && input.Reward.Amount > 0, "Invalid param Reward");
Assert(Context.Sender == input.Address, "Param Address is not Sender");

var requestStr = string.Concat(input.Address.ToBase58(), input.ActivityId,input.Points, input.OpTime);
requestStr = string.Concat(requestStr, input.Reward.Symbol, input.Reward.Amount);
CheckPointsRequestHash(requestStr, input.RequestHash);

var lastOpTime = State.TreePointsActivityClaimTimeMap[input.Address][input.ActivityId];
Assert(lastOpTime == 0, "You have already participated in this activity");
Assert(input.OpTime > lastOpTime, "Invalid param OpTime");

var treePointsInfo = State.TreePointsMap[input.Address];
Assert(treePointsInfo != null, "your points is zero");
Assert(treePointsInfo.Points >= input.Points, "You don't have enough points");
treePointsInfo.Points -= input.Points;
State.TreePointsMap[input.Address] = treePointsInfo;
State.TreePointsActivityClaimTimeMap[input.Address][input.ActivityId] = input.OpTime;

//transfer award
var balance = State.TokenContract.GetBalance.Call(new GetBalanceInput
{
Symbol = input.Reward.Symbol,
Owner = Context.Self
});
Assert(balance.Balance >= input.Reward.Amount,$"The platform does not have enough {input.Reward.Symbol}");
State.TokenContract.Transfer.Send(new TransferInput
{
To = input.Address,
Symbol = input.Reward.Symbol,
Amount = input.Reward.Amount
});
//event
Context.Fire(new TreePointsClaimed()
{
Owner = input.Address,
Points = input.Points,
ActivityId = input.ActivityId,
OpTime = input.OpTime,
RewardSymbol = input.Reward.Symbol,
RewardAmount = input.Reward.Amount,
TotalPoints = treePointsInfo.Points,
RequestHash = input.RequestHash
});
return new Empty();
}
public override Empty SetTreePointsHashVerifyKey(StringValue input)
{
AssertContractInitialized();
Assert(input != null && !string.IsNullOrEmpty(input.Value), "Invalid param key");
var key = State.TreePointsHashVerifyKey.Value;
if (string.IsNullOrEmpty(key))
{
State.TreePointsHashVerifyKey.Value = input.Value;
return new Empty();
}
AssertSenderIsAdmin();
State.TreePointsHashVerifyKey.Value = input.Value;
return new Empty();
}

public override Empty TreeLevelUpgrade(TreeLevelUpgradeInput input)
{
AssertContractInitialized();
Assert(input != null, "Invalid param");
Assert(!input.Address.Value.IsNullOrEmpty(), "Invalid param Address");
Assert(input.Points > 0, "Invalid param Points");
Assert(!string.IsNullOrEmpty(input.RequestHash), "Invalid param RequestHash");
Assert(input.OpTime != null && input.OpTime > 0, "Invalid param OpTime");
Assert(input.UpgradeLevel > 0, "Invalid UpgradeLevel, Should be greater than 0");
Assert(Context.Sender == input.Address, "Param Address is not Sender");

var requestStr = string.Concat(input.Address.ToBase58(), input.Points, input.OpTime, input.UpgradeLevel);
CheckPointsRequestHash(requestStr, input.RequestHash);

var lastOpTime = State.TreePointsLevelUpgradeTimeMap[input.Address];
Assert(input.OpTime > lastOpTime, "Invalid param OpTime");

var treePointsInfo = State.TreePointsMap[input.Address];
Assert(treePointsInfo != null, "your points is zero");
Assert(treePointsInfo.Points >= input.Points, "You don't have enough points");
Assert(treePointsInfo.Level < input.UpgradeLevel, $"You are already level{input.UpgradeLevel}");

treePointsInfo.Points -= input.Points;
State.TreePointsMap[input.Address] = treePointsInfo;
State.TreePointsLevelUpgradeTimeMap[input.Address] = input.OpTime;

//event
Context.Fire(new TreeLevelUpgraded()
{
Owner = input.Address,
Points = input.Points,
OpTime = input.OpTime,
UpgradeLevel = input.UpgradeLevel,
TotalPoints = treePointsInfo.Points,
RequestHash = input.RequestHash
});
return new Empty();
}
}
5 changes: 5 additions & 0 deletions contract/Forest/ForestContract_Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,9 @@ public override Int32Value GetMaxBatchCancelListCount(Empty input)
{
return new Int32Value { Value = State.MaxBatchCancelListCount.Value };
}

public override TreePointsInfo GetTreePoints(Address input)
{
return State.TreePointsMap[input];
}
}
91 changes: 91 additions & 0 deletions protobuf/forest_contract.proto
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ service ForestContract {
rpc GetMaxBatchCancelListCount(google.protobuf.Empty) returns (google.protobuf.Int32Value){
option (aelf.is_view) = true;
}

rpc AddTreePoints(AddTreePointsInput) returns (google.protobuf.Empty){
}

rpc ClaimTreePoints(ClaimTreePointsInput) returns (google.protobuf.Empty){
}

rpc TreeLevelUpgrade(TreeLevelUpgradeInput) returns (google.protobuf.Empty){
}

rpc GetTreePoints(aelf.Address) returns (TreePointsInfo){
option (aelf.is_view) = true;
}

rpc SetTreePointsHashVerifyKey(google.protobuf.StringValue)returns (google.protobuf.Empty){
}
}

// Structs.
Expand Down Expand Up @@ -234,6 +250,11 @@ message WhitelistInfoList{
repeated WhitelistInfo whitelists = 1;
}

message TreePointsInfo {
aelf.Address owner = 1;
int64 points = 2;
int64 level = 3;
}
// Inputs.

message InitializeInput {
Expand Down Expand Up @@ -460,6 +481,42 @@ message CreateArtInfo {
Price cost_price = 8;
string painting_style = 9;
}
message AddTreePointsInput {
aelf.Address address = 1;
int64 points = 2;
int32 points_type =3;
int64 op_time = 4;
string request_hash = 5;
}

message ClaimTreePointsInput {
aelf.Address address = 1;
int64 points = 2;
string activity_id = 3;
int64 op_time = 4;
TreeReward reward = 5;
string request_hash = 6;
}

message TreeLevelUpgradeInput {
aelf.Address address = 1;
int64 points = 2;
int64 op_time = 3;
int32 upgrade_level = 4;
string request_hash = 5;
}

message TreeReward {
string symbol = 1;
int64 amount = 2;
}

enum TreePointsType {
NORMALONE = 0;
NORMALTWO = 1;
INVITE = 2;
}


// Events

Expand Down Expand Up @@ -631,3 +688,37 @@ message ArtCreated {
string painting_style = 9;
}

message TreePointsAdded {
option (aelf.is_event) = true;
aelf.Address owner = 1;
int64 points = 2;
int32 points_type = 3;
int64 op_time = 4;
int64 total_points = 5;
string request_hash = 6;
}

message TreePointsClaimed {
option (aelf.is_event) = true;
aelf.Address owner = 1;
int64 points = 2;
string activity_id = 3;
int64 op_time = 4;
string reward_symbol = 5;
int64 reward_amount = 6;
int64 total_points = 7;
string request_hash = 8;
}

message TreeLevelUpgraded {
option (aelf.is_event) = true;
aelf.Address owner = 1;
int64 points = 2;
int32 upgrade_level = 3;
int64 op_time = 4;
int64 total_points = 5;
string request_hash = 6;
}



Loading

0 comments on commit cfff711

Please sign in to comment.