await this.boxV2.increment();
contract(‘BoxV2 (proxy)’, function () {
我们可以在 Rinkeby 网络上运行迁移。
我们可以在 Rinkeby 网络上运行迁移,以陈设新的合约实现。留意:运行此迁移时,我们需要跳过之前运行过的迁移。
在本文中,我们还没有initialize函数,因此我们将利用store 函数来初始化状态。
// Test case
> Blocks: 0 Seconds: 5
Box.proxy.test.js
[2]Tiny 熊: https://learnblockchain.cn/people/15
利用以下 JavaScript 在migrations目次中建设4_prepare_upgrade_boxv2.js。
> Saving migration to chain.
value = newValue;
一段时间后,我们抉择要向合约添加成果。在本文中,我们将添加一个increment函数。
在 migrations 目次中建设以下2_deploy_box.js剧本。
…
const { deployProxy } = require(‘@openzeppelin/truffle-upgrades’);
// Increments the stored value by 1
truffle(rinkeby)> box = await Box.deployed()
// Load dependencies
const { admin } = require(‘@openzeppelin/truffle-upgrades’);
this.boxV2 = await upgradeProxy(this.box.address, BoxV2);
truffle(rinkeby)> box.address
// 留意需要利用字符串去比拟256位的整数
});
4_prepare_upgrade_boxv2.js
}
我们将从建设一个新的 npm 项目开始:
利用 OpenZeppelin 进级插件陈设的合约具备可进级的特性:可以进级以修改其代码,同时保存其地点,状态和余额。这使你可以迭代地向项目中添加新成果,或修复在线上版本中大概发明的任何错误。
进级合约
const gnosisSafe = ‘0x1c14600daeca8852BA559CC8EdB1C383B8825906’;
module.exports = async function (deployer, network) {
// Start test block
// SPDX-License-Identifier: MIT
Deploying ‘ProxyAdmin’
// 测试是否返回了同一个配置的值
// Stores a new value in the contract
…
});
一旦测试了新的实现,就可以筹备进级。这将验证并陈设新合约。留意:我们仅是筹备进级。我们将利用 Gnosis Safe 执行实际进级。
4_prepare_upgrade_boxv2.js
expect((await this.boxV2.retrieve()).toString()).to.equal(‘1’);
truffle(rinkeby)> boxV2 = await BoxV2.at(box.address)
· 转移进级权限到 Gnosis Safe 多签
为了测试我们的进级版本,我们应该为新的合约建设单位测试,并为通过署理测试交互,并查抄进级之间是否保持状态。
=======================
> contract address: 0x2A210B6d5EffC0A3BB47dD3791a4C26B8E31f161
it(‘retrieve returns a value previously stored’, async function () {
$ npx truffle console –network rinkeby
await deployProxy(Box, [42], { deployer, initializer: ‘store’ });
// Note that we need to use strings to compare the 256 bit integers
// Deploy a new Box contract for each test
’43’
value = value + 1;
Deploying ‘AdminUpgradeabilityProxy’
// 测试是否返回了同一个配置的值
// Load dependencies
// 为每个测试陈设一个新的Box合约
uint256 private value;
实现一个新的进级版本
我们将在测试中利用 chai(一个 Js 测试框架),因此首先需要安装它。
const { prepareUpgrade } = require(‘@openzeppelin/truffle-upgrades’);
[4]Solidity: https://learnblockchain.cn/docs/solidity/
’42’
});
const box = await Box.deployed();
将合约陈设到民众网络
// Start test block
expect((await this.boxV2.retrieve()).toString()).to.equal(’42’);
2_deploy_box.js
beforeEach(async function () {
首先,我们需要署理的地点(box.address)和新实现的地点(boxV2.address)。我们可以从 truffle 迁移的输出或 truffle console 中得到。
truffle(rinkeby)> await boxV2.increment()
Box.test.js
truffle(rinkeby)> (await boxV2.retrieve()).toString()
const BoxV2 = artifacts.require(‘BoxV2’);
// 加载依赖
// Test case
‘0xEc784bE1CC7F5deA6976f61f578b328E856FB72c’
emit ValueChanged(newValue);
const Box = artifacts.require(‘Box’);
可以在主网上执行沟通的进程。留意:我们应该始终首先在民众测试网上测试进级。
在本文中,我们将陈设到 Rinkeby。假如需要设置方面的辅佐,请参阅利用 Truffle 毗连到民众测试网络[7]。留意:助记符或 Infura 项目 ID 之类的机要内容都不该提交给版本节制。
// test/Box.proxy.test.js
…
it(‘retrieve returns a value previously incremented’, async function () {
[7]利用 Truffle 毗连到民众测试网络: https://forum.openzeppelin.com/t/connecting-to-public-test-networks-with-truffle/2960
};
}
留意:我们不需要在此处反复单位测试,这是为了测试署理交互和测试进级。
陈设新的进级版本
// Load compiled artifacts
===============
我们还可以通过(进级)署理建设测试举办交互。
await this.boxV2.increment();
…
[10]EIP1967: https://learnblockchain.cn/docs/eips/eip-1967.html
// Load compiled artifacts
BoxV2.test.js
✓ retrieve returns a value previously stored (100ms)
// 测试是否返回了同一个配置的值
pragma solidity ^0.7.0;
假如你对本文有任何疑问或发起的改造,请宣布在openzeppelin 社区论坛[11]中。
return value;
// Don’t change ProxyAdmin ownership for our test network
Using network ‘test’.
安装 Truffle 进级插件。
$ npx truffle test
我们的合约应该始终有相应的测试。要测试合约,我们应该为合约实现建设单位测试。
[11]openzeppelin 社区论坛: https://forum.openzeppelin.com/
✓ retrieve returns a value previously incremented (90ms)
进级后,我们还可以通过署理举办交互来建设测试。留意:我们不需要在此处反复单位测试,这是为了测试署理交互和测试进级后的状态。
✓ retrieve returns a value previously incremented (86ms)
$ npx truffle console –network rinkeby
await prepareUpgrade(box.address, BoxV2, { deployer });
const Box = artifacts.require(‘Box’);
利用以下 JavaScript 在你的test目次中建设Box.proxy.test.js。
> transaction hash: 0xf39e8cb97c332b8bbdf0c66b13f26a9a3dc97b207d2caec73ba6df8d5bb6b211
// 留意需要利用字符串去比拟256位的整数
我们已经建设了一个可进级的合约,将进级的节制权转移到了 Gnosis Safe,并进级了我们的合约。
this.box = await deployProxy(Box, [42], {initializer: ‘store’});
// Store a value
Contract: Box (proxy)
});
function retrieve() public view returns (uint256) {
it(‘retrieve returns a value previously initialized’, async function () {
const { expect } = require(‘chai’);
const Box = artifacts.require(‘Box’);
function store(uint256 newValue) public {
// Test if the returned value is the same one
在“应用措施(APPS)”选项卡中,选择“ OpenZeppelin”应用措施,然后将署理地点粘贴到“合约地点(Contract address)”字段中,然后将新实现的地点粘贴到“新实现的地点( New implementation address)”字段中。
truffle(rinkeby)> boxV2.address
});
// Increment
$ npx truffle migrate –network rinkeby
然后,我们可以运行测试。
我们将为新的合约实现建设单位测试。我们可以在已经建设的单位测试中添加新测试,以确保高包围率。利用以下 JavaScript 在你的test目次中建设BoxV2.test.js。
// The owner of the ProxyAdmin can upgrade our contracts
建设可进级合约
· 当地测试合约
设置开拓情况
contract(‘BoxV2’, function () {
‘0xF325bB49f91445F97241Ec5C286f90215a7E3BC6’
emit ValueChanged(newValue);
truffle(rinkeby)> box = await Box.deployed()
[1]登链翻译打算: https://github.com/lbc-team/Pioneer
// Deploy a new BoxV2 contract for each test
const Box = artifacts.require(‘Box’);
truffle(rinkeby)> box.address
}
this.boxV2 = await BoxV2.new();
…
emit ValueChanged(value);
利用以下 Solidity 代码在你的contracts目次中建设新的实现BoxV2.sol 。
Contract: Box
});
});
我们可以利用 Truffle 节制台(truffle console)与我们的合约举办交互。
});
// 留意需要利用字符串去比拟256位的整数
// Note that we need to use strings to compare the 256 bit integers
· 建设可进级合约
// test/Box.proxy.test.js
[9]进级: https://docs.openzeppelin.com/learn/upgrading-smart-contracts#upgrading
uint256 private value;
转移进级权限到 Gnosis Safe 多签
// Load dependencies
// migrations/3_transfer_ownership.js
event ValueChanged(uint256 newValue);
· 进级合约
在 Rinkeby 上建设 Gnosis Safe 之后,请复制地点,以便我们转移所有权。
接下来});
Contract: Box (proxy)
———————-
[6]Truffle 迁移: https://learnblockchain.cn/docs/truffle/getting-started/running-migrations.html
…
5 passing (1s)
const BoxV2 = artifacts.require(‘BoxV2’);
· 实现一个新的进级版本
’42’
—————–
Deploying ‘Box’
> Blocks: 1 Seconds: 17
该应用措施应显示该合约是EIP1967[10]兼容的。在本文中,我们将展示利用 OpenZeppelin Truffle 进级插件和 Gnosis Safe 的生命周期,包括从建设合约,测试合约、陈设合约一直到利用 Gnosis Safe 举办进级整个进程:
[8]建设 Safe Multisig: https://help.gnosis-safe.io/en/articles/3876461-create-a-safe-multisig
expect((await this.boxV2.retrieve()).toString()).to.equal(’43’);
✓ retrieve returns a value previously initialized (38ms)
[5]initialize函数而不是结构函数: https://docs.openzeppelin.com/learn/upgrading-smart-contracts#initialization
{ tx:
module.exports = async function (deployer) {
…
pragma solidity ^0.7.0;
// test/BoxV2.test.js
};
// Reads the last stored value
· 当地测试进级版本
function increment() public {
[12]Cell Network: https://www.cellnetwork.io/?utm_souce=learnblockchain
const { expect } = require(‘chai’);
参考资料
// contracts/Box.sol
…
// Reads the last stored value
truffle(rinkeby)> (await boxV2.retrieve()).toString()
Contract: Box
beforeEach(async function () {
return value;
expect((await this.box.retrieve()).toString()).to.equal(’42’);
}
Contract: BoxV2 (proxy)
BoxV2.sol
译者注:Gnosis Safe 是一款多签名钱包,可配置满意 n/m (譬喻:2/3)的签名才可以举办生意业务。
const { expect } = require(‘chai’);
beforeEach(async function () {
// Increment
利用以下 JavaScript 在migrations目次中建设3_transfer_ownership.js。将 gnosisSafe 的值变动为你的 Gnosis Safe 地点。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。