foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
8.13k stars 1.68k forks source link

Keystores exported from brownie could not be used #5572

Open ChiTimesChi opened 1 year ago

ChiTimesChi commented 1 year ago

Component

Forge

Have you ensured that all of these are up to date?

What version of Foundry are you on?

forge 0.2.0 (d4f626b 2023-08-09T00:21:28.739489228Z)

What command(s) is the bug in?

forge create; forge script

Operating System

Linux

Describe the bug

forge script as well as forge create doesn't seem to work with keystores exported/generated by brownie. This is quite unfortunate, as there's no option to export a keystore using cast wallet and a custom private key, at least until https://github.com/foundry-rs/foundry/pull/5551 is implemented.

Generating a Brownie keystore

First, import any private key into Brownie and export a keystore. We'll be using a known private key for this.

  1. $ brownie accounts new ones
  2. Type this not very secure private key: 1111111111111111111111111111111111111111111111111111111111111111
  3. Type this not very secure password for encryption ones.
  4. You should see SUCCESS: A new account '0x19E7E376E7C213B7E7e7e46cc70A5dD086DAff2A' has been generated with the id 'ones'
  5. $ brownie accounts export ones ./ones.json This should get you the keystore with the "encrypted" "private" key.

Pasting the resulting ones.json as is

{"address": "19e7e376e7c213b7e7e7e46cc70a5dd086daff2a", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "e5b40cf278493c6f30bdf6f09c479665"}, "ciphertext": "1681df71af78f6b2a4b1f586af06572e7a45a8409284f1af225d53ccd0f9275c", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "9f49ee3d090dd70f01de9562278b0971"}, "mac": "9e8eb87ebb16491a04f9aef9912c6145a024a22ea68ff7abdd92180a3e937ed2"}, "id": "3373aad8-f07c-48b5-b617-52d82f3154f5", "version": 3}

Deploying using brownie keystore

Now, try using this keystore. Obviously, don't send any funds to this address, we're only interested in whether the keystore could be decrypted.

Clone any Foundry-based repo. I usually use minimalistic Multicall3 repo: https://github.com/mds1/multicall/

Try deploying anything using this keystore:

forge create -r https://eth.llamarpc.com --keystore ones.json --password ones Multicall3
Error: 
Failed to decrypt keystore "ones.json"

Context:
- scrypt InvalidParams

Deploying using cast wallet keystore

Compare this to using the keystore for a random address, generated by cast wallet new . This one is protected by not a secure password by any means ripped.

Pasting the resulting ripped.json as is

{"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"163575c56116453d4a297d3c1565ff66"},"ciphertext":"f6fce3db1fdb3b7a5dfebb83f768b4feba31b1cbf2f1540109dc379493c6309b","kdf":"scrypt","kdfparams":{"dklen":32,"n":8192,"p":1,"r":8,"salt":"c6b1b9504ec0b070ac97d56802de529de028b7f6dea67bfcb99c6c237c821584"},"mac":"a2121b79cb5dc1df9b72da32df97f6f488a780850fe45ea2c51bddd2ab4f0cc9"},"id":"f63c2ab2-0a5c-4daa-806b-9ec2a2388420","version":3}
forge create -r https://eth.llamarpc.com --keystore ripped.json --password ripped Multicall3

In this case keystore is successfully decrypted:

Error: 
(code: -32000, message: insufficient funds for gas * price + value: address 0xE65Bc689E5ef8205d710f7B5E2477Daa6F23c5E8 have 0 want 29039692383000000000, data: None)

Deploying using brownie keystore with address field removed

You may have noticed that brownie keystore json file has as extra address field, but the error remains even if you rip it out.

jq 'del(.address)' ones.json > onesCleared.json

Pasting the resulting onesCleared.json as is

{
  "crypto": {
    "cipher": "aes-128-ctr",
    "cipherparams": {
      "iv": "e5b40cf278493c6f30bdf6f09c479665"
    },
    "ciphertext": "1681df71af78f6b2a4b1f586af06572e7a45a8409284f1af225d53ccd0f9275c",
    "kdf": "scrypt",
    "kdfparams": {
      "dklen": 32,
      "n": 262144,
      "r": 1,
      "p": 8,
      "salt": "9f49ee3d090dd70f01de9562278b0971"
    },
    "mac": "9e8eb87ebb16491a04f9aef9912c6145a024a22ea68ff7abdd92180a3e937ed2"
  },
  "id": "3373aad8-f07c-48b5-b617-52d82f3154f5",
  "version": 3
}
forge create -r https://eth.llamarpc.com --keystore onesCleared.json --password ones Multicall3

The very same error happens

Error: 
Failed to decrypt keystore "onesCleared.json"

Context:
- scrypt InvalidParams
maxsiz commented 7 months ago

@ChiTimesChi i face same problem. But I have more wide issue so could you please dm me in Telegram? https://t.me/msmobile

Rob-lg commented 4 months ago

Same problem, moving from an old Brownie project onto Foundry.

mattsse commented 3 months ago

hmm, this indeed fails because the settings violate a scrypt check:

https://github.com/RustCrypto/password-hashes/blob/b289d5a96192a2478dfe46c66bf964bf7d368eba/scrypt/src/params.rs#L67-L72

maybe exported blocksize (r) and parallelism factor (p) are switched, defaults are r=8,p=1