Skip to main content

Week13 - 9.26

Day1 存储抵押

Conflux Core Space 引入了存储抵押 (CFS) 机制作为使用存储的定价方法。与以太坊的一次性存储费相比,CFS 机制会更加公平合理。原则上,该机制需要锁定一定数量的资金作为抵押品来占用存储空间。在相应的存储空间被释放或被他人覆盖之前,抵押品将被锁定,锁定的CFX产生的相应利息将直接分配给矿工,用于维护存储空间。因此,Conflux 的存储成本也取决于存储空间被占用的时间长短。

存储抵押计算公式为 存储抵押 = 占用字节数 * 1CFX /1024 ;即每占用1KB空间,需要支付1CFX

使用场景

当操作智能合约且导致新增存储空间时,就需要为该新增的存储支付存储抵押

举个栗子

如下面是一个最简化的只有mint功能的ERC20合约

pragma solidity ^0.8.0;
contract MinimalERC20 {
    mapping(address => uint256) public balances;
    
    function mint(address account, uint256 amount) public {
        balances[account] += amount;
    }
}

一开始用户a的balance是0,所以balances中没有用户a的状态;当 mint(a,10)时,用户a的balance变为10。 这时变量balances会新增一对存储,key为a,value为10。 在合约中addressuint256都是占用32个字节;所以需要为该存储抵押64*1CFX/1024=0.0625CFX

而当释放该存储时该存储抵押将原路退还给存储抵押支付者。

更多详细介绍请参见存储抵押

Day2 Keystore

无论在保存或者传输私钥时都有可能被泄露的风险,所以对私钥加密后再保存或传输更为稳妥。传统文件通常采用ZIP或者RAR压缩包的方法来加密;而区块链世界更通用的方式是采用 keystore 格式加密存储,keystore格式也可以被多数钱包APP及客户端所导入、导出。

keystore生成过程,历经4个步骤:

  • 通过 KDF 的算法的变种算法 Scrypt 算法,将我们选中的密码:123456,变换为一个 AES-128-CTR 对称加密算法所能采用的加密密匙 S 。
  • 使用该密匙 S 通过 AES-128-CTR 对称加密算法加密明文的以太坊私钥。
  • 将 2 步骤生成的结果保存为密文 cyphertext 。
  • 为了防止可能的篡改或数据变更,将 cyphertext 与 S 联合起来作为输入,使用 SHA3 哈希算法对该值进行带入求值,得到一个完整性校验签名。

keystore解密的过程与生成过程相反:

  • 用户输入准确的密码 123456 后,通过 KDF 的 Scrypt 算法先计算出解密密匙 S’ 。
  • 如果密码正确,S = S’ ,否则提示用户密码输入错误。
  • 最终通过 S’,经由 AES-128-CTR 对称加密算法反向计算出私钥。

加密后的keystore 如代码清单下所示:

{
  "version": 3,
  "id": "7d5d99c8-f455-49aa-8b89-6c795a7cdd46",
  "address": "7c52e508c07558c287d5a453475954f6a547ec41",
  "crypto": {
      "kdf": "scrypt",
      "kdfparams": {
          "dklen": 32,
          "salt": "a4f9677eaf6f72394da51e16695899ad3e9b4f2228ad4eca5ef2a5c36093fe12",
          "n": 262144,
          "r": 8,
          "p": 1
      },
      "cipher": "aes-128-ctr",
      "ciphertext": "d89df5ef74f51ae485308e6dce8991dd80674e111f8073f9efa52cb2dd6eca3f",
      "cipherparams": {
          "iv": "6b064c5b09a154d9877d3a07e610a567"
      },
      "mac": "30949eb085ce342a6a488fd51fa5e3231e45f7515efa10c19ea0d46270c73f06"
  }
}

这串 JSON 格式的 keystore 代码可以被市面上大多数钱包 App 读取并合法导入。当导入时,仅需根据客户端程序提示输入 123456 将其解密即可。在网络中传输 keystore 是安全的,因为即使黑客窃取到了密文也不知道如何解密。

在 keystore 中的重要参数和对应的解释如下表。

名词 解释
id 随机生成的一个 uuid 格式的字符串
address 该 keystore 对应的公开地址
crypto 加密后的密文区域以及加密参数
kdf 全称Key Derivation Function,加密密匙生成算法, 举例中选用了Scrypt 算法
kdfparams Scrypt 算法所需要的必要参数
cypher 加密私钥选用的对称加密算法,举例中选用了AES-128-CTR 算法
cyphertext 加密后的密码文
cypherparams AES-128-CTR 算法所需要的必要输入参数
mac cyphertext与加密密匙的校验值,防止keystore被中途篡改

当前 go-conflux-sdkjs-conflux-sdkjava-conflux-sdk 都支持创建和导入导出keystore文件;其它sdk后续也会支持

参考文章:

  1. https://ethbook.abyteahead.com/ch2/keystore.html

Day3 Conflux智能合约开发工具

为了方便开发者更快速的开发Dapp,Conflux 提供了如下智能合约开发工具

详情参见 Tools

Day4 代理合约

Solidity合约部署在链上之后,代码是不可变的(immutable)。这样既有优点,也有缺点:

  • 优点:安全,用户知道会发生什么(大部分时候)。
  • 缺点:就算合约中存在bug,也不能修改或升级,只能部署新合约。但是新合约的地址与旧的不一样,且合约的数据也需要花费大量gas进行迁移。

有没有办法在合约部署后进行修改或升级呢?答案是有的,那就是代理模式。

代理模式将合约数据和逻辑分开,分别保存在不同合约中。我们拿上图中简单的代理合约为例,数据(状态变量)存储在代理合约中,而逻辑(函数)保存在另一个逻辑合约中。代理合约(Proxy)通过delegatecall,将函数调用全权委托给逻辑合约(Implementation)执行,再把最终的结果返回给调用者(Caller)。

代理模式主要有两个好处:

  • 可升级:当我们需要升级合约的逻辑时,只需要将代理合约指向新的逻辑合约。
  • 省gas:如果多个合约复用一套逻辑,我们只需部署一个逻辑合约,然后再部署多个只保存数据的代理合约,指向逻辑合约。

详情及示例请参见这里

Day5 最小化代理合约-EIP1167

EIP1167是最小化的代理合约,特点是不能修改逻辑合约的地址,同时也意味着合约不可升级,对于用户来说没有安全风险。其最大的优点是可以极大节省gas消耗。

具体实现可以参考 openzepplin 的 clone 合约

参考文章

  1. https://eips.ethereum.org/EIPS/eip-1167
  2. https://mirror.xyz/xyyme.eth/mmUAYWFLfcHGCEFg8903SweY3Sl-xIACZNDXOJ3twz8