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

Feature: Added aelf-samples submodule #52

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
Binary file added .DS_Store
Binary file not shown.
60 changes: 60 additions & 0 deletions .github/workflows/publish-aelf-samples-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
on:
push:
tags:
- 'aelf-samples-v*'
Copy link
Collaborator

Choose a reason for hiding this comment

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

This file should not exists. Basically when someone puts up a template tag with version, it should also pack all aelf-samples contract into the contract template package.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed prod-workflow


jobs:
publish:
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: aelf-samples
environment: prod
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0 # Ensure the full history is fetched so we can check the commit history

- name: Verify tag is on master branch
id: verify_tag
run: |
# Get the commit SHA of the tag
TAG_COMMIT=$(git rev-list -n 1 $GITHUB_REF)
# Check if the commit exists on the master branch
if git merge-base --is-ancestor $TAG_COMMIT origin/master; then
echo "Tag commit is on master branch."
echo "IS_ON_MASTER=true" >> $GITHUB_ENV
else
echo "Tag commit is not on master branch."
echo "IS_ON_MASTER=false" >> $GITHUB_ENV
fi

- name: Stop if not on master
if: env.IS_ON_MASTER != 'true'
run: |
echo "This tag was not created from the master branch. Exiting."
exit 1

- name: Setup .NET
if: env.IS_ON_MASTER == 'true'
uses: actions/setup-dotnet@v1
with:
dotnet-version: '7.0.*' # Change this to the .NET version you're using

- name: Read version from Version.props
if: env.IS_ON_MASTER == 'true'
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
version=$(grep -oP '<Version>\K[^<]+' Version.props)
echo "VERSION=$version" >> $GITHUB_ENV

- name: Pack
if: env.IS_ON_MASTER == 'true'
working-directory: ${{ env.WORKING_DIRECTORY }}
run: dotnet pack --configuration Release --output nupkgs /p:Version=$VERSION

- name: Publish NuGet packages
if: env.IS_ON_MASTER == 'true'
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
dotnet nuget push "nupkgs/*.nupkg" --api-key ${{ secrets.AELF_SAMPLES_NUGET_API_KEY }} --source ${{ vars.AELF_SAMPLES_NUGET_SOURCE_URL }}
34 changes: 34 additions & 0 deletions .github/workflows/publish-aelf-samples-staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
on:
push:
branches:
- release/aelf-samples/*

jobs:
publish:
runs-on: ubuntu-latest
env:
WORKING_DIRECTORY: aelf-samples
environment: staging
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: '7.0.*' # Change this to the .NET version you're using

- name: Read version from Version.props
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
version=$(grep -oP '<Version>\K[^<]+' Version.props)
echo "VERSION=$version-rc.${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV

- name: Pack
working-directory: ${{ env.WORKING_DIRECTORY }}
run: dotnet pack --configuration Release --output nupkgs /p:Version=$VERSION

- name: Publish NuGet packages
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
dotnet nuget push "nupkgs/*.nupkg" --api-key ${{ secrets.TEST_AELF_SAMPLES_NUGET_API_KEY }} --source ${{ vars.TEST_AELF_SAMPLES_NUGET_SOURCE_URL }}
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "aelf-samples"]
path = aelf-samples
url = https://github.com/AElfProject/aelf-samples.git
1 change: 1 addition & 0 deletions aelf-samples
Submodule aelf-samples added at 6e8355
Binary file added templates/.DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions templates/AElf.Contract.Template.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<Content Include="LotteryGameContract\**\*" Exclude="LotteryGameContract\**\bin\**;LotteryGameContract\**\obj\**" />
<Content Include="SimpleDAOContract\**\*" Exclude="SimpleDAOContract\**\bin\**;SimpleDAOContract\**\obj\**" />
<Content Include="NftSaleContract\**\*" Exclude="NftSaleContract\**\bin\**;NftSaleContract\**\obj\**" />
<Content Include="ToDoContract\**\*" Exclude="ToDoContract\**\bin\**;ToDoContract\**\obj\**" />
Copy link
Collaborator

Choose a reason for hiding this comment

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

These should be removed and instead be read from the aelf-sample submodule

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Configured to fetch from aelf-samples

<Content Include="TicTacToeContract\**\*" Exclude="TicTacToeContract\**\bin\**;TicTacToeContract\**\obj\**" />
<Content Include="ExpenseTrackerContract\**\*" Exclude="ExpenseTrackerContract\**\bin\**;ExpenseTrackerContract\**\obj\**" />
<Compile Remove="**\*" />
</ItemGroup>

Expand Down
Binary file added templates/ExpenseTrackerContract/.DS_Store
Binary file not shown.
21 changes: 21 additions & 0 deletions templates/ExpenseTrackerContract/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "http://json.schemastore.org/template",
Copy link
Collaborator

Choose a reason for hiding this comment

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

All these should be added into aelf-samples repo to maintain consistency

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added to aelf-samples

"author": "AElf",
"classifications": [
"AElf/SmartContract"
],
"identity": "AElf.Contract.ExpenseTracker.Template",
"name": "AElf Contract ExpenseTracker Template",
"shortName": "aelf-expense-tracker",
"tags": {
"language": "C#",
"type": "project"
},
"sourceName": "ExpenseTracker",
"symbols": {
"NamespacePath": {
"type": "parameter",
"replaces": "AElf.Contracts.ExpenseTracker"
}
}
}
Binary file not shown.
117 changes: 117 additions & 0 deletions templates/ExpenseTrackerContract/src/ExpenseTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using Google.Protobuf.WellKnownTypes;
using System.Collections.Generic;

namespace AElf.Contracts.ExpenseTracker
{
public class ExpenseTracker : ExpenseTrackerContainer.ExpenseTrackerBase
{
public override Empty Initialize(Empty input)
{
if (State.Initialized.Value)
{
return new Empty();
}
State.Initialized.Value = true;
State.Owner.Value = Context.Sender;
State.ExpenseIds.Value = "";
State.ExpenseCounter.Value = 0;
return new Empty();
}

public override StringValue AddExpense(ExpenseInput input)
{
if (!State.Initialized.Value)
{
return new StringValue { Value = "Contract not initialized." };
}
var expenseId = (State.ExpenseCounter.Value + 1).ToString();
State.ExpenseCounter.Value++;
var timestamp = Context.CurrentBlockTime.Seconds;
State.Expenses[expenseId] = new Expense
{
ExpenseId = expenseId,
Description = input.Description,
Category = input.Category,
Amount = input.Amount, // Now using int64 for amount
Currency = input.Currency,
CreatedAt = timestamp,
UpdatedAt = timestamp,
Owner = Context.Sender.ToString().Trim('"'),
};
State.ExpenseExistence[expenseId] = true;

var existingExpenseIds = State.ExpenseIds.Value;
existingExpenseIds += string.IsNullOrEmpty(existingExpenseIds) ? expenseId : $",{expenseId}";
State.ExpenseIds.Value = existingExpenseIds;

return new StringValue { Value = expenseId };
}

public override Empty UpdateExpense(ExpenseUpdateInput input)
{
var expense = State.Expenses[input.ExpenseId];
if (expense == null)
{
return new Empty(); // Handle case if expense doesn't exist
}
expense.Description = input.Description ?? expense.Description;
expense.Category = input.Category ?? expense.Category;
expense.Amount = input.Amount != 0 ? input.Amount : expense.Amount; // Now using int64 for amount
expense.Currency = input.Currency ?? expense.Currency;
expense.UpdatedAt = Context.CurrentBlockTime.Seconds;

State.Expenses[input.ExpenseId] = expense;
return new Empty();
}

public override Empty DeleteExpense(StringValue input)
{
State.Expenses.Remove(input.Value);
State.ExpenseExistence.Remove(input.Value);

var existingExpenseIds = State.ExpenseIds.Value.Split(',');
var newExpenseIds = new List<string>(existingExpenseIds.Length);
foreach (var expenseId in existingExpenseIds)
{
if (expenseId != input.Value)
{
newExpenseIds.Add(expenseId);
}
}
State.ExpenseIds.Value = string.Join(",", newExpenseIds);

return new Empty();
}

public override ExpenseList ListExpenses(StringValue input)
{
var owner = input.Value; // Get the owner value from the input
var expenseList = new ExpenseList();
var expenseIds = State.ExpenseIds.Value.Split(',');
foreach (var expenseId in expenseIds)
{
var expense = State.Expenses[expenseId];
if (expense != null && expense.Owner == owner) // Filter expenses by owner
{
expenseList.Expenses.Add(expense);
}
}
return expenseList;
}

public override Expense GetExpense(StringValue input)
{
var expense = State.Expenses[input.Value];
if (expense == null)
{
return new Expense { ExpenseId = input.Value, Description = "Expense not found." };
}
return expense;
}

public override BoolValue GetInitialStatus(Empty input)
{
return new BoolValue { Value = State.Initialized.Value };
}
}
}
27 changes: 27 additions & 0 deletions templates/ExpenseTrackerContract/src/ExpenseTracker.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>AElf.Contracts.ExpenseTracker</RootNamespace>
<IsContract>true</IsContract>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup>
<ObjPath>$(MSBuildProjectDirectory)/$(BaseIntermediateOutputPath)$(Configuration)/$(TargetFramework)/</ObjPath>
</PropertyGroup>

<Target Name="ProtoGeneratedRecognition" AfterTargets="CoreCompile">
<ItemGroup>
<Compile Include="$(ObjPath)Protobuf/**/*.cs" />
</ItemGroup>
</Target>

<ItemGroup>
<PackageReference Include="AElf.Sdk.CSharp" Version="1.5.0" />
<PackageReference Include="AElf.Tools" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>

15 changes: 15 additions & 0 deletions templates/ExpenseTrackerContract/src/ExpenseTrackerState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using AElf.Sdk.CSharp.State;
using AElf.Types;

namespace AElf.Contracts.ExpenseTracker
{
public class ExpenseTrackerState : ContractState
{
public BoolState Initialized { get; set; }
public SingletonState<Address> Owner { get; set; }
public MappedState<string, Expense> Expenses { get; set; } // Mapping of expense ID to Expense
public MappedState<string, bool> ExpenseExistence { get; set; } // Mapping to track expense existence
public StringState ExpenseIds { get; set; } // Concatenated string of expense IDs
public Int32State ExpenseCounter { get; set; } // Counter for generating unique IDs
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
syntax = "proto3";
import "aelf/options.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/wrappers.proto";
import "Protobuf/reference/acs12.proto";
// The namespace of this class
option csharp_namespace = "AElf.Contracts.ExpenseTracker";
service ExpenseTracker {
option (aelf.csharp_state) = "AElf.Contracts.ExpenseTracker.ExpenseTrackerState";
option (aelf.base) = "Protobuf/reference/acs12.proto";
rpc Initialize (google.protobuf.Empty) returns (google.protobuf.Empty) {
}
rpc AddExpense (ExpenseInput) returns (google.protobuf.StringValue) {
}
rpc UpdateExpense (ExpenseUpdateInput) returns (google.protobuf.Empty) {
}
rpc DeleteExpense (google.protobuf.StringValue) returns (google.protobuf.Empty) {
}
rpc ListExpenses (google.protobuf.StringValue) returns (ExpenseList) {
option (aelf.is_view) = true;
}
rpc GetExpense (google.protobuf.StringValue) returns (Expense) {
option (aelf.is_view) = true;
}
rpc GetInitialStatus (google.protobuf.Empty) returns (google.protobuf.BoolValue) {
option (aelf.is_view) = true;
}
}

message Expense {
string expense_id = 1;
string description = 2;
string category = 3;
int64 amount = 4; // Store as cents
string currency = 5;
string owner = 6;
int64 created_at = 7;
int64 updated_at = 8;
}

message ExpenseInput {
string description = 1;
string category = 2;
int64 amount = 3; // Store as cents
string currency = 4;
}

message ExpenseUpdateInput {
string expense_id = 1;
string description = 2;
string category = 3;
int64 amount = 4; // Store as cents
string currency = 5;
}

message ExpenseList {
repeated Expense expenses = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";

import "aelf/core.proto";

option csharp_namespace = "AElf.Contracts.ExpenseTracker";

message AuthorityInfo {
aelf.Address contract_address = 1;
aelf.Address owner_address = 2;
}
Loading