Ethereum is a popular public blockchain that makes it possible to create unstoppable applications in a permissionless fashion. It’s available to every user that has an Ethereum account. These Ethereum accounts consist of a private and an associated public key.
The main challenge as a user participating in a public blockchain such as Ethereum is safely managing the blockchain credentials.
Because an externally owned Ethereum account is required to approve transactions, including funds transfers and other sensitive operations, its key material must be carefully safeguarded.
In some fully decentralized applications, the user is expected to manage their own key material. There are other applications, however, where it may be desirable to entrust the management of key material to an external process or service, such as when the key material is frequently needed even when the user isn’t available. This is a common requirement for token staking and other modern blockchain applications.
This post series explains how to create a solution using AWS Key Management Service (AWS KMS). In this first post, we cover the following aspects:
Develop and build cloud infrastructure templates using the AWS Cloud Development Kit (AWS CDK) and Python
Bundle and deploy the AWS CDK-based AWS Lambda functions using Docker
Configure and provision a new AWS KMS-based Ethereum account using a customer master key (CMK)
The second post focuses on the inner workings of Ethereum and how to use the created CMK instance as a secure Ethereum key management service.
The following diagram illustrates our solution architecture.
The scope of the provided solution in the AWS CDK repository is limited to the area within the dotted red line.
For this walkthrough, you must have the following prerequisites:
An AWS account
An AWS Identity and Access Management (IAM) user with administrator access
Configured AWS credentials
Docker, Node.js, Python 3, and pip installed on the workstation that you plan to deploy the solution from
Deploy the solution with the AWS CDK
The AWS CDK command line interface (CLI) allows you to interact with AWS CDK applications. It provides features like synthesizing AWS CloudFormation templates, confirming the security changes, and deploying applications.
This section shows how to prepare the environment for running the AWS CDK and the sample code.
When working with Python, it’s good practice to use venv to create project-specific virtual environments. The use of venv also reflects AWS CDK standard behavior. You can find out more in the workshop Activating the virtualenv.
To install the sample application, complete the following steps:
Install the AWS CDK and test the AWS CDK CLI:
Download the code from the GitHub repo and change into the new directory:
Download the lambci/lambda:build-python3.8 Docker container:
Install the dependencies using the Python package manager:
Deploy the sample code with the AWS CDK CLI:
AWS CDK asks for an additional confirmation to deploy the solution, as shown in the following screenshot.
Enter y to confirm.
This deploys the derived CloudFormation template to the AWS account you have specified. You can see additional details about the deployment process and the stack (configuration and resources) by navigating to the AWS CloudFormation console and choosing the aws-kms-lambda-ethereum stack.
After the deployment is complete, the terminal shows us the CloudFormation stack ARN as well as the CMK KeyID.
Sign an Ethereum transaction with a CMK
To create and sign an Ethereum transaction that can be published to the Ethereum network, you need an account that is sufficiently funded. To fund an account on an Ethereum testnet like Rinkeby, you can use the Rinkeby faucet.
To determine the CMK-based Ethereum address, you first need to run a Lambda function that returns the public Ethereum address of the CMK-based account.
On the Lambda console, choose the newly created aws-kms-lambda-ethereum-ethkmsclientFunction Lambda function.
The random suffix attached to the Lambda function is related to how the AWS CDK names and identifies the resources.
After you choose the function, choose the Test tab.
Use the following JSON snippet as the request for your new test event:
A successful run of the test event calculates the matching Ethereum address for the CMK public key and returns it as the checksum enabled address (eth_checksum_address) as shown in the following screenshot.
To create and sign an Ethereum transaction with the given CMK-based address, run a Lambda function using the following JSON snippet:
In the preceding JSON snippet, Amount specifies the amount of ether to send, dst_address specifies the Ethereum destination address, and nonce specifies the current number of transactions on the sending address.
Because the AWS KMS-based address has never been used, the nonce value must be 0 for the first transaction.
If the correct parameters have been provided, the sign operation returns the signed transaction as a hex string wrapped in a JSON object.
Congratulations! You have created your first AWS KMS CMK-backed Ethereum transaction.
To send off the transaction via an Amazon Managed Blockchain Ethereum node, follow the instructions in Deploying an Ethereum Node on Amazon Managed Blockchain. The newly created Lambda function from the referenced blog authenticates with your dedicated Amazon Managed Blockchain Ethereum node using Signature Version 4 authentication. You have to provide the hex encoded Ethereum transaction as an input parameter to the Ethereum client Lambda function as shown in the following Node.JS example below.
What is happening under the hood?
The CMK source code repository cloned to your local workstation contains two files that define the CloudFormation template, which defines the AWS Cloud infrastructure as shown in our solution architecture.
The app.py file defines the stack name, which is specified as aws-kms-lambda-ethereum. Furthermore, this file imports the stack definition from aws_kms_lambda_ethereum.aws_kms_lambda_ethereum_stack, which is located in the aws-kms-ethereum-accounts folder.
During the cdk deploy or cdk synthesize step, this high-level construct is translated into a CloudFormation statement.
The high-level API available in Python allows you to specify the expected type, default values, or a regular expression that is required to be matched.
To add additional modules, list them in the setup.py file in the repository root folder.
These modules are installed during the pip install step mentioned earlier.
In the stack definition file, you can now import these modules in the standard Python way:
Read MoreAWS Database Blog