From 35b4db556609c57bfa1a5ecfe294f25c791a0ee4 Mon Sep 17 00:00:00 2001 From: Eugenio Paluello Date: Fri, 6 Sep 2024 17:55:27 +0200 Subject: [PATCH] feat: deploy Openzeppelin accounts script (#1396) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Time spent on this PR: 0.5 ## Pull request type Please check the type of change your PR introduces: - [ ] Bugfix - [x] Feature - [ ] Code style update (formatting, renaming) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [ ] Documentation content changes - [ ] Other (please describe): ## What is the current behavior? Resolves # ## What is the new behavior? Script that allows the deployment of OpenZeppelin accounts, saving the private key on AWS Secrets and exporting a JSON containing the addresses of the deployed accounts and the secret ID to retrieve the private key (file stored in `kakarot_scripts/data`). **Parameters to configure in order to run the script:** - **num_accounts** - The number of OZ accounts. - **amount** - The amount to send to the address to deploy the accounts. - **private_key** - The private key to use, which will also be saved on AWS Secrets. Therefore, it only needs to be provided the first time; in subsequent executions, you can use an empty string `""` to retrieve the previous key. Otherwise, the secret will be updated. - **class_hash** - The class hash of OpenZeppelinAccount. To interact with AWS Secrets, boto3 requires the AWS configuration variables to be set up. [Here is the documentation](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/configure/index.html) - - - This change is [Reviewable](https://reviewable.io/reviews/kkrt-labs/kakarot/1396) --- kakarot_scripts/constants.py | 3 ++ kakarot_scripts/utils/deploy_oz.py | 62 ++++++++++++++++++++++++++ kakarot_scripts/utils/starknet.py | 4 +- poetry.lock | 71 +++++++++++++++++++++++++++++- pyproject.toml | 1 + 5 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 kakarot_scripts/utils/deploy_oz.py diff --git a/kakarot_scripts/constants.py b/kakarot_scripts/constants.py index 72b363408..9af25dbc4 100644 --- a/kakarot_scripts/constants.py +++ b/kakarot_scripts/constants.py @@ -40,6 +40,7 @@ class NetworkType(Enum): "chain_id": StarknetChainId.MAINNET, "check_interval": 1, "max_wait": 10, + "class_hash": 0x061DAC032F228ABEF9C6626F995015233097AE253A7F72D68552DB02F2971B8F, }, "sepolia": { "name": "starknet-sepolia", @@ -50,6 +51,7 @@ class NetworkType(Enum): "chain_id": StarknetChainId.SEPOLIA, "check_interval": 1, "max_wait": 10, + "class_hash": 0x061DAC032F228ABEF9C6626F995015233097AE253A7F72D68552DB02F2971B8F, }, "starknet-devnet": { "name": "starknet-devnet", @@ -68,6 +70,7 @@ class NetworkType(Enum): "type": NetworkType.DEV, "check_interval": 0.01, "max_wait": 3, + "class_hash": 0x6153CCF69FD20F832C794DF36E19135F0070D0576144F0B47F75A226E4BE530, "relayers": [ { "address": 0xB3FF441A68610B30FD5E2ABBF3A1548EB6BA6F3559F2862BF2DC757E5828CA, diff --git a/kakarot_scripts/utils/deploy_oz.py b/kakarot_scripts/utils/deploy_oz.py new file mode 100644 index 000000000..77b200e5b --- /dev/null +++ b/kakarot_scripts/utils/deploy_oz.py @@ -0,0 +1,62 @@ +# %% Imports +import asyncio +import json +import logging +import secrets + +import boto3 + +from kakarot_scripts.utils.starknet import deploy_starknet_account + +# Initialize AWS Secrets Manager client +client = boto3.client("secretsmanager") +SECRET_NAME = "relayers_private_key" + +logging.basicConfig() +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + + +# %% Get private key +def get_private_key(): + """Retrieve or generate a private key.""" + try: + response = client.get_secret_value(SecretId=SECRET_NAME) + private_key = response["SecretString"] + secret_id = response["ARN"] + except client.exceptions.ResourceNotFoundException: + private_key = hex(secrets.randbits(256)) + secret_id = client.create_secret(Name=SECRET_NAME, SecretString=private_key)[ + "ARN" + ] + return private_key, secret_id + + +# %% Deploy accounts +async def main(): + """Deploy 'num_accounts' accounts and store the private keys in AWS Secrets Manager.""" + num_accounts = 30 # Number of accounts to create + amount = 0.1 # Initial funding amount for each relayer account + accounts_data = [] + private_key, secret_id = get_private_key() + + accounts_data = [ + { + "secret_id": secret_id, + "address": ( + await deploy_starknet_account(private_key=private_key, amount=amount) + )["address"], + } + for _ in range(num_accounts) + ] + logger.info(f"{num_accounts} accounts deployed and saved to 'oz_accounts.json'") + + # Save the account data to a JSON file + with open("kakarot_scripts/data/oz_accounts.json", "w") as json_file: + json.dump(accounts_data, json_file, indent=2) + + +# %% Run +if __name__ == "__main__": + # Deploy the accounts and store private keys in AWS Secrets Manager + asyncio.run(main()) diff --git a/kakarot_scripts/utils/starknet.py b/kakarot_scripts/utils/starknet.py index 587d71be8..fb326eed6 100644 --- a/kakarot_scripts/utils/starknet.py +++ b/kakarot_scripts/utils/starknet.py @@ -334,7 +334,9 @@ async def deploy_starknet_account(class_hash=None, private_key=None, amount=1): ) key_pair = KeyPair.from_private_key(int(private_key, 16)) constructor_calldata = [key_pair.public_key] - class_hash = class_hash or get_declarations()["OpenzeppelinAccount"] + class_hash = class_hash or NETWORK.get( + "class_hash", get_declarations().get("OpenzeppelinAccount") + ) address = compute_address( salt=salt, class_hash=class_hash, diff --git a/poetry.lock b/poetry.lock index ba05d5c28..3ced7342d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohttp" @@ -417,6 +417,44 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "boto3" +version = "1.35.12" +description = "The AWS SDK for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "boto3-1.35.12-py3-none-any.whl", hash = "sha256:acaa7c75cbf483605e3c46e9ac03043a4cf5e9866940122d68b06d1defe00774"}, + {file = "boto3-1.35.12.tar.gz", hash = "sha256:b32faab174f6f9b75fada27bcf054ab3e8846bd410ed9817d0b511109326b6b1"}, +] + +[package.dependencies] +botocore = ">=1.35.12,<1.36.0" +jmespath = ">=0.7.1,<2.0.0" +s3transfer = ">=0.10.0,<0.11.0" + +[package.extras] +crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] + +[[package]] +name = "botocore" +version = "1.35.12" +description = "Low-level, data-driven core of boto 3." +optional = false +python-versions = ">=3.8" +files = [ + {file = "botocore-1.35.12-py3-none-any.whl", hash = "sha256:cb787030415438ea6ff8381f8acd8b1107593d5ebea457fd843a5e36ba19e9a4"}, + {file = "botocore-1.35.12.tar.gz", hash = "sha256:a8f8230032d090225a93763675a73c208d121bb63ed99f41ee6ad3d51b74b80d"}, +] + +[package.dependencies] +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} + +[package.extras] +crt = ["awscrt (==0.21.2)"] + [[package]] name = "cached-property" version = "1.5.2" @@ -1892,6 +1930,17 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + [[package]] name = "joblib" version = "1.4.2" @@ -3484,6 +3533,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -3885,6 +3935,23 @@ files = [ {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, ] +[[package]] +name = "s3transfer" +version = "0.10.2" +description = "An Amazon S3 Transfer Manager" +optional = false +python-versions = ">=3.8" +files = [ + {file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"}, + {file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"}, +] + +[package.dependencies] +botocore = ">=1.33.2,<2.0a.0" + +[package.extras] +crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] + [[package]] name = "scikit-learn" version = "1.5.1" @@ -4620,4 +4687,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.11" -content-hash = "69c724616c0a807fe636f597665f8d0dbe5d80acc47f94038a5c20bcd9bfe65c" +content-hash = "9683cf7dacce11dd7a98325daaa9f1b56f136db87b14157f53cfafd3214ddcb6" diff --git a/pyproject.toml b/pyproject.toml index 69fdf0c54..c83b8e134 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ async-lru = "^2.0.4" toml = "^0.10.2" scikit-learn = "^1.5.1" seaborn = "^0.13.2" +boto3 = "^1.35.12" [tool.poetry.group.dev.dependencies] pytest = "^8.1.1"