Developing Smart Contracts
#
This guide shows how to develop a smart contract using the GreeterContract as an example. You’ll learn to create your own basic contract.
Steps for Developing Smart Contracts#
The Greeter contract includes an AddGreeters method to add a new greeter and a GetGreeters method to list all greeters.
Install Template#
1dotnet new --install AElf.ContractTemplates
1dotnet new uninstall
Initialize Project#
1dotnet new aelf -n GreeterContract -N AElf.Contracts.Greeter
This generates the following structure:
1.2├── src3│ ├── GreeterContract.cs4│ ├── GreeterContract.csproj5│ ├── GreeterContractState.cs6│ └── Protobuf7│ ├── contract8│ │ └── hello_world_contract.proto9│ └── message10│ └── authority_info.proto11└── test12├── GreeterContract.Tests.csproj13├── GreeterContractTests.cs14├── Protobuf15│ ├── message16│ │ └── authority_info.proto17│ └── stub18│ └── hello_world_contract.proto19└── _Setup.cs
1syntax = "proto3";23import "aelf/options.proto";4import "google/protobuf/empty.proto";5import "google/protobuf/wrappers.proto";6option csharp_namespace = "AElf.Contracts.Greeter";78service GreeterContract {9option (aelf.csharp_state) = "AElf.Contracts.Greeter.GreeterContractState";1011rpc AddGreeters (google.protobuf.StringValue) returns (google.protobuf.Empty) {}12rpc GetGreeters (google.protobuf.Empty) returns (GreeterList) {13option (aelf.is_view) = true;14}15}1617message GreeterList {18repeated string greeter = 1;19}
1using AElf.Sdk.CSharp;2using Google.Protobuf.WellKnownTypes;34namespace AElf.Contracts.Greeter5{6public class GreeterContract : GreeterContractContainer.GreeterContractBase7{8public override Empty AddGreeters(StringValue input)9{10Assert(!string.IsNullOrWhiteSpace(input.Value), "Invalid name.");1112var greeterList = State.GreeterList.Value ?? new GreeterList();13if (!greeterList.Greeter.Contains(input.Value))14{15greeterList.Greeter.Add(input.Value);16}17State.GreeterList.Value = greeterList;1819return new Empty();20}2122public override GreeterList GetGreeters(Empty input)23{24return State.GreeterList.Value ?? new GreeterList();25}26}27}
1using AElf.Sdk.CSharp.State;23namespace AElf.Contracts.Greeter4{5public class GreeterContractState : ContractState6{7public SingletonState<GreeterList> GreeterList { get; set; }8}9}
1using AElf.Cryptography.ECDSA;2using AElf.Testing.TestBase;34namespace AElf.Contracts.Greeter5{6public class Module : ContractTestModule<GreeterContract> { }78public class TestBase : ContractTestBase<Module>9{10internal readonly GreeterContractContainer.GreeterContractStub GreeterContractStub;11private ECKeyPair DefaultKeyPair => Accounts[0].KeyPair;1213public TestBase()14{15GreeterContractStub = GetGreeterContractContractStub(DefaultKeyPair);16}1718private GreeterContractContainer.GreeterContractStub GetGreeterContractContractStub(ECKeyPair senderKeyPair)19{20return GetTester<GreeterContractContainer.GreeterContractStub>(ContractAddress, senderKeyPair);21}22}23}
1using System.Threading.Tasks;2using Google.Protobuf.WellKnownTypes;3using Shouldly;4using Xunit;56namespace AElf.Contracts.Greeter7{8public class GreeterContractTests : TestBase9{10[Fact]11public async Task AddGreetersTest()12{13var user1 = new StringValue { Value = "Tom" };14var user2 = new StringValue { Value = "Jerry" };15var expectList = new GreeterList();16expectList.Greeter.Add(user1.Value);17expectList.Greeter.Add(user2.Value);1819await GreeterContractStub.AddGreeters.SendAsync(user1);20await GreeterContractStub.AddGreeters.SendAsync(user2);2122var greeterList = await GreeterContractStub.GetGreeters.CallAsync(new Empty());23greeterList.ShouldBe(expectList);24}25}26}
Edited on: 16 July 2024 05:34:15 GMT+0