草庐IT

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

区块链小萝卜 2023-04-09 原文

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. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  2. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

  3. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  4. iNFTnews | 周杰伦18年前未发布的作品Demo,藏在了区块链技术里 - 2

    当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在

  5. 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一) - 2

    前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型

  6. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  7. ruby - Ruby gems 的问题(损坏?)试图让指南针在 npm 中工作 - 2

    我不是Ruby专家,但想弄清楚发生了什么,因为我试图让指南针在节点应用程序中工作,但我的Ruby似乎坏了。打字:ruby--version让我:ruby2.1.1p76(2014-02-24revision45161)[x86_64-darwin13.0]我安装了Homebrew,之前遇到过Ruby版本的问题,但它似乎已安装并且可以正常工作。但是,当我使用gem输入请求时,出现此错误:$gem-hErrorloadingRubyGemsplugin"/Users/user_dir/.rvm/gems/ruby-2.1.1@global/gems/executable-hooks-1.3

  8. ruby - 使用指南针安装 bootstrap sass - 2

    我正在尝试安装bootstrap-sass并收到以下错误。我试过旧版本的sass,但bundler一直在安装3.3.0。WARN:UnresolvedspecsduringGem::Specification.reset:sass(~>3.2)WARN:Clearingoutunresolvedspecs.Pleasereportabugifthiscausesproblems./Library/Ruby/Gems/2.0.0/gems/compass-0.12.2/lib/compass/sass_extensions/monkey_patches/browser_support.r

  9. JMockit 使用指南 - 2

    目录配置模拟模拟类型与实例期望录制-回放-验证指定调用计数验证指定自定义结果验证调用参数联级模拟部分模拟模拟未实现的类其他伪装伪装方法及类伪装未实现类本文主要内容如何在SpringBoot中配置使用JMockit如何mock/faking依赖的对象如何对行为mock如何VerificationJMockit之所以强大,是因其使用了javaagent对类的字节码做了修改,在JVM的所有mock工具中,它是功能最强大的。同时注解又是最少的。配置在SpringBoot项目中使用JMockit隔离代码做单元测试,需要做以下配置引入JMockit依赖。dependencies>dependency>gr

  10. ruby-on-rails - 是否有针对经验丰富的 Ruby 开发人员的 Rails 指南? - 2

    几年前,我从一些Rails初学者指南开始学习Ruby/Rails。那时我已经学习了Rails的基础知识,例如模型和路由的一些约定优于配置,以及如何使用helpers等。但是,我并没有坚持多久,因为此后不久我发现了Sinatra,并决定我个人更喜欢它。不过,我最终真的爱上了Ruby,从那以后我写了很多Ruby,几乎没有一个是针对任何Rails项目的。然而,事实证明大部分可用的Ruby工作都是针对Rails应用程序的。所以我现在想再尝试一下Rails。现在,该引用资料很棒并且有很多有用的信息,但我只查看了我需要的特定内容的引用资料,而没有记住。但我不太可能在引用资料中看到像script/c

随机推荐