智能合约简单教程
简介
本文主要介绍使用文昌链 EVM 模块的基本流程。
文昌链 EVM 模块完全兼容以太坊(ERC20 的转账功能根据合规要求做了限制),可直接使用以太坊生态工具进行对接。
一、Remix 教程
配置 MetaMask 连接测试网
- RPC: https://evmrpc.testnet.bianjie.ai
- Chain ID: 12231
- Symbol: gas
- Explorer: https://explorer.testnet.bianjie.ai
填写完毕后点击保存。
账户充值
在 MetaMask 中复制测试用的链账户地址,发给文昌链技术支持获取测试能量值。
Remix 操作
1. 打开 Remix
访问地址是:https://remix.ethereum.org/
2. 创建工作空间
3. 清理空间,并编写合约
4. 编译合约
默认合约是自动编译的,如果合约没有问题,可以自动编译
5.连接钱包
6. 部署合约
7. 调整费用,执行部署(irita 的话建议调整一下,我们的 gasprice 很低)
执行合约,报后点击确认,得到如下信息:
8. 操作合约
- 操作方法牵扯到链上状态更改需要和部署合约时一样,进行签名
- get的方法不需要签名,直接可以访问
二、hardhat 教程
准备工作
# 创建文件夹
mkdir contract-demo-hardhat
# 进入文件夹
cd contract-demo-hardhat
流程
1. 初始化
yarn init -y
2. 安装hardhat
yarn install -D hardhat
3. 初始化项目
yarn hardhat
选择如下的选项
会出现一堆下载依赖的过程,可能会有网络问题,挂 outline
4. 安装一些常用的依赖(可以跳过)
yarn add -D @openzeppelin/hardhat-defender @nomiclabs/hardhat-web3 @openzeppelin/hardhat-upgrades @openzeppelin/contracts-upgradeable hardhat-abi-exporter hardhat-contract-sizer
# @openzeppelin/contracts
# @openzeppelin/contracts-upgradeable
5. 整理项目
5.1 删除不必要的文件
- 删除 scripts文件夹中的ts 文件
- 删除 contracts中的Getter合约
- 删除 test的关于Getter合约的测试
- 修改package.json脚本:
 "scripts": {
    "compile": "yarn hardhat compile",
    "clean": "yarn hardhat clean",
    "test": "hardhat test",
    "typecheck": "yarn compile && yarn test && yarn tsc --noEmit"
  },
5.2 修改 hardhat.config.ts
删除不必要的引用,改为类似的结构:
import { HardhatUserConfig, task } from "hardhat/config";
import "@nomiclabs/hardhat-etherscan";
import "@nomiclabs/hardhat-waffle";
import "@typechain/hardhat";
import "@openzeppelin/hardhat-upgrades";
import "@openzeppelin/hardhat-defender";
import "@nomiclabs/hardhat-ethers";
import "hardhat-gas-reporter";
import "hardhat-contract-sizer";
import "hardhat-abi-exporter";
import "solidity-coverage";
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
const config: HardhatUserConfig = {
  solidity: "0.8.4",
  networks: {
    testnet: {
      url: 'http://127.0.0.1:8545',
      gasPrice: 1,
      chainId: 1223,
      gas: 25000000,
      accounts: [''],
    },
  },
  gasReporter: {
    enabled: true,
    showMethodSig: true,
    maxMethodDiff: 10,
    currency: 'USD',
    gasPrice: 127,
  },
  contractSizer: {
    alphaSort: true,
    runOnCompile: true,
    disambiguatePaths: false,
  },
  paths: {
    sources: "./contracts",
    tests: "./test",
    cache: "./cache",
    artifacts: "./artifacts"
  },
  abiExporter: {
    path: './abi',
    runOnCompile: true,
    clear: true,
    spacing: 2
  }
};
export default config;
6. 创建合约
在 contracts 目录创建 Counter.sol文件,内容如下:
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
contract Counter {
    uint256 counter = 0;
    function add() public {
        counter++;
    }
    function subtract() public {
        counter--;
    }
    function getCounter() public view returns (uint256) {
        return counter;
    }
}
7. 编译合约
yarn compile
8. 编写测试
在 test 目录下新建 couter.ts 的文件,内容如下:
import { ethers } from "hardhat";
import { Signer } from "ethers";
import chai, { expect } from "chai";
import { Counter } from '../typechain';
describe("Counters", () => {
    let counterManger: Counter;
    before("Deploy Counter", async () => {
        const counterFactory = await ethers.getContractFactory("Counter");
        counterManger = await counterFactory.deploy();
        await counterManger.deployed();
    });
    it("counter should be incremented by 1 after calling add", async () => {
        const counterBefore = await counterManger.getCounter();
        await counterManger.add();
        const counterAfter = await counterManger.getCounter();
        expect(counterBefore.add(1)).to.equal(counterAfter);
    })
    it("counter should be subtracted by 1 after calling subtract", async () => {
        const counterBefore = await counterManger.getCounter();
        await counterManger.subtract();
        const counterAfter = await counterManger.getCounter();
        expect(counterBefore.sub(1)).to.equal(counterAfter);
    })
})
运行 yarn test
9. 编写部署脚本
当脚本完成后,我们就可以部署了,
创建 tasks 文件夹,并创建 :
- 
config.ts: 用来读取配置,
- 
counter.ts:部署脚本
在 hardhat.config.ts 中增加一行:import "./tasks/counter";
counter.ts 内容如下:
import "@nomiclabs/hardhat-web3";
import { error } from "console";
import { task, types } from "hardhat/config"
const config = require('./config')
task("deployCounter", "Deploy Counter")
    .setAction(async (taskArgs, hre) => {
        await config.load(async function (env: any) {
            const counterFactory = await hre.ethers.getContractFactory('Counter');
            const counterManager = await counterFactory.deploy();
            await counterManager.deployed();
            console.log("Counter deployed to:", counterManager.address);
            env.contract.counterAddress = counterManager.address
        }, true)
    });
task("addCounter", "Add Counter")
    .setAction(async (taskArgs, hre) => {
        await config.load(async function (env: any) {
            const counterFactory = await hre.ethers.getContractFactory('Counter');
            const counterManager = await counterFactory.attach(env.contract.counterAddress);
            for (let i = 0; i < env.params.times; i++) {
                const result = await counterManager.add();
                console.log(result);
            }
        }, true)
    });
task("subtractCounter", "Add Counter")
    .setAction(async (taskArgs, hre) => {
        await config.load(async function (env: any) {
            const counterFactory = await hre.ethers.getContractFactory('Counter');
            const counterManager = await counterFactory.attach(env.contract.counterAddress);
            for (let i = 0; i < env.params.times; i++) {
                const result = await counterManager.subtract();
                console.log(result);
            }
        }, true)
    });
task("getCount", "Get Counter")
    .setAction(async (taskArgs, hre) => {
        await config.load(async function (env: any) {
            const counterFactory = await hre.ethers.getContractFactory('Counter');
            const counterManager = await counterFactory.attach(env.contract.counterAddress);
            const result = await counterManager.getCounter();
            console.log(result);
        }, true)
    });
执行 yarn hardhat deployCounter --network testnet  完成部署
ABI 生成 Go 的文件
前置条件
安装 abigen: Downloads | go-ethereum 下载对应版本
生成 go 文件: 在 hardhat 工程文件中执行: abigen --abi abi/contracts/Counter.sol/Counter.json --pkg counter --out counter.go
把文件引入到你的项目即可
测试程序初始化
# 安装依赖
yarn install
# 编译
yarn compile
# 测试
yarn test
count add
yarn hardhat addCounter --network testnet
counter get
yarn hardhat getCount  --network testnet
 
      
    














