Last active
December 23, 2021 15:15
-
-
Save benjaminion/6d24491abe01a40e728c37f0834f5009 to your computer and use it in GitHub Desktop.
Convert Eth2 EIP-2335 scrypt keystores to pbkdf2 keystores
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Converts Eth2 EIP-2335 scrypt keystores to pbkdf2 keystores | |
# | |
# Requires ethdo (https://github.com/wealdtech/ethdo) and jq. | |
# | |
# Tested with ethdo v1.7.3 and Teku v0.12.5+508-g03d75b2 | |
# | |
# Notes: | |
# - I'd definitely do this off-line and air-gapped. | |
# - The files in INPUT_DIR and PASS_DIR are not modified. | |
# - Take care of directory and file permissions. This script assumes it can | |
# access everything it needs to, and doesn't make any special settings. | |
# - The following abuses ethdo in various undeserved ways... | |
### Settings #### | |
ethdo=~/bin/ethdo | |
# The existing keystores in Teku's normal ingestion format. | |
# Individual keystores are named <x>.json | |
INPUT_DIR=`pwd`/validator_keys_scrypt | |
# Where the pbkdf2 files will be written to. | |
# They will end up with the same format as INPUT_DIR. | |
OUTPUT_DIR=`pwd`/validator_keys_pbkdf2 | |
# Keystore passwords are here. One file named <x>.txt for each <x>.json. | |
# Passwords are unchanged by the process. | |
PASS_DIR=`pwd`/passwords | |
### Processing ### | |
echo Using ethdo version $($ethdo version) | |
echo Using output directory $OUTPUT_DIR | |
if [ "$INPUT_DIR" == "$OUTPUT_DIR" ]; then | |
echo "ERROR: output directory cannot be the same as input directory" >&2 | |
exit 1; | |
fi | |
mkdir -p $OUTPUT_DIR | |
WALLET1=Wallet1 | |
WALLET2=Wallet2 | |
## Create wallets | |
if $ethdo wallet list | grep $WALLET1 > /dev/null; then | |
echo Deleting $WALLET1 | |
$ethdo wallet delete --wallet=$WALLET1 | |
fi | |
if $ethdo wallet list | grep $WALLET2 > /dev/null; then | |
echo Deleting $WALLET2 | |
$ethdo wallet delete --wallet=$WALLET2 | |
fi | |
echo Creating wallet $WALLET1 | |
$ethdo wallet create --wallet=$WALLET1 | |
echo Creating wallet $WALLET2 | |
$ethdo wallet create --wallet=$WALLET2 | |
## Find out where the wallets are stored in the filesystem | |
wallet1_dir=$($ethdo wallet info --verbose --wallet=$WALLET1 | grep 'Location:' | cut -c 11-) | |
wallet2_dir=$($ethdo wallet info --verbose --wallet=$WALLET2 | grep 'Location:' | cut -c 11-) | |
echo Wallet1 directory: $wallet1_dir | |
echo Wallet2 directory: $wallet2_dir | |
## Repeatedly populate the wallet with accounts to convert | |
n=0 | |
for keystore in $INPUT_DIR/*.json | |
do | |
echo Processing $keystore | |
## Extract UUID of the account | |
uuid=$(cat $keystore | jq '.uuid' | tr -d '"') | |
## Add account name to the keystore and copy it into Wallet1 | |
account=Account$(printf "%05d" $n) | |
cat $keystore | jq -c ". * {name: \"$account\"}" > $wallet1_dir/$uuid | |
cat $wallet1_dir/index | jq -c ". += [{uuid:\"$uuid\",name:\"$account\"}]" > $wallet1_dir/index_tmp && mv $wallet1_dir/index_tmp $wallet1_dir/index | |
base=$(basename -s '.json' $keystore) | |
password=$(cat $PASS_DIR/$base.txt) | |
# Export the private key from the original (scrypt) wallet account and | |
# immediately import it into a new (pbkdf2) wallet account | |
$ethdo account import --key=$($ethdo account key --account=$WALLET1/$account --passphrase=$password) --account=$WALLET2/$account --passphrase=$password --allow-weak-passphrases | |
## Copy the new (pbkdf2) keystore to the output directory | |
echo Copying new keystore to the output directory | |
new_uuid=$(cat $wallet2_dir/index | jq '.[0].uuid' | tr -d '"') | |
cp $wallet2_dir/$new_uuid $OUTPUT_DIR/$base.json | |
# Ethdo does not helpfully order the accounts in the wallet, and there seems to be | |
# no clean way to delete an account, so we reset the index by force. | |
echo -n '[]' > $wallet2_dir/index | |
((n++)) | |
done | |
## Tidy up | |
echo Deleting wallet $WALLET1 | |
$ethdo wallet delete --wallet=$WALLET1 | |
rm -rf $wallet1_dir | |
echo Deleting wallet $WALLET2 | |
$ethdo wallet delete --wallet=$WALLET2 | |
rm -rf $wallet2_dir |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment