From a0979fb8f650c933d4e5be47b04b017f8c93d99a Mon Sep 17 00:00:00 2001 From: Jerome P Date: Tue, 4 Feb 2025 10:52:32 -0800 Subject: [PATCH] Switched out originator account creation from python script to Makefile to make it more CI friendly and implement less code --- Makefile | 51 +++++++++++++++++++++++++++-- cmd/genkey/genkey.go | 25 ++++++++++++-- integration_test.py | 41 +++++++++++------------ script/flow.json | 78 ++++++++++++++++++++++++++++++++------------ 4 files changed, 150 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index 350445c..7a17972 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,76 @@ -.PHONY: all build +# Set default values +ACCOUNT_KEYS_FILENAME = "./account-keys.csv" +FLOW_JSON = "script/flow.json" +FLOW_JSON_NETWORK = "emulator" +FLOW_JSON_SIGNER = emulator-account +FLOW_CLI_FLAGS = -n $(FLOW_JSON_NETWORK) -f $(FLOW_JSON) --signer $(FLOW_JSON_SIGNER) +ROSETTA_NETWORK = "localnet" +ROSETTA_HOST_URL = "http://127.0.0.1:8080" +COMPILER_FLAGS := CGO_CFLAGS="-O2 -D__BLST_PORTABLE__" +.PHONY: all build all: build +.PHONY: go-build go-build: - go build -o server cmd/server/server.go + ${COMPILER_FLAGS} go build -o server cmd/server/server.go + +.PHONY: gen-originator-account +gen-originator-account: + set -e; \ + KEYS=$$(go run ./cmd/genkey/genkey.go -csv); \ + PUBLIC_FLOW_KEY=$$(echo $$KEYS | cut -d',' -f1); \ + PUBLIC_ROSETTA_KEY=$$(echo $$KEYS | cut -d',' -f2); \ + PRIVATE_KEY=$$(echo $$KEYS | cut -d',' -f3); \ + echo "Created keys:"; \ + echo "Flow Key: $$PUBLIC_FLOW_KEY"; \ + echo "Rosetta Key: $$PUBLIC_ROSETTA_KEY"; \ + echo "Private Key: $$PRIVATE_KEY"; \ + address=$$(flow accounts create --sig-algo ECDSA_secp256k1 --key $$PUBLIC_FLOW_KEY $(FLOW_CLI_FLAGS) | grep "Address" | cut -d' ' -f2 | cut -c3-);\ + echo "Address created: $$address"; \ + jq --arg account_name "$(ACCOUNT_NAME)" '.accounts[$$account_name] = { \ + "address": "'$$address'", \ + "key": { \ + "type": "hex", \ + "index": 0, \ + "signatureAlgorithm": "ECDSA_secp256k1", \ + "hashAlgorithm": "SHA3_256", \ + "privateKey": "'$$PRIVATE_KEY'" \ + } \ + }' "${FLOW_JSON}" > flow.json.tmp && mv flow.json.tmp "${FLOW_JSON}" || { echo "Failed to update flow.json with jq"; exit 1; }; \ + echo "$(ACCOUNT_NAME),$$KEYS,$$address" >> $(ACCOUNT_KEYS_FILENAME); \ + echo "Updated $(FLOW_JSON) and $(ACCOUNT_KEYS_FILENAME)"; + +.PHONY: build build: go-build +.PHONY: deps deps: go mod download -x +.PHONY: fix-lint +fix-lint: + golangci-lint run -v --fix ./... + +.PHONY: lint lint: @go mod tidy @staticcheck ./... +.PHONY: proto proto: @echo ">> Generating model/model.pb.go" @protoc --proto_path=model --go_out=model \ --go_opt=paths=source_relative model/model.proto +.PHONY: integration-test-cleanup integration-test-cleanup: rm -f flow.json rm -f account-keys.csv rm -rf data rm -rf flow-go +.PHONY: integration-test integration-test: python3 integration_test.py \ No newline at end of file diff --git a/cmd/genkey/genkey.go b/cmd/genkey/genkey.go index 1f4e743..7177131 100644 --- a/cmd/genkey/genkey.go +++ b/cmd/genkey/genkey.go @@ -2,6 +2,7 @@ package main import ( + "flag" "fmt" "log" @@ -9,12 +10,30 @@ import ( ) func main() { + // Define a flag for output format + csvOutput := flag.Bool("csv", false, "Output keys in CSV format") + flag.Parse() + + // Generate private key priv, err := secp256k1.GeneratePrivateKey() if err != nil { log.Fatalf("Failed to generate key: %s", err) } + + // Generate public keys pub := priv.PubKey() - fmt.Printf("Public Key (Flow Format): %x\n", pub.SerializeUncompressed()[1:]) - fmt.Printf("Public Key (Rosetta Format): %x\n", pub.SerializeCompressed()) - fmt.Printf("Private Key: %x\n", priv.Serialize()) + publicFlowKey := fmt.Sprintf("%x", pub.SerializeUncompressed()[1:]) + publicRosettaKey := fmt.Sprintf("%x", pub.SerializeCompressed()) + privateKey := fmt.Sprintf("%x", priv.Serialize()) + + // Output based on the flag + if *csvOutput { + // Output as a single line in CSV format + fmt.Printf("%s,%s,%s\n", publicFlowKey, publicRosettaKey, privateKey) + } else { + // Human-readable output + fmt.Printf("Public Key (Flow Format): %s\n", publicFlowKey) + fmt.Printf("Public Key (Rosetta Format): %s\n", publicRosettaKey) + fmt.Printf("Private Key: %s\n", privateKey) + } } diff --git a/integration_test.py b/integration_test.py index c773148..0ea6093 100644 --- a/integration_test.py +++ b/integration_test.py @@ -29,9 +29,10 @@ } } +signer_account = "localnet-service-account" number_of_contract_accounts = 2 -localnet_flags = ['-n', 'localnet'] -service_account_flags = ['-f', 'flow.json', '--signer', 'localnet-service-account'] +localnet_flags = ['-n', 'localnet', '-f', 'script/flow.json'] +service_account_flags = ['--signer', signer_account] rosetta_host_url = "http://127.0.0.1:8080" ###################################################################################### @@ -72,7 +73,7 @@ def init_flow_json(): with open('flow.json', 'w') as json_file: json.dump(localnet_const, json_file, indent=4) - +# Deprecated after move to Makefile def gen_contract_account(account_name): public_flow_key, public_rosetta_key, private_key = gen_account_keys() @@ -112,7 +113,7 @@ def gen_contract_account(account_name): # Open flow.json in read and write mode and load its content as a JSON object. # Add the new account to the JSON object under the key specified by account_name. # Write back the modified JSON object to the file and truncate any remaining content. - with open('flow.json', "r+") as json_file: + with open('script/flow.json', "r+") as json_file: data = json.load(json_file) data["accounts"][account_name] = contract_account_value json_file.seek(0) @@ -144,7 +145,7 @@ def seed_contract_accounts(): reader = csv.reader(file_object) for row in reader: address = row[-1] - seed_cmd = "flow transactions send script/cadence/transactions/basic-transfer.cdc " + address + " 100.0 --signer localnet-service-account" + seed_cmd = "flow transactions send script/cadence/transactions/basic-transfer.cdc " + address + " 100.0 --signer " + signer_account cmds = seed_cmd.split(" ") + localnet_flags result = subprocess.run(cmds, stdout=subprocess.PIPE) @@ -153,7 +154,7 @@ def seed_contract_accounts(): ### Helper Functions ###################################################################################### - +# Deprecated after move to Makefile def gen_account_keys(): gen_key_cmd = "go run ./cmd/genkey/genkey.go" result = subprocess.run(gen_key_cmd.split(" "), stdout=subprocess.PIPE) @@ -163,6 +164,7 @@ def gen_account_keys(): private_key = keys[2].split(" ")[-1] return (public_flow_key, public_rosetta_key, private_key) +# Deprecated after move to Makefile def get_account_keys(account): with open("account-keys.csv") as search: for line in search: @@ -180,7 +182,6 @@ def request_router(target_url, body): ### Rosetta Construction Functions ###################################################################################### - def rosetta_create_account(root_originator, root_originator_name="root-originator-account-1", i=0): public_flow_key, public_rosetta_key, new_private_key = gen_account_keys() transaction = "create_account" @@ -463,24 +464,24 @@ def submit_transaction(signed_tx): def main(): - clone_flowgo_cmd() - build_flow() - init_localnet() - init_flow_json() - for i in range(1,number_of_contract_accounts+1): - account_str = "root-originator-account-" + str(i) - gen_contract_account(account_str) - deploy_contracts(account_str) - setup_rosetta() + # clone_flowgo_cmd() + # build_flow() + # init_localnet() + # init_flow_json() + # for i in range(1,number_of_contract_accounts+1): + # account_str = "root-originator-account-" + str(i) + # gen_contract_account(account_str) + # deploy_contracts(account_str) + # setup_rosetta() seed_contract_accounts() _, _, _, root_address = get_account_keys("root-originator-account-1") - print("root_address" + root_address) - # rosetta_create_account(root_address, "root-originator-account-1") + print("root_address: " + root_address) + rosetta_create_account(root_address, "root-originator-account-1") # rosetta_create_proxy_account(root_address, "root-originator-account-1") - # _, _, _, new_address = get_account_keys("root-originator-account-1-create_account") + _, _, _, new_address = get_account_keys("root-originator-account-1-create_account") - # rosetta_transfer(root_address, new_address, 50) + rosetta_transfer(root_address, new_address, 50) # _, _, _, new_proxy_address = get_account_keys("root-originator-account-1-create_proxy_account") # rosetta_transfer(root_address, new_proxy_address, 50) # _, _, _, flow_account_address = get_account_keys("flow-account") diff --git a/script/flow.json b/script/flow.json index 4fe160d..51ea91f 100644 --- a/script/flow.json +++ b/script/flow.json @@ -1,21 +1,59 @@ { - "emulators": { - "default": { - "port": 3569, - "serviceAccount": "emulator-account" - } - }, - "contracts": {}, - "networks": { - "emulator": "127.0.0.1:3569", - "mainnet": "access.mainnet.nodes.onflow.org:9000", - "testnet": "access.devnet.nodes.onflow.org:9000" - }, - "accounts": { - "emulator-account": { - "address": "f8d6e0586b0a20c7", - "key": "91a22fbd87392b019fbe332c32695c14cf2ba5b6521476a8540228bdf1987068" - } - }, - "deployments": {} -} \ No newline at end of file + "emulators": { + "default": { + "port": 3569, + "serviceAccount": "emulator-account" + } + }, + "contracts": {}, + "networks": { + "emulator": "127.0.0.1:3569", + "testing": "127.0.0.1:3569", + "localnet": "192.168.1.186:4001", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" + }, + "accounts": { + "emulator-account": { + "address": "f8d6e0586b0a20c7", + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "privateKey": "04264ea6342c0dae476c7b7d327e8ba369e605db8314758f7af7bab790ec787b" + } + }, + "localnet-service-account": { + "address": "f8d6e0586b0a20c7", + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA2_256", + "privateKey": "8ae3d0461cfed6d6f49bfc25fa899351c39d1bd21fdba8c87595b6c49bb4cc43" + } + }, + "root-originator-account-1": { + "address": "1beecc6fef95b62e", + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_secp256k1", + "hashAlgorithm": "SHA3_256", + "privateKey": "f0cd40495618388f333147b8b6b6be8ef5b279aed520ffa256fcb2a73cba6227" + } + }, + "root-originator-account-2": { + "address": "ff8975b2fe6fb6f1", + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_secp256k1", + "hashAlgorithm": "SHA3_256", + "privateKey": "4dd3d8b317934a4101c15bd1944e89f77d7062a4ad1f4b24d39191f036c9f7bd" + } + } + }, + "deployments": {} +}