Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: secp256k1 account #2598

Merged
merged 6 commits into from
Sep 27, 2022
Merged
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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@
### fix: Only kill main process on `dfx stop`
Removes misleading panics when running `dfx stop`.

### feat: Initialise the nns with an account controlled by a secp256k1 key

This enables easy access to toy ICP using command line tools and this key:
```
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEICJxApEbuZznKFpV+VKACRK30i6+7u5Z13/DOl18cIC+oAcGBSuBBAAK
oUQDQgAEPas6Iag4TUx+Uop+3NhE6s3FlayFtbwdhRVjvOar0kPTfE/N8N6btRnd
74ly5xXEBNSXiENyxhEuzOZrIWMCNQ==
-----END EC PRIVATE KEY-----
```
For example, you can create an identity in dfx by putting this key in the file `ident-1.pem` and importing it:
```
dfx identity import ident-1 ident-1.pem
dfx --identity ident-1 ledger balance
```

### feat: default to run ic-wasm shrink when build canisters
This behavior applies to Motoko, Rust and Custom canisters.
If you want to disable this behavior, you can config it in dfx.json:
Expand Down
5 changes: 5 additions & 0 deletions e2e/assets/nns/ident-1/identity.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEICJxApEbuZznKFpV+VKACRK30i6+7u5Z13/DOl18cIC+oAcGBSuBBAAK
oUQDQgAEPas6Iag4TUx+Uop+3NhE6s3FlayFtbwdhRVjvOar0kPTfE/N8N6btRnd
74ly5xXEBNSXiENyxhEuzOZrIWMCNQ==
-----END EC PRIVATE KEY-----
19 changes: 18 additions & 1 deletion e2e/tests-dfx/nns.bash
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ assert_nns_canister_id_matches() {
dfx_start_for_nns_install
dfx nns install

echo Checking that the install worked...
echo "Checking that the install worked..."
echo " The expected wasms should be installed..."
# Note: The installation is quite expensive, so we test extensively on one installation
# rather than doing a separate installation for every test. The tests are read-only
# so no test should affect the output of another.
Expand Down Expand Up @@ -145,6 +146,22 @@ assert_nns_canister_id_matches() {
wasm_matches internet_identity internet_identity_dev.wasm
wasm_matches nns-dapp nns-dapp_local.wasm

echo " Accounts should have funds..."
account_has_funds() {
assert_command dfx ledger balance "$1"
assert_eq "1000000000.00000000 ICP"
}
SECP256K1_ACCOUNT_ID="2b8fbde99de881f695f279d2a892b1137bfe81a42d7694e064b1be58701e1138"
ED25519_ACCOUNT_ID="5b315d2f6702cb3a27d826161797d7b2c2e131cd312aece51d4d5574d1247087"
account_has_funds "$SECP256K1_ACCOUNT_ID"
account_has_funds "$ED25519_ACCOUNT_ID"

echo " The secp256k1 account can be controlled from the command line"
install_asset nns
dfx identity import --force --disable-encryption ident-1 ident-1/identity.pem
assert_command dfx ledger account-id --identity ident-1
assert_eq "$SECP256K1_ACCOUNT_ID"

echo Stopping dfx...
dfx stop
}
Expand Down
14 changes: 12 additions & 2 deletions src/dfx/src/lib/nns/install_nns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use ic_agent::Agent;
use ic_utils::interfaces::management_canister::builders::InstallMode;
use ic_utils::interfaces::ManagementCanister;
use reqwest::Url;
use std::ffi::OsStr;
use std::fs;
use std::io::Write;
use std::path::Component;
Expand Down Expand Up @@ -75,7 +76,10 @@ pub async fn install_nns(
let ic_nns_init_opts = IcNnsInitOpts {
wasm_dir: nns_wasm_dir(env),
nns_url: nns_url.to_string(),
test_accounts: Some(canisters::TEST_ACCOUNT.to_string()),
test_accounts: vec![
canisters::ED25519_TEST_ACCOUNT.to_string(),
canisters::SECP256K1_TEST_ACCOUNT.to_string(),
],
sns_subnets: Some(subnet_id.to_string()),
};
ic_nns_init(ic_nns_init_path, &ic_nns_init_opts).await?;
Expand Down Expand Up @@ -450,7 +454,7 @@ pub struct IcNnsInitOpts {
wasm_dir: PathBuf,
/// The ID of a test account that ic-nns-init will create and to initialise with tokens.
/// Note: At present only one test account is supported.
test_accounts: Option<String>,
test_accounts: Vec<String>,
/// A subnet for SNS canisters.
/// Note: In this context we support at most one subnet.
sns_subnets: Option<String>,
Expand All @@ -477,6 +481,12 @@ pub async fn ic_nns_init(ic_nns_init_path: &Path, opts: &IcNnsInitOpts) -> anyho
cmd.arg("--sns-subnet");
cmd.arg(subnet);
});
let args: Vec<_> = cmd
.get_args()
.into_iter()
.map(OsStr::to_string_lossy)
.collect();
println!("ic-nns-init {}", args.join(" "));
cmd.stdout(std::process::Stdio::inherit());
cmd.stderr(std::process::Stdio::inherit());
let output = cmd
Expand Down
31 changes: 30 additions & 1 deletion src/dfx/src/lib/nns/install_nns/canisters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,33 @@ pub const SNS_CANISTERS: [&SnsCanisterInstallation; 5] = [
];

/// Test account with well known public & private keys, used in NNS_LEDGER, NNS_DAPP and third party projects.
pub const TEST_ACCOUNT: &str = "5b315d2f6702cb3a27d826161797d7b2c2e131cd312aece51d4d5574d1247087";
/// The keys use the ED25519 curve, used for BasicIdentity on th eInternet Computer.
/// The keys are as follows, in the tweetnacl format used by agent-js:
/// ```
/// const publicKey = "Uu8wv55BKmk9ZErr6OIt5XR1kpEGXcOSOC1OYzrAwuk=";
/// const privateKey =
/// "N3HB8Hh2PrWqhWH2Qqgr1vbU9T3gb1zgdBD8ZOdlQnVS7zC/nkEqaT1kSuvo4i3ldHWSkQZdw5I4LU5jOsDC6Q==";
/// const identity = Ed25519KeyIdentity.fromKeyPair(
/// base64ToUInt8Array(publicKey),
/// base64ToUInt8Array(privateKey)
/// );
/// ```
pub const ED25519_TEST_ACCOUNT: &str =
"5b315d2f6702cb3a27d826161797d7b2c2e131cd312aece51d4d5574d1247087";

/// Test account for command line usage. The test account is typically called ident-1
/// The keys use the secp256k1 curve. To use:
/// ```
/// $ cat ~/.config/dfx/identity/ident-1/identity.pem
/// -----BEGIN EC PRIVATE KEY-----
/// MHQCAQEEICJxApEbuZznKFpV+VKACRK30i6+7u5Z13/DOl18cIC+oAcGBSuBBAAK
/// oUQDQgAEPas6Iag4TUx+Uop+3NhE6s3FlayFtbwdhRVjvOar0kPTfE/N8N6btRnd
/// 74ly5xXEBNSXiENyxhEuzOZrIWMCNQ==
/// -----END EC PRIVATE KEY-----
/// ```
/// The test account should match the output of:
/// ```
/// $ dfx --identity ident-1 ledger account-id
/// ```
pub const SECP256K1_TEST_ACCOUNT: &str =
"2b8fbde99de881f695f279d2a892b1137bfe81a42d7694e064b1be58701e1138";
Comment on lines +192 to +221
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using the anonymous identity for this? It's present for all dfx installations already so the key doesn't have to be imported

Copy link
Member Author

@bitdivine bitdivine Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way normal API calls can be used. In this PR the secp256k1 key matches the existing ed25519 account (5b...), where it is also the case that code needs to have and use the secret key explicitly. It is a "no magic" philosophy. That said, if we did initialize the anonymous identity with ICP, how would this work? What is the account ID of the anonymous identity and what dfx call would transfer funds from the anonymous identity to another? Does the anonymous account use secp256k1? I mean, there might well be a use case for giving the anonymous ID funds but we would probably want to check the ramifications. In the case of the pre-populated ed25519 the account can be, and is, used like any other account. The idea was to do the same here. We can change the current approach but is that what we want?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NVM, I stand corrected: I just tried it out, and the anonymous principal did receive ICP, but is not allowed to send:

❯ dfx ledger account-id --of-principal 2vxsx-fae
1c7a48ba6a562aa9eaa2481a9049cdf0433b9738c992d698c31d8abf89cadc79
❯ dfx-wip ledger balance $(dfx --identity anonymous ledger account-id)
1000000000.00000000 ICP
❯ dfx-wip --identity anonymous ledger transfer --amount 5.7 e213184a548871a47fb526f3cba24e2ee2fbbc8129c4ab497ef2ce535130a0a4 --memo 1284
[Canister ryjl3-tyaaa-aaaaa-aaaba-cai] Panicked at 'Sending from 2vxsx-fae is not allowed', rosetta-api/ledger_canister/src/main.rs:140:9

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Thank you for looking. I didn't know about dfx --identity anonymous. It is in the docs example of dfx identity list. That could be useful.