Skip to content

Commit cc9479e

Browse files
committed
fix: use subnet_leader_mnemonic to update subnet contract
1 parent 68fc223 commit cc9479e

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

components/clarinet-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ base58 = "0.2.0"
134134
ctrlc = "3.1.9"
135135
strum = { version = "0.23.0", features = ["derive"] }
136136
bitcoin = "0.29.2"
137+
tiny-hderive = "0.3.0"
137138
segment = { version = "0.1.2", optional = true }
138139
mac_address = { version = "1.1.2", optional = true }
139140
tower-lsp = { version = "0.18.0", optional = true }

components/clarinet-cli/src/frontend/cli.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ use clarinet_deployments::{
2525
use clarinet_files::{
2626
get_manifest_location, FileLocation, ProjectManifest, ProjectManifestFile, RequirementConfig,
2727
};
28+
use clarinet_utils::get_bip39_seed_from_mnemonic;
2829
use clarity_repl::analysis::call_checker::ContractAnalysis;
30+
use clarity_repl::clarity::address::AddressHashMode;
31+
use clarity_repl::clarity::stacks_common::types::chainstate::StacksAddress;
32+
use clarity_repl::clarity::util::hash::bytes_to_hex;
33+
use clarity_repl::clarity::util::secp256k1::Secp256k1PublicKey;
2934
use clarity_repl::clarity::vm::analysis::AnalysisDatabase;
3035
use clarity_repl::clarity::vm::costs::LimitedCostTracker;
3136
use clarity_repl::clarity::vm::diagnostic::{Diagnostic, Level};
@@ -34,13 +39,15 @@ use clarity_repl::clarity::ClarityVersion;
3439
use clarity_repl::repl::diagnostic::{output_code, output_diagnostic};
3540
use clarity_repl::repl::{ClarityCodeSource, ClarityContract, ContractDeployer, DEFAULT_EPOCH};
3641
use clarity_repl::{analysis, repl, Terminal};
42+
use libsecp256k1::{PublicKey, SecretKey};
3743
use stacks_network::chainhook_event_observer::chainhooks::types::ChainhookSpecification;
3844
use stacks_network::chainhook_event_observer::utils::Context;
3945
use stacks_network::{self, DevnetOrchestrator};
4046
use std::collections::HashMap;
4147
use std::fs::{self, File};
4248
use std::io::prelude::*;
4349
use std::{env, process};
50+
use tiny_hderive::bip32::ExtendedPrivKey;
4451

4552
use clap::{IntoApp, Parser, Subcommand};
4653
use clap_generate::{Generator, Shell};
@@ -1302,7 +1309,11 @@ pub fn main() {
13021309
}
13031310
}
13041311
.issuer;
1305-
1312+
let subnet_leader = compute_stx_address(
1313+
&devnet_config.subnet_leader_mnemonic,
1314+
&devnet_config.subnet_leader_derivation_path,
1315+
&StacksNetwork::Devnet,
1316+
);
13061317
let _ = fs::create_dir(format!("{}/requirements", cache_location.display()));
13071318

13081319
let ctx = Context {
@@ -1314,6 +1325,7 @@ pub fn main() {
13141325
&ctx,
13151326
cache_location,
13161327
&subnet_deployer,
1328+
&subnet_leader.into(),
13171329
)) {
13181330
Ok(_) => {}
13191331
Err(e) => {
@@ -1951,6 +1963,40 @@ impl DiagnosticsDigest {
19511963
}
19521964
}
19531965

1966+
pub fn compute_stx_address(
1967+
mnemonic: &str,
1968+
derivation_path: &str,
1969+
network: &StacksNetwork,
1970+
) -> StacksAddress {
1971+
let bip39_seed = match get_bip39_seed_from_mnemonic(&mnemonic, "") {
1972+
Ok(bip39_seed) => bip39_seed,
1973+
Err(_) => panic!(),
1974+
};
1975+
1976+
let ext = ExtendedPrivKey::derive(&bip39_seed[..], derivation_path).unwrap();
1977+
1978+
let secret_key = SecretKey::parse_slice(&ext.secret()).unwrap();
1979+
1980+
// Enforce a 33 bytes secret key format, expected by Stacks
1981+
let mut secret_key_bytes = secret_key.serialize().to_vec();
1982+
secret_key_bytes.push(1);
1983+
let miner_secret_key_hex = bytes_to_hex(&secret_key_bytes);
1984+
1985+
let public_key = PublicKey::from_secret_key(&secret_key);
1986+
let pub_key = Secp256k1PublicKey::from_slice(&public_key.serialize_compressed()).unwrap();
1987+
let version = clarity_repl::clarity::address::C32_ADDRESS_VERSION_TESTNET_SINGLESIG;
1988+
1989+
let stx_address = StacksAddress::from_public_keys(
1990+
version,
1991+
&AddressHashMode::SerializeP2PKH,
1992+
1,
1993+
&vec![pub_key],
1994+
)
1995+
.unwrap();
1996+
1997+
stx_address
1998+
}
1999+
19542000
fn display_separator() {
19552001
println!("{}", yellow!("----------------------------"));
19562002
}

components/clarinet-files/src/network_manifest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ impl NetworkManifest {
690690
let subnet_events_ingestion_port =
691691
devnet_config.subnet_events_ingestion_port.unwrap_or(30445);
692692

693-
let mut stacks_node_events_observers = devnet_config
693+
let stacks_node_events_observers = devnet_config
694694
.stacks_node_events_observers
695695
.take()
696696
.unwrap_or(vec![]);

components/stacks-network/src/orchestrator.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ use reqwest::RequestBuilder;
2727
use serde_json::Value;
2828
use std::collections::HashMap;
2929
use std::fs::{self, File};
30-
use std::io::{Cursor, Write};
30+
use std::io::{Cursor, Read, Write};
3131
use std::path::PathBuf;
3232
use std::sync::mpsc::{Receiver, Sender};
3333
use std::time::Duration;
34+
use tar::EntryType;
3435

3536
#[derive(Debug)]
3637
pub struct DevnetOrchestrator {
@@ -1399,6 +1400,7 @@ events_keys = ["*"]
13991400
ctx: &Context,
14001401
cache_dir: PathBuf,
14011402
deployer: &StandardPrincipalData,
1403+
miner: &StandardPrincipalData,
14021404
) -> Result<(), String> {
14031405
let (docker, devnet_config) = match (&self.docker_client, &self.network_config) {
14041406
(Some(ref docker), Some(ref network_config)) => match network_config.devnet {
@@ -1478,9 +1480,21 @@ events_keys = ["*"]
14781480
};
14791481
let contract_path = prefix.join(filename_str);
14801482

1481-
entry
1482-
.unpack(contract_path.clone())
1483-
.map_err(|e| e.to_string())?;
1483+
// Write the contract file, replacing the miner address
1484+
if entry.header().entry_type() == EntryType::Regular {
1485+
let mut buffer = String::new();
1486+
entry
1487+
.read_to_string(&mut buffer)
1488+
.map_err(|e| e.to_string())?;
1489+
let contract_content = buffer.replace(
1490+
"(define-data-var miner principal tx-sender)",
1491+
&format!("(define-data-var miner principal '{})", &miner),
1492+
);
1493+
let contract_file = FileLocation::from_path(contract_path.clone());
1494+
contract_file
1495+
.write_content(contract_content.as_bytes())
1496+
.map_err(|e| e.to_string())?;
1497+
}
14841498

14851499
// Write the metadata file
14861500
let metadata_path = contract_path.with_extension("json");

0 commit comments

Comments
 (0)