本文首先介绍了部署交易是什么, 然后探索使用 Truffle、Remix、Hardhat,Truffle Team 进行合约主网部署的利与弊。
- 原文: https://soliditydeveloper.com/deployments
- 译文出自:登链翻译计划
- 译者:Tiny 熊
- 本文永久链接:learnblockchain.cn/article…
部署到以太坊主网你需要知道的一切
我们都喜欢以太坊,所以你已经创建了一些出色的智能合约。它们通过单元测试和测试网进行了密集的测试。现在终于到了上主网的时候了。但这是一个棘手的事情...
首先让我们从低层次快速讨论一下什么是合约部署。任何以太坊交易本身只由几个属性组成,一般有三种交易类型:
这所有三个交易的某些部分对总是相同的:from
,value
,gas
,gasPrice
和nonce
。它们之间的区别来自于 to
和 data
参数,这两个参数代表了交易被发送到哪里,以及与之一起发送的数据是什么。
发出以太币交易
to
: ETH的接收地址data
: 空(这里不涉及智能合约)部署智能合约
to
:空(我们还没有智能合约的地址,因为我们只是在刚才创建它)data
:智能合约的字节码(编译智能合约的结果)。与智能合约的交互
to
:智能合约地址data
:函数选择器及函数参数数据你肯定明白智能合约的安全是极其重要的。虽然从一开始就应该遵循最佳实践 - (中译文),但在部署到主网之前进行审计是最后也是关键的一步。你可以使用https://www.smartcontractaudits.com/,找到一个合适的审计师。
其次要考虑你的私钥的安全性。虽然对于测试网来说,在你的机器上存储一个私钥是完全可以的,但对于主网来说,这还不够好。假设你有某种访问控制,对非常关键的方面进行控制的地址应该是一个多签名合约。你可以自己设置。例如,一个7分之5的多重签名将需要7个地址中的5个地址来签署交易。你可以使用Gnosis Safe这样的应用程序来创建一个多签合约。而私钥本身最好都是来自硬件钱包,如Ledger和Trezor。
总的来说,部署一份合约需要
有一些工具可以帮助你,我可以告诉你,有些工具对主网来说比其他工具更好用。
Truffle仍然是一个非常广泛使用的工具,特别是用于部署。它可以做很多事情,从智能合约的编译到自动测试。但这里我们只对它的迁移功能感兴趣,它是用于部署的。
在下边你看到一个非常典型的truffle 配置。在这里你可以看到我们是如何解决部署合约的很多要求的。
require("dotenv").config();
const HDWalletProvider = require("@truffle/hdwallet-provider");
const { MNEMONIC, INFURA_API_KEY } = process.env;
const kovanUrl = `https://kovan.infura.io/v3/${INFURA_API_KEY}`;
const mainnetUrl = `https://mainnet.infura.io/v3/${INFURA_API_KEY}`;
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*",
},
mainnet: {
provider: () => new HDWalletProvider(MNEMONIC, mainnetUrl),
network_id: 1,
},
kovan: {
provider: () => new HDWalletProvider(MNEMONIC, kovanUrl),
network_id: 42,
},
},
compilers: {
solc: {
version: "0.8.4",
optimizer: { enabled: true, runs: 200 }
},
},
};
compilers
部分定义我们的solc版本,Truffle将在部署前自动编译我们的合约。迁移是为你定义如何部署智能合约的特殊脚本。如果你有多个合约需要部署,而这些合约又相互依赖,或者你需要在部署后调用任何合约上的功能,这就特别有用。
请查看迁移链接这里,了解如何使用它们的完整文档。
var MyContract = artifacts.require("MyContract");
module.exports = deployer => {
deployer.then(async () => {
await deployer.deploy(MyContract, param1, param2);
const myContract = await MyContract.deployed();
await myContract.changeOwnership(multiSigAddress);
});
};
这里你可以看到一个典型的迁移脚本,它利用了async/await语法。在部署之后,我们将所有权转移到一个已经部署好的multisig合约上。
值得一提的是,由于几个原因,Truffle本身远不是部署到主网的最佳选择。
在主网上,Truffle中的长时间迁移是非常非常痛苦的。
至少,Truffle现在在实际部署前会进行运行模拟部署。你可以用--skip-dry-run
跳过测试网的模拟,但不要在主网上这样做。这将确保你至少不会在中间环节出现错误,而不得不从头开始重新启动。
总而言之,如果你有钱支付使用Truffle所增加的费用,就去使用它吧。否则,请继续阅读替代方案。
Remix是我最喜欢的快速部署主网的工具。你可以完全控制正在发生的事情,因为你将使用MetaMask手动完成每个步骤。
一旦你有了编译好的合约,部署就像输入参数和点击部署一样简单。你可以使用truffle-flattener从Truffle获得Remix的可部署合约,或者使用Hardhat内置扁平化命令获得可部署合约。由于你使用的是MetaMask,你会:
然而使用Remix,你必须手动完成每一个步骤,手动输入每个参数,手动部署每一个合约,手动调用每个函数。你可以看到这对很长的部署程序来说是多么的痛苦。
Hardhat中没有对部署的直接支持。然而,你可以写一个脚本,通过ethers.js部署一个合约,并从hardhat命令中调用它。在solidity-template中可以看到一个关于如何做到这一点的例子。
下面是一个部署脚本的例子:
import { Contract, ContractFactory } from "ethers";
import { ethers } from "hardhat";
async function main(): Promise<void> {
const Greeter: ContractFactory
= await ethers.getContractFactory("Greeter");
const greeter: Contract
= await Greeter.deploy("Hello, Buidler!");
await greeter.deployed();
console.log("Greeter deployed to: ", greeter.address);
}
main()
.then(() => process.exit(0))
.catch((error: Error) => {
console.error(error);
process.exit(1);
});
该脚本可以用以下方式调用。
$ npx hardhat run scripts/deploy.ts
另外,你可以使用hardhat-deploy插件,它增加了完成部署后保存在文件的能力。
当然,你总是可以直接使用Web3(或ethers.js)构建你的自定义部署逻辑。当你频繁地部署合约并需要自定义逻辑来存储部署信息时,这非常有用。Web3直接支持使用myContract.deploy()进行部署。
const myContract = new web3.eth.Contract(jsonABI)
myContract.deploy({
data: '0x12345...', // bytecode
arguments: [123, 'My String'] // constructor arguments
}).send({
from: '0x1234567890123456789012345678901234567891',
gas: 1500000,
gasPrice: '30000000000000'
}
还记得上面提到的用Truffle部署到主网的问题吗?那么有一个解决方案,叫做Truffle Teams。它对开源项目是免费的,否则每个月会花费几美元。但是,通过Truffle Team你就可以得到一个项目仪表板。这是与Github的直接连接,并作为持续集成运行你的测试。任何成功的构建都可以从仪表板上部署。
这允许你为部署连接MetaMask,意味着完全控制交易成本并加速。
Truffle Teams部署的完整文档,请参阅这里。
在部署到主网之后,你应该在Etherscan和Sourcify上验证合约的源代码。这涉及到将Solidity代码提交给这些服务,这些服务将对其进行编译,并验证它是否与部署的字节码相匹配。验证成功后,用户可以在Etherscan上获得更多的信息,可以直接在Etherscan上与之交互,或者在Remix等支持工具从Sourcify上获取代码。
你可以在Etherscan网站上手动验证你的合约。另外,也推荐使用Truffle、Hardhat插件和直接使用Etherscan API自动验证的插件。
关于如何使用Sourcify,请查看这篇博文。
本翻译由 Cell Network 赞助支持。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!