ethereum: Add contract verification instructions (#792)
This commit is contained in:
parent
0044bb5e44
commit
60d313b23c
|
@ -330,6 +330,7 @@ yargs(hideBin(process.argv))
|
||||||
case 2:
|
case 2:
|
||||||
console.log("Upgrading contract")
|
console.log("Upgrading contract")
|
||||||
console.log("Hash: " + (await tb.upgrade(vaa)).hash)
|
console.log("Hash: " + (await tb.upgrade(vaa)).hash)
|
||||||
|
console.log("Don't forget to verify the new implementation! See ethereum/VERIFY.md for instructions")
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
throw new Error("unknown governance action")
|
throw new Error("unknown governance action")
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Contract verification
|
||||||
|
|
||||||
|
The various EVM explorer sites (etherscan, bscscan, etc.) support contract
|
||||||
|
verification. This essentially entails uploading the source code to the site,
|
||||||
|
and they verify that the uploaded source code compiles to the same bytecode
|
||||||
|
that's actually deployed. This enables the explorer to properly parse the
|
||||||
|
transaction payloads according to the contract ABI.
|
||||||
|
|
||||||
|
This document outlines the process of verification. In general, you will need an
|
||||||
|
API key for the relevant explorer (this can be obtained by creating an account),
|
||||||
|
and also know which address the contract code lives. The API key is expected to
|
||||||
|
be set in the `ETHERSCAN_KEY` environment variable for all APIs (not just
|
||||||
|
etherscan, bit of a misnomer).
|
||||||
|
|
||||||
|
Our contracts are structured as a separate proxy and an implementation. Both of
|
||||||
|
these components need to be verified, but the proxy contract only needs this
|
||||||
|
once, since it's not going to change. The implementation contract needs to be
|
||||||
|
verified each time it's upgraded.
|
||||||
|
|
||||||
|
## Verifying the proxy contract (first time)
|
||||||
|
|
||||||
|
The proxy contract is called `TokenBridge`. To verify it on e.g. avalanche, at contract address `0x0e082F06FF657D94310cB8cE8B0D9a04541d8052`, run
|
||||||
|
|
||||||
|
```
|
||||||
|
ETHERSCAN_KEY=... npm run verify --module=TokenBridge --contract_address=0x0e082F06FF657D94310cB8cE8B0D9a04541d8052 --network=avalanche
|
||||||
|
```
|
||||||
|
|
||||||
|
(Note: the network name comes from the `truffle-config.json`).
|
||||||
|
(Note: In this case, the `ETHERSCAN_KEY` is your snowtrace API key).
|
||||||
|
|
||||||
|
|
||||||
|
## Verifying the implementation contract (on each upgrade)
|
||||||
|
|
||||||
|
To verify the actual implementation, at address `0xa321448d90d4e5b0a732867c18ea198e75cac48e`, run
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ETHERSCAN_KEY=... npm run verify --module=BridgeImplementation --contract_address=0xa321448d90d4e5b0a732867c18ea198e75cac48e --network=avalanche
|
||||||
|
```
|
||||||
|
|
||||||
|
As a final step, when first registering the proxy contract, we need to verify
|
||||||
|
that it's a proxy that points to the implementation we just verified. This can
|
||||||
|
be done on avalanche at
|
||||||
|
https://snowtrace.io/proxyContractChecker?a=0x0e082F06FF657D94310cB8cE8B0D9a04541d8052
|
||||||
|
|
||||||
|
(other evm scanner sites have an identical page).
|
||||||
|
|
||||||
|
|
||||||
|
# Note
|
||||||
|
The `npm run verify` script uses the `truffle-plugin-verify` plugin under the
|
||||||
|
hood. The version of `truffle-plugin-verify` pinned in the repo (`^0.5.11` at
|
||||||
|
the time of writing) doesn't support the avalanche RPC. In later versions of the
|
||||||
|
plugin, support was added, but other stuff has changed as well in the transitive
|
||||||
|
dependencies, so it fails to parse the `HDWallet` arguments in our
|
||||||
|
`truffle-config.json`. As a quick workaround, we backport the patch to `0.5.11`
|
||||||
|
by applying the `truffle-verify-constants.patch` file, which the `npm run
|
||||||
|
verify` script does transparently. Once the toolchain has been upgraded and the
|
||||||
|
errors fixed, this patch can be removed.
|
|
@ -21,7 +21,8 @@
|
||||||
"build": "truffle compile",
|
"build": "truffle compile",
|
||||||
"test": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle test",
|
"test": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle test",
|
||||||
"migrate": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate",
|
"migrate": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate",
|
||||||
"flatten": "mkdir -p node_modules/@poanet/solidity-flattener/contracts && cp -r contracts/* node_modules/@poanet/solidity-flattener/contracts/ && poa-solidity-flattener"
|
"flatten": "mkdir -p node_modules/@poanet/solidity-flattener/contracts && cp -r contracts/* node_modules/@poanet/solidity-flattener/contracts/ && poa-solidity-flattener",
|
||||||
|
"verify": "patch -u -f node_modules/truffle-plugin-verify/constants.js -i truffle-verify-constants.patch; truffle run verify $npm_config_module@$npm_config_contract_address --network $npm_config_network"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
--- node_modules/truffle-plugin-verify/contants-old.js 2022-01-28 12:44:53.140709519 +0000
|
||||||
|
+++ node_modules/truffle-plugin-verify/constants.js 2022-01-28 12:45:16.800710171 +0000
|
||||||
|
@@ -3,13 +3,23 @@
|
||||||
|
3: 'https://api-ropsten.etherscan.io/api',
|
||||||
|
4: 'https://api-rinkeby.etherscan.io/api',
|
||||||
|
5: 'https://api-goerli.etherscan.io/api',
|
||||||
|
+ 10: 'https://api-optimistic.etherscan.io/api',
|
||||||
|
42: 'https://api-kovan.etherscan.io/api',
|
||||||
|
56: 'https://api.bscscan.com/api',
|
||||||
|
+ 69: 'https://api-kovan-optimistic.etherscan.io/api',
|
||||||
|
97: 'https://api-testnet.bscscan.com/api',
|
||||||
|
128: 'https://api.hecoinfo.com/api',
|
||||||
|
137: 'https://api.polygonscan.com/api',
|
||||||
|
250: 'https://api.ftmscan.com/api',
|
||||||
|
256: 'https://api-testnet.hecoinfo.com/api',
|
||||||
|
+ 1284: 'https://api-moonbeam.moonscan.io/api',
|
||||||
|
+ 1285: 'https://api-moonriver.moonscan.io/api',
|
||||||
|
+ 1287: 'https://api-moonbase.moonscan.io/api',
|
||||||
|
+ 4002: 'https://api-testnet.ftmscan.com/api',
|
||||||
|
+ 42161: 'https://api.arbiscan.io/api',
|
||||||
|
+ 43113: 'https://api-testnet.snowtrace.io/api',
|
||||||
|
+ 43114: 'https://api.snowtrace.io/api',
|
||||||
|
+ 421611: 'https://api-testnet.arbiscan.io/api',
|
||||||
|
80001: 'https://api-testnet.polygonscan.com/api'
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -18,16 +28,25 @@
|
||||||
|
3: 'https://ropsten.etherscan.io/address',
|
||||||
|
4: 'https://rinkeby.etherscan.io/address',
|
||||||
|
5: 'https://goerli.etherscan.io/address',
|
||||||
|
+ 10: 'https://optimistic.etherscan.io/address',
|
||||||
|
42: 'https://kovan.etherscan.io/address',
|
||||||
|
56: 'https://bscscan.com/address',
|
||||||
|
+ 69: 'https://kovan-optimistic.etherscan.io/address',
|
||||||
|
97: 'https://testnet.bscscan.com/address',
|
||||||
|
128: 'https://hecoinfo.com/address',
|
||||||
|
137: 'https://polygonscan.com/address',
|
||||||
|
250: 'https://ftmscan.com/address',
|
||||||
|
256: 'https://testnet.hecoinfo.com/address',
|
||||||
|
+ 1284: 'https://moonbeam.moonscan.io/address',
|
||||||
|
+ 1285: 'https://moonriver.moonscan.io/address',
|
||||||
|
+ 1287: 'https://moonbase.moonscan.io/address',
|
||||||
|
+ 4002: 'https://testnet.ftmscan.com/address',
|
||||||
|
+ 42161: 'https://arbiscan.io/address',
|
||||||
|
+ 43113: 'https://testnet.snowtrace.io/address',
|
||||||
|
+ 43114: 'https://snowtrace.io/address',
|
||||||
|
+ 421611: 'https://testnet.arbiscan.io/address',
|
||||||
|
80001: 'https://mumbai.polygonscan.com/address'
|
||||||
|
}
|
||||||
|
-
|
||||||
|
const RequestStatus = {
|
||||||
|
OK: '1',
|
||||||
|
NOTOK: '0'
|
Loading…
Reference in New Issue