前言
在以太坊 DApp(去中心化应用)开发过程中,web3.js 是必不可少的一个 JavaScript 库。Web3.js 中的一些函数会返回一个 Promise,这时候需要使用 async/await 来处理异步操作。在进行这样的操作时,我们就需要对返回值进行类型检查,这使用 TypeScript 将会更加方便而且更加安全。而 TypeChain 就是一款用于生成类型化以太坊智能合约的工具,它可以将 Solidity 合约编译为 TypeScript 文件。
然而,使用 TypeChain 时需要指定目标合约环境。但是,如果使用 Truffle 来部署合约,就需要使用 Truffle's Contract abstraction。这就需要用到 typechain-target-truffle 这个 npm 包了。
本文将介绍如何使用 npm 包 typechain-target-truffle 来使 typechain 和 Truffle 进行无缝集成,以方便在以太坊 DApp 开发中的使用。
typechain-target-truffle 的安装
在开始使用 typechain-target-truffle 前,需要先在项目中安装 typechain 和 typechain-target-truffle。在终端中输入以下命令:
$ npm install --save-dev typechain typechain-target-truffle
安装完成后,我们就可以通过以下命令启动 TypeChain 了:
$ npx typechain --target=truffle --outPath=src/types --noEmit
这时候,Typechain 会生成 TypeScript 的接口和抽象类来表示我们的合约。这里的 outPath 是指 Typechain 将生成的文件输出到项目的哪个位置。
如果 target 默认为 ethererum,则需要按以下方式更改:
# remove current version yarn remove typechain typechain-target-truffle # install version 2 of typechain yarn add -D typechain@^2.0.0 yarn add -D typechain-target-ethers@^2.0.0
Truffle 合约定义
我们首先需要在 Truffle 中定义一个合约,以便将其与 TypeScript 对象进行同步。可以使用以下示例合约:
-- -------------------- ---- ------- ------ -------- ------- -------- -------- ------- - ------- ------ ------- - -- -------- ----------- ------ - ---------- - -------- ----------- ------ - ---------- - -
我们可以在 migrations 中定义合约的地址,然后将合约地址导入 TypeScript 中。
TypeScript 对象同步
TypeChain 创建的类型化合约抽象类和接口使用了 Truffle 的 Artifact
接口。我们需要使用 web3js-eea.artifacts
软件包中的 EnvelopingArtifactAdapter
类来获取与合约同步的抽象合约。以下是同步步骤:
import { EnvelopingArtifactAdapter } from "web3js-eea/artifacts"; import ExampleContract from "./artifacts/Example.json"; export async function createExampleContract(web3Provider: any) { const adapter = new EnvelopingArtifactAdapter(web3Provider); const contract = await adapter.createArtifactAsync(ExampleContract); return contract as any; }
这里,我们先将 Example.sol 编译成 json 形式,并将其保存在 /.artifacts 目录中。然后,使用 EnvelopingArtifactAdapter 类实例化合约抽象类。
添加 TypeScript Interface
接下来,我们需要将生成的 types 文件夹中的接口引入到我们的入口文件中。例如:
const exampleContractInterface = require("./types/Example").Example;
这样,我们就可以像使用普通的类型和接口一样,使用 exampleContractInterface 来访问合约。这将大大提高代码的简洁性和可读性。此外,Truffle Contract Abstraction 类的内置类型也可供使用。
合约部署和使用
使用 Truffle 部署合约时,我们需要使用网络名称作为参数。一个节点可以连接许多以太坊网络,而网络的名称可以由用户自行定义。看一下以下的示例代码:
-- -------------------- ---- ------- ------ ---- ---- ------- ------ - --------------------- - ---- -------------------- ----- ------------ - -------------- ----- -------- ----------------------------------- ---- - ----- -------- - ----- ------------------------------------ ----- ---- - --- ------------------- --------------------------------------- ------------ -- ---- ----- ---------------- - ----- -------------- ----- ------- ---- ------- --- --------------------- -------- -- ------------------------------ ------ ----------------- - ----- -------- -------------------------------- ---- - ----- -------- - ----- ------------------------------------ ----- ---------------- - ----- ---------------------- ----------- -------------------- ------ ------- ------------------------------ ----- ---------------------------- ----- ------ --- -------------------- ------ ------- ------------------------------ - ------ ---------- - ----- ------------ - --- ----------------------------------------------------- ----- ---------------- - ----- ------------------------------------ ----- --------------------------------- -----
其中,deployExampleContract 函数从 example.sol 合约创建了一个智能合约。同样地,useExampleContract 函数中我们可以更新 counter 的值。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/5eedac3db5cbfe1ea06109a2