Skip to content

Commit 9d503ff

Browse files
llwslcericglau
andauthoredMar 3, 2023
Use proxy transactionHash for implementation contract abstraction in Truffle (#737)
Co-authored-by: Eric Lau <ericglau@outlook.com>

8 files changed

+46
-9
lines changed
 

‎packages/plugin-truffle/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- Use proxy transaction hash for implementation contract abstraction. ([#737](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/737))
6+
37
## 1.17.0 (2022-09-27)
48

59
- Include solc version in storage layouts in manifest files. ([#662](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/662))

‎packages/plugin-truffle/src/deploy-beacon-proxy.ts

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export async function deployBeaconProxy(
8282
await manifest.addProxy(proxyDeployment);
8383

8484
attachTo.address = proxyDeployment.address;
85+
attachTo.transactionHash = proxyDeployment.txHash;
8586
const contract = new attachTo(proxyDeployment.address);
8687
contract.transactionHash = proxyDeployment.txHash;
8788
return contract;

‎packages/plugin-truffle/src/deploy-proxy.ts

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export async function deployProxy(
7171
await manifest.addProxy(proxyDeployment);
7272

7373
Contract.address = proxyDeployment.address;
74+
Contract.transactionHash = proxyDeployment.txHash;
7475
const contract = new Contract(proxyDeployment.address);
7576
contract.transactionHash = proxyDeployment.txHash;
7677
return contract;

‎packages/plugin-truffle/src/upgrade-proxy.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ export async function upgradeProxy(
2626
const upgradeTo = await getUpgrader(provider, Contract, proxyAddress);
2727
const { impl: nextImpl } = await deployProxyImpl(Contract, opts, proxyAddress);
2828
const call = encodeCall(Contract, opts.call);
29-
await upgradeTo(nextImpl, call);
29+
const { tx: txHash } = await upgradeTo(nextImpl, call);
3030

3131
Contract.address = proxyAddress;
32-
return new Contract(proxyAddress);
32+
Contract.transactionHash = txHash;
33+
const contract = new Contract(proxyAddress);
34+
contract.transactionHash = txHash;
35+
return contract;
3336
}
3437

35-
type Upgrader = (nextImpl: string, call?: string) => Promise<void>;
38+
type Upgrader = (nextImpl: string, call?: string) => Promise<{ tx: string }>;
3639

3740
async function getUpgrader(
3841
provider: EthereumProvider,
@@ -47,7 +50,9 @@ async function getUpgrader(
4750
const TransparentUpgradeableProxyFactory = getTransparentUpgradeableProxyFactory(contractTemplate);
4851
const proxy = new TransparentUpgradeableProxyFactory(proxyAddress);
4952

50-
return (nextImpl, call) => (call ? proxy.upgradeToAndCall(nextImpl, call) : proxy.upgradeTo(nextImpl));
53+
return (nextImpl, call) => {
54+
return call ? proxy.upgradeToAndCall(nextImpl, call) : proxy.upgradeTo(nextImpl);
55+
};
5156
} else {
5257
// Admin contract: redirect upgrade call through it
5358
const manifest = await Manifest.forNetwork(provider);
@@ -59,8 +64,9 @@ async function getUpgrader(
5964
throw new Error('Proxy admin is not the one registered in the network manifest');
6065
}
6166

62-
return (nextImpl, call) =>
63-
call ? admin.upgradeAndCall(proxyAddress, nextImpl, call) : admin.upgrade(proxyAddress, nextImpl);
67+
return (nextImpl, call) => {
68+
return call ? admin.upgradeAndCall(proxyAddress, nextImpl, call) : admin.upgrade(proxyAddress, nextImpl);
69+
};
6470
}
6571
}
6672

‎packages/plugin-truffle/src/utils/truffle.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface ContractClass {
1818
class_defaults: ContractClassDefaults;
1919
contractName: string;
2020
address?: string;
21+
transactionHash?: string;
2122
networks?: {
2223
[id: string]: NetworkObject;
2324
};

‎packages/plugin-truffle/test/migrations/2_1_deploy_greeter_transparent.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@ const Greeter = artifacts.require('Greeter');
22
const GreeterV2 = artifacts.require('GreeterV2');
33

44
const { deployProxy, upgradeProxy } = require('@openzeppelin/truffle-upgrades');
5+
const assert = require('assert');
56

67
module.exports = async function (deployer) {
78
const g = await deployProxy(Greeter, ['Hello Truffle'], { deployer, kind: 'transparent' });
8-
await upgradeProxy(g, GreeterV2, { deployer });
9+
10+
assert.equal(Greeter.address, g.address);
11+
assert.equal(Greeter.transactionHash, g.transactionHash);
12+
13+
const upgraded = await upgradeProxy(g, GreeterV2, { deployer });
14+
15+
assert.equal(GreeterV2.address, upgraded.address);
16+
assert.equal(GreeterV2.transactionHash, upgraded.transactionHash);
17+
assert.notEqual(GreeterV2.transactionHash, Greeter.transactionHash);
918
};

‎packages/plugin-truffle/test/migrations/2_2_deploy_greeter_uups.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@ const Greeter = artifacts.require('GreeterProxiable');
22
const GreeterV2 = artifacts.require('GreeterV2Proxiable');
33

44
const { deployProxy, upgradeProxy } = require('@openzeppelin/truffle-upgrades');
5+
const assert = require('assert');
56

67
module.exports = async function (deployer) {
78
const g = await deployProxy(Greeter, ['Hello Truffle'], { deployer, kind: 'uups' });
8-
await upgradeProxy(g, GreeterV2, { deployer });
9+
10+
assert.equal(Greeter.address, g.address);
11+
assert.equal(Greeter.transactionHash, g.transactionHash);
12+
13+
const upgraded = await upgradeProxy(g, GreeterV2, { deployer });
14+
15+
assert.equal(GreeterV2.address, upgraded.address);
16+
assert.equal(GreeterV2.transactionHash, upgraded.transactionHash);
17+
assert.notEqual(GreeterV2.transactionHash, Greeter.transactionHash);
918
};

‎packages/plugin-truffle/test/migrations/2_3_deploy_greeter_beacon.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ const GreeterBeaconImpl = artifacts.require('GreeterBeaconImpl');
22
const GreeterV2 = artifacts.require('GreeterV2');
33

44
const { deployBeacon, deployBeaconProxy, upgradeBeacon } = require('@openzeppelin/truffle-upgrades');
5+
const assert = require('assert');
56

67
module.exports = async function (deployer) {
78
const beacon = await deployBeacon(GreeterBeaconImpl, { deployer });
8-
await deployBeaconProxy(beacon, GreeterBeaconImpl, ['Hello Truffle'], { deployer });
9+
10+
const proxy = await deployBeaconProxy(beacon, GreeterBeaconImpl, ['Hello Truffle'], { deployer });
11+
12+
assert.equal(GreeterBeaconImpl.address, proxy.address);
13+
assert.equal(GreeterBeaconImpl.transactionHash, proxy.transactionHash);
14+
915
await upgradeBeacon(beacon, GreeterV2, { deployer });
1016
};

0 commit comments

Comments
 (0)
Please sign in to comment.