Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ It also includes a script for getting the emitted events from a transaction.
## Read returned value from tx

[This example](/getting-tx-return-value) shows how to get the return value from a mined transaction.

## AWS encrypted credentials

[This example](/aws-encrypted-credentials) shows how to have encrypted private keys on an environment file.
2 changes: 2 additions & 0 deletions aws-encrypted-credentials/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
KMS_KEY_ID=
PRIVATE_KEY=
1 change: 1 addition & 0 deletions aws-encrypted-credentials/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
21 changes: 21 additions & 0 deletions aws-encrypted-credentials/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# AWS encrypted credentials

This repository shows how you have encrypted environment credentials. Code on `hardhat.config.js` can be much cleaner, but its for demonstration purpose.

Main idea here is to avoid having unencrypted private key on environment files: Avoid leaking credentials on github, npm, or while showing something on a video call.

## Steps
1. Copy example environment file:
```bash
cp .env.example . env`
```
2. Set up your `KMS_KEY_ID` on your `.env`
```bash
nano .env
```
3. Run task to encrypt your private key
```bash
npx hardhat encrypt
```
4. Copy output of encrypted private key into the `.env` file

23 changes: 23 additions & 0 deletions aws-encrypted-credentials/contracts/Greeter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.7.0;

import "hardhat/console.sol";


contract Greeter {
string greeting;

constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
71 changes: 71 additions & 0 deletions aws-encrypted-credentials/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require("@nomiclabs/hardhat-waffle");
require("dotenv").config();
const inquirer = require('inquirer');
const { KMS } = require('aws-sdk');
const { utils } = require("ethers");

const DEFAULT_CLIENT_CONFIGURATION = {
apiVersion: '2014-11-01',
region: 'us-east-1',
};

const kms = new KMS(DEFAULT_CLIENT_CONFIGURATION);

const encrypt = async (stringToEncrypt) => {
const data = await kms
.encrypt({
KeyId: process.env.KMS_KEY_ID,
Plaintext: Buffer.from(stringToEncrypt),
})
.promise();
return data.CiphertextBlob.toString('base64');
};

const decrypt = (encryptedString) => {
let decryptedInfo = undefined;
let kill = false;
kms.decrypt(
{
CiphertextBlob: Buffer.from(encryptedString, 'base64'),
},
(error, data) => {
if (error) {
console.log('MKS:decryptSync error:');
console.log(error);
kill = true;
} else {
decryptedInfo = data;
}
}
);

while (decryptedInfo === undefined && !kill) {
require('deasync').sleep(25);
}
if (!decryptedInfo) return encryptedString;
return decryptedInfo.Plaintext.toString();
};

task("encrypt", "Encrypts credentials")
.setAction(async () => {
const answer = await inquirer.prompt([
{
type: 'password',
message: 'Enter private key',
name: 'privateKey',
mask: '*',
}
]);
const encryptedPrivateKey = await encrypt(answer.privateKey)
console.log('Encrypted credential, save this into your .env file:')
console.log(`PRIVATE_KEY=${encryptedPrivateKey}`);
});

module.exports = {
networks: {
hardhat: {
accounts: (!!process.env.PRIVATE_KEY && process.env.PRIVATE_KEY != '') ? [{ privateKey: decrypt(process.env.PRIVATE_KEY), balance: utils.parseEther('1').toString() }] : []
}
},
solidity: "0.7.3"
};
19 changes: 19 additions & 0 deletions aws-encrypted-credentials/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "aws-encrypted-credentials",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.0",
"chai": "^4.2.0",
"ethereum-waffle": "^3.0.0",
"ethers": "^5.0.0",
"hardhat": "^2.2.1"
},
"dependencies": {
"aws-sdk": "2.1029.0",
"deasync": "0.1.24",
"inquirer": "8.2.0"
}
}
32 changes: 32 additions & 0 deletions aws-encrypted-credentials/scripts/sample-script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// When running the script with `hardhat run <script>` you'll find the Hardhat
// Runtime Environment's members available in the global scope.
const hre = require("hardhat");

async function main() {
// Hardhat always runs the compile task when running scripts with its command
// line interface.
//
// If this script is run directly using `node` you may want to call compile
// manually to make sure everything is compiled
// await hre.run('compile');

// We get the contract to deploy
const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");

await greeter.deployed();

console.log("Greeter deployed to:", greeter.address);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
14 changes: 14 additions & 0 deletions aws-encrypted-credentials/test/sample-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { expect } = require("chai");

describe("Greeter", function() {
it("Should return the new greeting once it's changed", async function() {
const Greeter = await ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, world!");

await greeter.deployed();
expect(await greeter.greet()).to.equal("Hello, world!");

await greeter.setGreeting("Hola, mundo!");
expect(await greeter.greet()).to.equal("Hola, mundo!");
});
});
Loading