# 编程日记：测试链部署合约（2022-08-22）

By [Corror](https://paragraph.com/@corror) · 2022-08-25

---

编程学习
----

### 内容目录

1.  安装环境
    
2.  迁移智能合约
    
3.  编译智能合约
    
4.  部署智能合约
    
    1.  方法一：contract factoty
        
        1.  准备 Provider, 用于和网络建立连接；
            
        2.  准备 Wallet, 用于签署交易；
            
        3.  创建 contract factory, 并提供 .abi, .bin 以及 Wallet 来获取实例。
            
        4.  通过 contract factory 的 deploy 方法，将合约部署至以太坊网络上。
            
    2.  方法二：raw transaction
        
        1.  将 transaction 用 raw 的形式 `tx = {}` 写出来。
            
        2.  使用钱包的 `sendTransaction()` 方法，为 tx 进行签名和发送。
            
5.  **_td_** 交互智能合约
    

### 做了什么？

成功部署合约

1.  准备阶段：
    
    1.  成功利用 ethers.js 中的 JsonRpcProvider, 建立连接起了程序和网络的连接，让程序和网络之间可以实现通讯；
        
    2.  成功利用 ehters.js 中的 Signer, 创建了用于签名交易的钱包 (wallet)；
        
    3.  成功利用 Node.js 文件系统，导入了 .abi 接口文件以及 .bin 二进制文件，从而提供了合约的具体内容。
        
2.  部署阶段：
    
    1.  成功利用 abi, bin 和 wallet 创建了 contract factory, 为部署合约提供了 initcode.
        
    2.  成功部署了 initcode, 并发送了 initcode transaction, 从而成功部署了合约。
        
    3.  成功确认了 initcode transaction, 并获得了交易收据。
        

### 收获了什么？

#### Provider 与 Wallet 的含义和作用

含义：

*   Provider 是一种接口，它负责为钱包和网络建立起连接；
    
*   Wallet 是和以太坊账户相关的一种类，它负责使用私钥来对消息和交易进行签名。
    

作用：是合约部署准备过程的一部分：

1.  准备 Provider 和 Wallet.
    
2.  准备智能合约的 .bin 和 .abi 格式。
    

用法：

    const provider = new ethers.providers.JsonRpcProvider(url);
    

    const Wallet = new ethers.Wallet(privateKey, provider);
    

#### UTF-8 与 Character Encoding 的关系

含义：

*   Character Encoding 是指字符编码，它定义了字节和文本之间的映射关系 (a mapping between bytes and text).
    
*   UTF-8 是最常用的字节和文本之间的映射关系。
    

关联：

每一串字节都可以根据不同的映射关系，被解释成为不同的文本，而 UTF-8 就是最常用的字符编码 (Character Encoding).

用法：

    fs.readFileSync(path, "utf8");
    

#### Contract Factory

概念：Contract Factory 是一种类，它负责用来创建合约。

原理：Contract Factory 可以在实例化后发送一种特殊的交易 (initcode transaction), 该交易的结果是一串代码，它会被部署为新的 contract.

应用：

    async function deploy() {
        const factory = new ethers.ConstractFactory(abi, bin, wallet);
        const constract = await factory.deploy();
    }
    

这里的 `factory.deploy()` 方法之前需要加 `await` 的原因是：根据 [ehter.js](https://docs.ethers.io/v5/api/contract/contract-factory/#ContractFactory-deploy) 可以知道，该方法会返回一个 `Promise< Constract >`, 因此需要通过 async 和 await 来处理返回值 Promise。

如果既不不加 `async` 也不加 `await`, 那么在处理返回值 Promise 的时候，会由于不认识 `.then()` 方法而导致报错。

**所以，如果要处理 Promise, 那么一定需要写上** `async` 和 `await`.

#### 交易部署逻辑

原理：

1.  先运行 transaction factory 的 `deploy()` 方法，将 transaction factory 部署至以太坊网络上；
    
2.  再运行 transaction factory 的`deployTransaction()` 方法，从而真正将智能合约部署在以太坊网络当中，并获得 transaction response;
    
3.  最后，在以太坊网络响应了 transaction response 并经过区块确认交易后，会获得 transaction receipt，即我们在区块链浏览器上所看见的交易账单。
    

步骤：[参考代码](https://docs.ethers.io/v5/api/contract/contract-factory/#ContractFactory-deploy)

1️⃣ 部署 Transaction Factory

    const contract = factory.deploy();
    

2️⃣ 部署智能合约

    constract.deployTransaction
    

3️⃣ resolve 交易收据

    contract.deployTransaction.wait()

---

*Originally published on [Corror](https://paragraph.com/@corror/2022-08-22)*
