Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script for verifying contracts with etherscan #345

Merged

Conversation

loredanacirstea
Copy link
Contributor

@loredanacirstea loredanacirstea commented Oct 19, 2018

fixes #319

Rough script to verify contracts. To be used like:

python -m raiden_contracts.deploy.etherscan_verify --apikey ETHERSCAN_APIKEY --contract-name EndpointRegistry --chain-id 3

python -m raiden_contracts.deploy.etherscan_verify --apikey ETHERSCAN_APIKEY --contract-name SecretRegistry --chain-id 3

python -m raiden_contracts.deploy.etherscan_verify --apikey ETHERSCAN_APIKEY --contract-name TokenNetworkRegistry --chain-id 3
  • Etherscan verification works for EndpointRegistry and SecretRegistry.

  • For some reason, the verification fails for TokenNetworkRegistry. However, if you manually verify on Etherscan using the flatten.sol source created by the script in raiden_contracts/deploy/ and the data printed by the script (solc version, ABI encoded constructor arguments etc.), then it works!

  • Could be improved, but I would merge it as it is now and improve it in another PR

Rough script to verify contracts. To be used like:
```
python -m raiden_contracts.deploy.etherscan_verify --apikey ETHERSCAN_APIKEY --contract-name EndpointRegistry --chain-id 3

python -m raiden_contracts.deploy.etherscan_verify --apikey ETHERSCAN_APIKEY --contract-name SecretRegistry --chain-id 3

python -m raiden_contracts.deploy.etherscan_verify --apikey ETHERSCAN_APIKEY --contract-name TokenNetworkRegistry --chain-id 3
```
source_path['raiden'].joinpath('SecretRegistry.sol').read_text() +
source_path['raiden'].joinpath('TokenNetwork.sol').read_text() +
source_path['raiden'].joinpath('TokenNetworkRegistry.sol').read_text()
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, the flattening should not be done like this, but following the compiled AST imports order or using a dedicated flattening package (I have not found one that works).
Can be improved in a future PR. For now, it does the job.

Copy link
Contributor

@rakanalh rakanalh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great... left some comments.

elif chain_id == 42:
etherscan_api = 'https://api-kovan.etherscan.io/api'
elif chain_id == 1:
etherscan_api = 'https://api.etherscan.io/api'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nitpick:
I think for this we can use a dictionary where:

{
3: "'https://api-ropsten.etherscan.io/api'",
4: "https://api-rinkeby.etherscan.io/api",
... etc
}

And use .get(chain_id) to fetch the URL that needs to be called.

if contract_name is None or contract_name == CONTRACT_SECRET_REGISTRY:
path = source_path['raiden'].joinpath(f'{CONTRACT_SECRET_REGISTRY}.sol')
source = path.read_text()
constructor_args = ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be refactored somehow into it's own function? as this block uses the same code as the block above it.

source = source.replace('import "raiden/TokenNetwork.sol";\n', '')

flatten_path = Path(__file__).parent.joinpath('flatten.sol')
flatten_path.open('w').write(source)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kudos for using pathlib 👍

)[0]['inputs']
]
constructor_args = encode_abi(constructor_types, constructor_arguments).hex()
print('constructor_args', constructor_arguments, constructor_types, constructor_args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover?

Copy link
Contributor Author

@loredanacirstea loredanacirstea Nov 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I wanted the constructor_args shown because automatic verification failed for some reason for TokenNetworkRegistry and you need to paste these manually in Etherscan.
True, pprint or using logging would be better.

'runs': metadata['settings']['optimizer']['runs'],
'constructorArguments': constructor_args,
}
print({k: v for k, v in data.items() if k is not 'sourceCode'})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good idea to use pprint to have the data printed a bit more readable?

@loredanacirstea
Copy link
Contributor Author

@rakanalh valid review points, thank you. Can we merge this as is and link your suggestions in an issue, to be fixed later? (you can also pick this up if you want) I did not want to spend more time on this script for now.

Copy link
Contributor

@rakanalh rakanalh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure... approving the PR for the comments to be addressed later on in a separate PR.

@loredanacirstea
Copy link
Contributor Author

Thank you. Documented the improvements here: #349, so anyone can pick it up when they have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatic contract verification on Etherscan
2 participants