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

Backend code to do #88

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions Backend/ContractReferences.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using AElf.Contracts.Consensus.AEDPoS;
using AElf.Contracts.MultiToken;

namespace AElf.Contracts.nft_contract
{
public partial class nft_contractState
{
internal TokenContractContainer.TokenContractReferenceState TokenContract { get; set; }
internal AEDPoSContractContainer.AEDPoSContractReferenceState ConsensusContract { get; set; }
}
}
89 changes: 89 additions & 0 deletions Backend/NFT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using AElf.Contracts.MultiToken;
using AElf.Sdk.CSharp;
using AElf.Types;
using Google.Protobuf.WellKnownTypes;

namespace AElf.Contracts.nft_contract
{
// Contract class must inherit the base class generated from the proto file
public class nft_contract : nft_contractContainer.nft_contractBase
{
private const string TokenContractAddress = "ASh2Wt7nSEmYqnGxPPzp4pnVDU4uhj1XW9Se5VeZcX2UDdyjx"; // tDVW token contract address

public override Empty Initialize(Empty input)
{
Assert(State.Initialized.Value == false, "Already initialized.");
State.Initialized.Value = true;
State.Owner.Value = Context.Sender;
State.TokenContract.Value = Address.FromBase58(TokenContractAddress);

return new Empty();
}

public override Int64Value CreateNFTToken(CreateNFTTokenInput input)
{
// Increment the token counter
State.TokenCounter.Value += 1;
var tokenId = State.TokenCounter.Value;

// Create the new NFT token
State.NFTTokens[tokenId] = new NFTToken
{
Name = input.Name,
Symbol = input.Symbol,
Owner = Context.Sender
};

// Fire an event for the creation of the NFT token
Context.Fire(new NFTCreated { NftId = tokenId });

return new Int64Value { Value = tokenId };
}

public override Empty TransferNFT(TransferNFTInput input)
{
var nft = State.NFTTokens[input.TokenId];
Assert(nft != null, "Token does not exist.");
Assert(nft.Owner == Context.Sender, "Not the owner.");
nft.Owner = input.To;
State.NFTTokens[input.TokenId] = nft;
Context.Fire(new NFTTransferred { TokenId = input.TokenId, From = Context.Sender, To = input.To });
return new Empty();
}

public override Empty BurnNFT(Int64Value input)
{
var nft = State.NFTTokens[input.Value];
Assert(nft != null, "Token does not exist.");
Assert(nft.Owner == Context.Sender, "Not the owner.");
State.NFTTokens.Remove(input.Value);
Context.Fire(new NFTBurned { TokenId = input.Value, Owner = Context.Sender });
return new Empty();
}

public override NFTDetails GetNFTDetails(Int64Value input)
{
var nft = State.NFTTokens[input.Value];
Assert(nft != null, "Token does not exist.");
return new NFTDetails
{
TokenId = input.Value,
Name = nft.Name,
Symbol = nft.Symbol,
Owner = nft.Owner
};
}

public override Int64Value GetNFTBalance(Address input)
{
return State.NFTBalances[input] ?? new Int64Value { Value = 0 };
}

public override StringValue GetOwner(Int64Value input)
{
var nft = State.NFTTokens[input.Value];
Assert(nft != null, "Token does not exist.");
return new StringValue { Value = nft.Owner.ToString() };
}
}
}
22 changes: 22 additions & 0 deletions Backend/NFTState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using AElf.Sdk.CSharp.State;
using AElf.Types;
using Google.Protobuf.WellKnownTypes;

namespace AElf.Contracts.nft_contract
{
// The state class is access the blockchain state
public partial class nft_contractState : ContractState
{
public BoolState Initialized { get; set; }
public SingletonState<Address> Owner { get; set; }
public MappedState<long, NFTToken> NFTTokens { get; set; }
public MappedState<Address, Int64Value> NFTBalances { get; set; }
public Int64State TokenCounter { get; set; }
}
public class NFTToken
{
public string Name { get; set; }
public string Symbol { get; set; }
public Address Owner { get; set; }
}
}
91 changes: 91 additions & 0 deletions Backend/nft_contract.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
syntax = "proto3";

import "aelf/core.proto";
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.nft_contract";

service nft_contract {
option (aelf.csharp_state) = "AElf.Contracts.nft_contract.nft_contractState";
option (aelf.base) = "Protobuf/reference/acs12.proto";

rpc Initialize (google.protobuf.Empty) returns (google.protobuf.Empty) {}

rpc CreateNFTToken (CreateNFTTokenInput) returns (google.protobuf.Int64Value) {}

rpc TransferNFT (TransferNFTInput) returns (google.protobuf.Empty) {}

rpc BurnNFT (google.protobuf.Int64Value) returns (google.protobuf.Empty) {}

rpc GetNFTDetails (google.protobuf.Int64Value) returns (NFTDetails) {
option (aelf.is_view) = true;
}

rpc GetNFTBalance (aelf.Address) returns (google.protobuf.Int64Value) {
option (aelf.is_view) = true;
}

rpc GetOwner (google.protobuf.Int64Value) returns (google.protobuf.StringValue) {
option (aelf.is_view) = true;
}
}

// Define request message for CreateNFTToken
message CreateNFTTokenInput {
string name = 1;
string symbol = 2;
}

// Define request message for TransferNFT
message TransferNFTInput {
int64 token_id = 1;
aelf.Address to = 2;
}

// An event that will be emitted from contract method call when CreateNFT is called.
message NFTCreated {
option (aelf.is_event) = true;
int64 nft_id = 1;
}

// An event that will be emitted from contract method call when CreateNFTCollection is called
message NFTCollectionCreated {
option (aelf.is_event) = true;
int64 nft_id = 1;
}

// An event that will be emitted from contract method call when TransferNFT is called.
message NFTTransferred {
option (aelf.is_event) = true;
int64 token_id = 1;
aelf.Address from = 2;
aelf.Address to = 3;
}

// An event that will be emitted from contract method call when BurnNFT is called.
message NFTBurned {
option (aelf.is_event) = true;
int64 token_id = 1;
aelf.Address owner = 2;
}

// Define message for NFT details
message NFTDetails {
int64 token_id = 1;
string name = 2;
string symbol = 3;
aelf.Address owner = 4;
}

// An event that will be emitted from contract method call when Deposit is called.
message DepositEvent {
option (aelf.is_event) = true;
int64 amount = 1;
string symbol = 2;
aelf.Address from = 3;
aelf.Address to = 4;
}
144 changes: 144 additions & 0 deletions ToDo/ToDo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
using Google.Protobuf.WellKnownTypes;
using System.Collections.Generic;
using AElf.Types;

namespace AElf.Contracts.ToDo
{
public class ToDo : ToDoContainer.ToDoBase
{
public override Empty Initialize(Empty input)
{
if (State.Initialized.Value)
{
return new Empty();
}

State.Initialized.Value = true;
State.Owner.Value = Context.Sender;
State.TaskIds.Value = ""; // Initialize empty string for task IDs
State.TaskCounter.Value = 0; // Initialize task counter

return new Empty();
}

public override StringValue CreateTask(TaskInput input)
{
if (!State.Initialized.Value)
{
// Handle uninitialized state
return new StringValue { Value = "Contract not initialized." };
}

var taskId = (State.TaskCounter.Value + 1).ToString();
State.TaskCounter.Value++;

var timestamp = Context.CurrentBlockTime.Seconds;

var task = new CustomTask
{
Name = input.Name,
Description = input.Description,
Category = input.Category,
Status = "Pending",
CreatedAt = timestamp,
UpdatedAt = timestamp
};

State.Tasks[taskId] = task;
State.TaskExistence[taskId] = true; // Mark task as existing

// Append task ID to the list of IDs
var existingTaskIds = State.TaskIds.Value;
if (!string.IsNullOrEmpty(existingTaskIds))
{
existingTaskIds += ",";
}
existingTaskIds += taskId;
State.TaskIds.Value = existingTaskIds;

return new StringValue { Value = taskId };
}

public override Empty UpdateTask(TaskUpdateInput input)
{
var task = State.Tasks[input.TaskId];
task.Name = input.Name ?? task.Name;
task.Description = input.Description ?? task.Description;
task.Category = input.Category ?? task.Category;
task.Status = input.Status ?? task.Status;
task.UpdatedAt = Context.CurrentBlockTime.Seconds;

State.Tasks[input.TaskId] = task;

return new Empty();
}

public override Empty DeleteTask(StringValue input)
{

State.Tasks.Remove(input.Value);
State.TaskExistence.Remove(input.Value); // Remove task existence record

// Remove task ID from the list of IDs
var existingTaskIds = State.TaskIds.Value.Split(',');
var newTaskIds = new List<string>();
foreach (var taskId in existingTaskIds)
{
if (taskId != input.Value)
{
newTaskIds.Add(taskId);
}
}
State.TaskIds.Value = string.Join(",", newTaskIds);

return new Empty();
}

public override TaskList ListTasks(Empty input)
{
var taskList = new TaskList();
var taskIds = State.TaskIds.Value.Split(',');

foreach (var taskId in taskIds)
{
var task = State.Tasks[taskId];
if (task != null)
{
taskList.Tasks.Add(new Task
{
TaskId = taskId,
Name = task.Name,
Description = task.Description,
Category = task.Category,
Status = task.Status,
CreatedAt = task.CreatedAt,
UpdatedAt = task.UpdatedAt
});
}
}

return taskList;
}

public override Task GetTask(StringValue input)
{
var customTask = State.Tasks[input.Value];
if (customTask == null)
{
// Handle task not found
return new Task { TaskId = input.Value, Name = "Task not found." };
}

return new Task
{
TaskId = input.Value,
Name = customTask.Name,
Description = customTask.Description,
Category = customTask.Category,
Status = customTask.Status,
CreatedAt = customTask.CreatedAt,
UpdatedAt = customTask.UpdatedAt
};
}
}
}
25 changes: 25 additions & 0 deletions ToDo/ToDoState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using AElf.Sdk.CSharp.State;
using AElf.Types;

namespace AElf.Contracts.ToDo
{
public class ToDoState : ContractState
{
public BoolState Initialized { get; set; }
public SingletonState<Address> Owner { get; set; }
public MappedState<string, CustomTask> Tasks { get; set; } // Mapping of task ID to Task
public MappedState<string, bool> TaskExistence { get; set; } // Mapping to track task existence
public StringState TaskIds { get; set; } // Concatenated string of task IDs
public Int32State TaskCounter { get; set; } // Counter for generating unique IDs
}

public partial class CustomTask
{
public string Name { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public string Status { get; set; }
public long CreatedAt { get; set; }
public long UpdatedAt { get; set; }
}
}
Loading