Top of OASIS Developer Guide: Translate EVM Contract to aelf’s
In the Top of OASIS hackathon, developers may need to translate their solidity contract to aelf compatible C# contract. In the following guide, we will use the Quadratic Funding contract as an example.
aelf contract development instructions
When developing aelf contracts, the first thing to define is the proto file.
The proto file is a file that defines GRpc methods and data structures in Google Protocol Buffers technology: https://developers.google.com/protocol-buffers/docs/overview.
In short, during the development of aelf contracts, the proto file has the role of defining method interfaces and data structures. The methods interfaces start with ‘rpc’ and are defined in the service module of the proto file; the data structures start with ‘message’ are defined directly in the proto file.
The above code defines the methods Initialize, RoundOver, Donate, GetAllProjects in QuadraticFundingContract, and a data structure named InitializeInput, the data structure is also used as the input type of the Initialize method.
Generating Contract Projects
Currently, contract projects can be generated by using the Code Generator project in the aelf scaffolding
Once generated, open the newly generated sln file to see the new contract project.
Implement The Contract Logic
Create XXXContract and XXXContractState files in the contract project.
The XXXContractState class needs to inherit from ContractState, which is used to define the State of the aelf contract. Developing the contract logic is essentially the process of writing how to read and write the public ledger of the aelf blockchain. Modifying any defined State means modifying the public ledger. Note that the name of XXXContractState is defined in the option (aelf.csharp_state) in the proto file, just keep it the same (when the code is generated, the proto will automatically find the file with the same name, and will report an error if it can’t find it, then create a new file with that name and recompile the contract).
XXXContract, we are accustomed to using partial to separate the implementation of different types of methods, need to inherit from the contract’s Base class. The base class is automatically generated, such as QuadraticFundingContract’s Base class name is:
The next step is to override the methods defined in the proto file using the override keyword in the XXXContract file.
Here is an analysis of how to implement the contract on aelf using C#, by comparing it to solidity’s Quadratic voting contract.
Interface definition means generating proto files.
There are three parts that need to be translated: methods, data structures, and events.
Sort out what needs to be translated by browsing the ManageableGrant.sol file.
(aelf contract method names are adjusted according to aelf other contracts and C# language style)
(The ‘uint256’ in solidity can be replaced with aelf.BigIntValue in future aelf versions.
But for this contract, using ‘int64’ in protobuf (google.protobuf.Int64Value), ‘long’ function in C# is sufficient.)
The finalized translation is as follows:
The fields that will be designed in the translation solidity to be modified by Ethernet WorldState are organized as follows.
The finalized translation is as follows:
Handling of onlyOwner
Simply add AssertSenderIsOwner to the first line of onlyOwner’s method.
When aelf implements a quadratic voting contract, a large number of token Transfer functions are involved. This requires a call to aelf’s system Token contract.
Preparing the cross-contract calls requires three steps.
Reference the corresponding proto file in the csproj file of the contract project.
Defining the contract reference property (ReferenceState) in the contract State file for the access level bit internal.
Assign a value to the reference with the contract address (a little interface-oriented programming: if the proto files of two contracts are the same, you can switch to call a different contract by modifying the address of the reference).
Referencing the proto file in the csproj file
To declare a reference to a Token contract, you need to introduce the proto file of the Token contract in the AElf.Contracts.QuadraticFunding.csproj file (using ContractReference, the relevant script is defined in the AElf.Contract.Tools. targets file in the project directory):
Declare the contract reference in the State file
The variable is then declared in the State file (a new partial file is created here):
Assigning a value to a contract reference
Before using the Token Contract, you need to set the address of the system Token Contract to State.TokenContract.Value, here you choose to set it during the initialization (https://github.com/AElfProject/aelf-quadratic-funding-) contract/blob/master/contract/AElf.Contracts.QuadraticFunding/QuadraticFundingContract.cs):
Cross-contract calls with Send and Call
Finally, you can call each method of the Token Contract by using State.TokenContract in the code, using Send for Action methods and Call for View methods, e.g.
In addition, you can also use Context.Send, Context.Call to achieve cross-contract calls, you just need to fill in the contract address, method name and parameters as described in the method parameter list.
The quadratic voting contract on aelf is as follows:
It can be read in conjunction with: