目前主流的合约开发主要有ETH的solidity,Solana的bpf(linux中常用)以及wasm;对于这些合约的开发,每条公链接都有自己的工具和框架,降低开发者在使用中的难度;今天就挑了三个对比,他们分别是 ETH的hardhat工具,Solana的anchor和substrate的ink!,我来为大家科普一下关于开发合约系统?以下内容希望对你有帮助!

开发合约系统(主流合约框架对比)

开发合约系统

目前主流的合约开发主要有ETH的solidity,Solana的bpf(linux中常用)以及wasm;对于这些合约的开发,每条公链接都有自己的工具和框架,降低开发者在使用中的难度;今天就挑了三个对比,他们分别是 ETH的hardhat工具,Solana的anchor和substrate的ink!。

你将了解如下的内容:

  1. 工具/框架的使用方法
  2. 自动生成的模版以及如何进行简单的开发
  3. 综合对比
框架的使用和代码分析ETH hardhat

官方doc

官方Tutorial

环境配置:因为需要使用 Ethers.js 进行测试和交互,所以需要安装node.js;

安装:npm install --save-dev hardhat

初始化项目:在项目中执行 npx hardhat,经过提示,选择自己要使用的模版,然后会在根目录中创建必要的文件和目录;

. ├── README.md ├── contracts │ └── Greeter.sol ├── hardhat.config.js ├── node_modules ├── package-lock.json ├── package.json ├── scripts │ └── sample-script.js └── test └── sample-test.js

可以看到框架已经帮我们分好了目录,其中contracts目录下是具体的solidity合约代码;scripts中是部署合约需要的代码;test中是测试代码;

编译:npx hardhat complie

部署: npx hardhat run scripts/deploy.js --network <network-name>

require("@nomiclabs/hardhat-waffle"); // Go to https://www.alchemyapi.io, sign up, create // a new App in its dashboard, and Replace "KEY" with its key const ALCHEMY_API_KEY = "KEY"; // Replace this private key with your Ropsten account private key // To export your private key from Metamask, open Metamask and // go to Account Details > Export Private Key // Be aware of NEVER putting real Ether into testing accounts const ROPSTEN_PRIVATE_KEY = "YOUR ROPSTEN PRIVATE KEY"; module.exports = { solidity: "0.8.4", networks: { ropsten: { url: `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_API_KEY}`, accounts: [`${ROPSTEN_PRIVATE_KEY}`] } } };

测试:npx hardhat test

由于hardhat自带本地ETH网络,所以不需要启动节点可以通过web3接口进行测试;

Debug:

1. 在合约代码中添加 ```import "hardhat/console.sol";``` 导入日志工具; 2. 在需要使用的代码中通过 ```console.log("info %s", to);```的方式打印一些需要的调试信息; 3. 最后使用``` npx hardhat test``` 会输出调试信息;

Solana Anchor

官方文档

依赖安装配置:

  1. 安装rust
  2. 安装solana
  3. 安装node.js和yarn并且换源
  4. 安装anchor

初始化项目:

运行 anchor init <new-project-name>

. ├── Anchor.toml // Anchor 配置文件 ├── Cargo.toml // Rust 工作区配置文件。 ├── app // 应用程序前端的目录 ├── migrations // 合约迁移部署的代码 │ └── deploy.ts ├── node_modules ├── package.json ├── programs // 合约逻辑代码 │ └── test │ ├── Cargo.toml │ ├── Xargo.toml │ └── src └── lib.rs ├── tests // 合约测试 │ └── test.ts ├── tsconfig.json └── yarn.lock

编译:anchor build

编译的命令是下面两条命令的组合; 1. `cargo build-bpf` 2. `anchor idl parse -f program/src/lib.rs -o target/idl/basic_0.json`

测试:anchor test

部署:anchor deploy

Anchor.toml文件中可以定义部署的网络环境和钱包信息等数据

[provider] cluster = "localnet" wallet = "~/.config/solana/id.json"

示例代码

use anchor_lang::prelude::*; declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); #[program] mod basic_1 { use super::*; pub fn initialize(ctx: Context<Initialize>, data: u64) -> ProgramResult { let my_account = &mut ctx.accounts.my_account; my_account.data = data; Ok(()) } pub fn update(ctx: Context<Update>, data: u64) -> ProgramResult { let my_account = &mut ctx.accounts.my_account; my_account.data = data; Ok(()) } } #[derive(Accounts)] pub struct Initialize<'info> { #[account(init, payer = user, space = 8 8)] pub my_account: Account<'info, MyAccount>, #[account(mut)] pub user: Signer<'info>, pub system_program: Program<'info, System>, } #[derive(Accounts)] pub struct Update<'info> { #[account(mut)] pub my_account: Account<'info, MyAccount>, } #[account] pub struct MyAccount { pub data: u64, } #[error] pub enum ErrorCode { #[msg("This account cannot update")] CannotUpdate, }

示例代码解析ink!

官方Doc

安装依赖:

  1. 安装rust
  2. 安装cargo和wasm依赖
  3. 安装contracts-node

初始化项目:

使用命令创建新的合约项目:cargo contract new <new project name>

flipper └─ lib.rs <-- Contract Source Code └─ Cargo.toml <-- Rust Dependencies and ink! Configuration └─ .gitignore

编译:cargo nightly contract build

测试:cargo nightly test

部署:直接在节点的UI界面上传编译之后的文件(target目录下的.contract结尾的文件),substrate的部署和运行时分开的,同一份代码只能部署一份,但是可以有很多的运行实例;

示例代码:

// We are importing the default ink! types use ink_lang as ink; #[ink::contract] mod MyContract { // Our struct will use those default ink! types #[ink(storage)] pub struct MyContract { number: u32, } impl MyContract { /// Constructor that initializes the `u32` value to the given `init_value`. #[ink(constructor)] pub fn new(init_value: u32) -> Self { Self { number: init_value, } } #[ink(message)] pub fn my_public_function(&self) { /* --snip-- */ } /// Private function fn my_private_function(&self) { /* --snip-- */ } } } self.env().emit_event() // 用于发出event,向外界提示信息,可以认为和Solana Anchor中的console.log类似 self.env().caller() // 表示合约的调用者,solana中会使用programID来表示;

派生宏介绍总提对比

平台 / 框架

代码模板优势

特点

难度

ETH / Hardhat

包括部署目录,合约目录,测试目录,拆分比较详细,结构很清晰

主要是对代码模块逻辑进行拆分,没有对solidity进行过多的封装,原生迁移比较容易;

需要了解solidity和javascript

Solana / Anchor

包括部署目录,合约目录,测试目录,拆分比较详细,结构很清晰

进行了很多的宏封装,将很多instructions和account进行包装,虽然简化了开发难度和代码量,但是对与刚了解solana的开发者不太容易理解细节;

需要了解solana的交易和account含义,并且要会rust

Substrate / ink!

单纯地包含了合约代码,比较简洁

进行了一些封装,简化了开发难度,但是自由度比较高,不用太局限于太多的细节;

需要会rust,对小白用户比较友好

,