如何从 Hardhat 上的助记词生成匹配的 RSK 帐户?

Jua*_*ola 5 rsk hardhat

我已经遵循了这个Hardhat 教程。但我正在修改配置文件以使其在RSK上运行上工作,\n并且遇到了一些意外的地址行为。\n\xe2\x80\x8b

\n
const { expect } = require(\'chai\');\n\xe2\x80\x8b\ndescribe(\'Token contract\', () => {\n  it(\'Deployment should assign the total supply of tokens to the owner\', async () => {\n    const [owner] = await ethers.getSigners();\n    console.log(\'Smart contract owner: \', owner.address);\n      \n    const Token = await ethers.getContractFactory(\'Token\');\n\xe2\x80\x8b\n    const hardhatToken = await Token.deploy();\n    \n    const ownerBalance = await hardhatToken.balanceOf(owner.address);\n    expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\x8b\n这里是hardhat.config.js我正在使用的设置:\n\xe2\x80\x8b

\n
require(\'@nomiclabs/hardhat-waffle\');\nconst fs = require(\'fs\');\n\xe2\x80\x8b\nconst minimumGasPriceTestnet = 65164000;\nconst TESTNET_GAS_MULT = 1;\nconst mnemonic = fs.readFileSync(\'.secret\', \'utf8\').toString().trim();\nif (!mnemonic || mnemonic.split(\' \').length !== 12) {\n  throw new Error(\'unable to retrieve mnemonic from .secret\');\n}\n\xe2\x80\x8b\nmodule.exports = {\n  solidity: \'0.7.3\',\n  defaultNetwork: \'rsktestnet\',\n  networks: {\n    hardhat: {},\n    rsktestnet: {\n      chainId: 31,\n      url: \'https://public-node.testnet.rsk.co/\',\n      gasPrice: Math.floor(minimumGasPriceTestnet * TESTNET_GAS_MULT),\n      gasMultiplier: TESTNET_GAS_MULT,\n      accounts: {\n        mnemonic,\n        initialIndex: 0,\n        // Ref: https://developers.rsk.co/rsk/architecture/account-based/#derivation-path-info\n        path: "m/44\'/37310\'/0\'/0",\n        count: 10,\n      },\n    },\n  },\n};\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\x8b\n在文件中.secret我存储了一个助记词短语,我也在网络浏览器钱包(Metamask)中使用。

\n

我运行测试,但失败并出现以下错误:\n\xe2\x80\x8b

\n
Token contract\nSmart contract owner:  0x266f1533e637F88C8022251d5Ec9221E9.......\n    1) Deployment should assign the total supply of tokens to the owner\n\xe2\x80\x8b\n\xe2\x80\x8b\n  0 passing (5s)\n  1 failing\n\xe2\x80\x8b\n  1) Token contract\n       Deployment should assign the total supply of tokens to the owner:\n     ProviderError: the sender account doesn\'t exist\n      at HttpProvider.request (node_modules/hardhat/src/internal/core/providers/http.ts:49:19)\n      at HDWalletProvider.request (node_modules/hardhat/src/internal/core/providers/accounts.ts:181:36)\n      at processTicksAndRejections (internal/process/task_queues.js:97:5)\n      at EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\x8b我注意到合约所有者地址与生成的 Metamask 不同。为什么 Hardhat 和 Metamask 会产生不同的帐户地址。由于我使用相同的种子短语,因此两者不应该具有相同的地址吗?

\n

bgu*_*uiz 4

MetaMask 使用派生路径值m/44'/60'/0'/0,从技术上讲,该值仅适用于以太坊,而适用于 RSK 则不正确。

这里技术上正确的解决方案是将 MetaMask 配置为也使用 RSK 派生路径。不幸的是,MetaMask 目前(2022 年 3 月)不支持网络配置中的自定义派生路径。

您可以使用一种解决方法来代替“正确”的解决方案:在安全帽配置中使用以太坊派生路径。

为此,请在 中hardhat.config.js替换:

path: "m/44'/37310'/0'/0",
Run Code Online (Sandbox Code Playgroud)

path: "m/44'/60'/0'/0",
Run Code Online (Sandbox Code Playgroud)

为什么这有效?

要真正了解上述情况及其工作原理,需要了解确定性钱包的多账户层次结构的 BIP-44 技术规范。上面hardhat配置文件中的属性path指的是BIP-44中描述的层次派生路径。

然而,它的完整内部工作原理是不必要的,只需将其视为一个黑匣子,只需将其视为具有输入和输出的函数即可。

将 BIP-44 中描述的完整过程视为一个黑匣子,位于名为 的函数中hdPath。该函数接受两个输入:种子短语和派生路径。该函数产生一个输出,即一组帐户。

hdPath(seedPhrase, derivationPath) -> set of accounts
Run Code Online (Sandbox Code Playgroud)

帐户由私钥组成,然后使用私钥生成公钥,然后使用公钥生成地址:

account : privateKey -> publicKey -> address
Run Code Online (Sandbox Code Playgroud)

因此,如果您使用相同的种子短语 (在安全帽和元掩码中),但使用不同的派生路径m/44'/37310'/0'/0在安全帽中,但m/44'/60'/0'/0在元掩码中);总的来说,该hdPath函数仍然有不同的输入,因此它将生成一组不同的私钥,这又意味着一组不同的公钥,这又意味着一组不同的地址;这就是你所观察到的。