2021年12月12日,aelf元宇宙黑客马拉松正式开启,为帮助更多的开发者快速加入aelf生态,开发更多创新项目,aelf特别开放黑客马拉松开发指南系列课程。

在本期aelf区块链开发指南中,aelf首席技术官Ean以Quadratic Funding合约为例,针对“如何将以太坊合约转为aelf合约?”的问题进行讲解。开发者可参考此教程将solidity语言翻译为C#语言,完成以太坊合约到aelf合约的转移。

**

aelf合约开发步骤

**

Proto文件

在开发aelf合约时,首先要定义的是proto文件。

proto文件是Google Protocol Buffers技术中定义GRpc方法和数据结构的文件:

https://developers.google.com/protocol-buffers/docs/overview。

简而言之,proto文件在aelf合约开发过程中,有定义方法接口和数据结构的作用。方法以rpc开头,定义在proto文件的service模块中;数据结构以message开头,直接定义在proto文件里。

比如:

service QuadraticFundingContract {option (aelf.csharp_state) = "AElf.Contracts.QuadraticFunding.QuadraticFundingContractState";rpc Initialize (InitializeInput) returns (google.protobuf.Empty) {}// Only Owner.rpc RoundOver (google.protobuf.Empty) returns (google.protobuf.Empty) {}...// Others.rpc Donate (google.protobuf.Int64Value) returns (google.protobuf.Empty) {}...rpc GetAllProjects (google.protobuf.Int64Value) returns (ProjectList) {option (aelf.is_view) = true;}}message InitializeInput {aelf.Address owner = 1;string vote_symbol = 2;int64 basic_voting_unit = 3;
}
...

以上代码的作用是在QuadraticFundingContract中定义了Initialize、RoundOver、Donate、GetAllProjects等方法,并定义了一个名为InitializeInput的数据结构,该数据结构同时作为了Initialize方法的入参类型。

生成合约项目

目前,可以使用aelf脚手架中的Code Generator项目来生成合约项目:https://github.com/AElfProject/aelf-boilerplate/tree/dev/chain/src/AElf.Boilerplate.CodeGenerator

生成完毕后,打开新生成的sln文件即可看到新合约的项目。

实现合约逻辑

在合约项目中新建XXXContract和XXXContractState文件。

XXXContractState类需要继承自ContractState,该类用于定义aelf合约的State。写合约逻辑本质上就是写如何读写aelf区块链的公共账本的过程。修改任何定义的State都意味着修改公共账本。注意,XXXContractState的名字定义于proto文件中的option (aelf.csharp_state),保持一致即可(在代码生成时,protoc会自动找该同名文件,找不到会报错,这时候新建一个该文件,重新编译合约即可)。

XXXContract,我们习惯上使用partial将不同类型方法的实现分开,需要继承自该合约的Base类。Base类是自动生成的,如QuadraticFundingContract的Base类名为:

QuadraticFundingContractContainer.QuadraticFundingContractBase。

接下来在XXXContract文件中使用override关键字重写proto文件中所定义的方法即可。

下面我们通过对照solidity的二次方投票合约,分析一下如何在aelf上使用C#实现该合约。

接口定义

接口定义即写proto文件。有三部分需要翻译:方法、数据结构、事件。通过浏览ManageableGrant.sol文件,整理以下需要翻译的内容:

最终完成的翻译如下:

https://github.com/AElfProject/aelf-quadratic-funding-contract/blob/master/protobuf/quadratic_funding_contract.proto

State定义

翻译solidity中会设计以太坊WorldState修改的字段,整理如下:



最终完成的翻译如下:

https://github.com/AElfProject/aelf-quadratic-funding-contract/blob/master/contract/AElf.Contracts.QuadraticFunding/QuadraticFundingContractState.cs

逻辑实现

onlyOwner的处理

在onlyOwner的方法的第一行添加AssertSenderIsOwner即可:

private void AssertSenderIsOwner(){Assert(State.Owner.Value != null, "Contract not initialized.");Assert(Context.Sender == State.Owner.Value);}

参考:

https://github.com/AElfProject/aelf-quadratic-funding-contract/blob/master/contract/AElf.Contracts.QuadraticFunding/QuadraticFundingContract_OnlyOwner.cs

抛出事件

Demo:

Context.Fire(new TaxPointChanged{TaxPoint = input.Value});

跨合约调用

在aelf实现二次方投票合约时,涉及大量的代币Transfer功能。这就需要调用aelf的系统Token合约。

准备跨合约调用需要三个步骤:

1.在合约项目的csproj文件引用对应proto文件;

2.在合约State文件中定义访问级别位internal的合约引用属性(ReferenceState);

3.用合约地址为该引用赋值(有一点面向接口编程的意思:如果两个合约的proto文件一致,可以通过修改该引用的地址,来切换调用不同的合约)。

csproj文件中引用proto文件

声明Token合约的引用,需要现在AElf.Contracts.QuadraticFunding.csproj文件中引入Token合约的proto文件(使用ContractReference,相关脚本定义于项目目录的AElf.Contract.Tools.targets文件中):

State文件中声明合约引用

然后在State文件中声明该变量(这里新建了一个partial文件):

https://github.com/AElfProject/aelf-quadratic-funding-contract/blob/master/contract/AElf.Contracts.QuadraticFunding/QuadraticFundingContractReferenceState.cs

为合约引用赋值地址

在使用Token合约之前,需要给State.TokenContract.Value设置上系统Token合约的地址,这里选择在初始化的时候设置上(https://github.com/AElfProject/aelf-quadratic-funding-contract/blob/master/contract/AElf.Contracts.QuadraticFunding/QuadraticFundingContract.cs):

***加粗样式***用Send和Call进行跨合约调用

最后,在代码中使用State.TokenContract即可通过调用Token合约的各个方法了。Action方法使用Send调用,View方法使用Call调用,如:

除此之外,也可以使用Context.Send、Context.Call来实现跨合约调用,只需要按方法参数列表说明填入合约地址、方法名、参数即可。

aelf上的二次方投票合约如下:

https://github.com/AElfProject/aelf-quadratic-funding-contract/tree/master/contract/AElf.Contracts.QuadraticFunding

可以结合https://github.com/dorahacksglobal/qf-grant-contract/blob/master/others/ManageableGrant.sol一起阅读。

aelf区块链开发指南(一) | 如何将以太坊合约转为aelf合约?相关推荐

  1. 区块链开发(十四)以太坊go-ethereum客户端查询交易列表探讨

    比特币是可以通过api(listtransactions)查询指定地址的历史交易的.但在eth中没有提供类似的查询api.Hyperledger fabric也有相应的查询历史交易记录的方法,利用如下 ...

  2. 区块链开发(十五)以太坊中的Events和Logs解析及用途

    以太坊中的事件(Events)和日志(Logs)是个特别让人困惑的概念,本文帮大家梳理. 因为上篇文章,我们讨论过以太坊go-ethereum客户端查询交易列表的一些办法,这篇文章,我们具体实现一种f ...

  3. 区块链开发(五)搭建以太坊区块链浏览器

    经过前面文章介绍,已经搭建以太坊的区块链环境,但是没有一个界面能查看到区块链的块数等信息,不是很直观,本篇搭建以太坊区块链浏览器. 下载区块链浏览器代码 uiran@cuiran:~/ethereum ...

  4. 区块链开发指南_区块链开发权威指南

    区块链开发指南 by Haseeb Qureshi 由Haseeb Qureshi 区块链开发权威指南 (The authoritative guide to blockchain developme ...

  5. 《区块链开发指南》一一导读

    前 言 Preface 比特币于2009年诞生,在很长一段时间内,人们只知比特币,不知区块链.从2015年开始,区块链像狂风一样席卷全球,倍受金融界和科技界的关注:2015年年底,区块链技术逐渐得到国 ...

  6. 003《区块链开发指南》一一1.2 区块和区块链 转

    摘要:             本节书摘来自华章计算机<区块链开发指南>一书中的第1章,第1.2节,作者:申屠青春 主编 宋 波 张 鹏 汪晓明 季宙栋 左川民 编著更多章节内容可以访问云 ...

  7. 【翻译】How To Become A Blockchain Developer: Crash Course! 区块链开发指南!

    为什么80%的码农都做不了架构师?>>>    In this guide, we are going to map out your journey for becoming a ...

  8. 区块链学堂(6):以太坊生产网络/测试网络/私有网络

    区块链学堂(6):以太坊生产网络/测试网络/私有网络 要理解以太坊 PrivateNetwork 先要理解以太坊的两种官方网络 目前以太坊官方提供了两种网络 生产环境网络 测试网络 TestNet 下 ...

  9. 向别人网页注入js_区块链研究实验室 | Web3 .js基于以太坊的Javascript API

    web3.js是一个库集合,你可以使用HTTP或IPC连接本地或远程以太它节点进行交互. web3的JavaScript库能够与以太坊区块链交互. 它可以检索用户帐户,发送交易,与智能合约交互等. V ...

最新文章

  1. ValueError: invalid literal for int() with base 10: “ ”
  2. mysql centos7 默认密码忘记_centos7 mysql忘记密码解决办法
  3. 1个系统节拍 c语言_自己写的非抢占式嵌入式操作系统ATOS,全c语言,移植太......
  4. ebs 供应商地点信息_实探荣耀办公地:与高通接近达成合作,加快供应商整合脚步...
  5. 在以阶段划分的编译过程中,判断程序语句的形式是否正确属于()阶段的工作。
  6. MapReduce分区-原理
  7. 把准脉搏 U-Mail邮件系统2014开足马力
  8. java 记录考勤记录_Java中的记录器– Java记录示例
  9. 为系统安装盘集成Server Pack补丁包
  10. matlab可达矩阵 结果,matlab可达矩阵
  11. Codesys学习调试笔记1
  12. 网页设计html图片滚动特效,网站设计|滚动特效全面讲解!
  13. 理想,努力了才叫梦想,放弃了那只是妄想
  14. Pytorch:VGG16
  15. 卡尔曼(Kalman)滤波(四)--深入浅出Kalman滤波算法
  16. javacv实现屏幕录制(一)
  17. 【Python游戏】咱就说Python实现一个蔡徐坤大战篮球的小游戏,可还行? | 附带源码
  18. CountDownLatch闭锁,join和yield的区别
  19. 原生js获取元素的子元素
  20. 基础理论—需求定律与供给定律分析…

热门文章

  1. OSGI实战中的问题:Exception in org.eclipse.datatools.enablement.oda.ws.ui.Activator.start()
  2. js运算符 ~~ 是什么意思?
  3. 运算放大器 - 运放   OPA541AP
  4. wordpress图片插件比较Foo Gallery,GT3 Photo Video Gal,Photo Gallery,NextGen Gallery
  5. 13Python基础-总结(五子棋小游戏)
  6. DSP中的EALLOW和EDIS
  7. 2022.4.19百度笔试记录
  8. 一种海量数据安全分类分级架构的实现
  9. mac 切换php,Mac切换php版本方法
  10. 银河麒麟V10 SP2搭建vsftp服务