diff --git a/rust/examples/global_contract_accountid.rs b/rust/examples/global_contract_accountid.rs new file mode 100644 index 0000000..d33df26 --- /dev/null +++ b/rust/examples/global_contract_accountid.rs @@ -0,0 +1,73 @@ +use dotenv::from_filename; +use std::str::FromStr; +use std::time::{SystemTime, UNIX_EPOCH}; +use near_api::*; +use near_crypto::SecretKey; +use near_primitives::views::FinalExecutionOutcomeView; + +/// Example deploying a contract to the global contract code storage as account-id +#[tokio::main] +async fn main() { + // Load environment variables + from_filename("../.env").unwrap(); + let private_key_string = std::env::var("PRIVATE_KEY").unwrap(); + let account_id_string = std::env::var("ACCOUNT_ID").unwrap(); + let private_key = SecretKey::from_str(&private_key_string).unwrap(); + + let global_account_id: AccountId = account_id_string.parse().unwrap(); + let global_code = std::fs::read("../contracts/contract.wasm").unwrap(); + let global_signer = Signer::new(Signer::from_secret_key(private_key)).unwrap(); + + // Deploy the global contract code using the account ID `nft-contract.testnet` + // This will deploy the contract to the specified account ID + // and return the final execution outcome + let result: FinalExecutionOutcomeView = Contract::deploy_global_contract_code(global_code) + .as_account_id(global_account_id.clone()) + .with_signer(global_signer.clone()) + .send_to_testnet() + .await.unwrap(); + + println!("{:?}", result); + + // Create a .testnet account with private key + // Generate a new account ID based on the current timestamp + let new_account_id: AccountId = format!( + "{}.testnet", + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() + ) + .parse() + .unwrap(); + + let private_key = signer::generate_secret_key().unwrap(); + let create_account_result = Account::create_account(new_account_id.clone()) + .fund_myself( + global_account_id.clone(), + NearToken::from_millinear(100), // Initial balance for new account in yoctoNEAR + ) + .public_key(private_key.public_key()).unwrap() + .with_signer(global_signer.clone()) // Signer is the account that is creating the new account + .send_to_testnet() + .await + .unwrap(); + + println!("{:?}", create_account_result); + + // Prepare a transaction to deploy a contract to the provided account using a mutable account-id reference to the code from the global contract code storage. + // This is useful for deploying contracts that are meant to be used by multiple accounts or for creating a contract that can be updated later. + // + // Please note that you have to trust the account-id that you are providing. As the code is mutable, the owner of the referenced account can + // change the code at any time which might lead to unexpected behavior or malicious activity. + let my_signer = Signer::new(Signer::from_secret_key(private_key)).unwrap(); + + let result: FinalExecutionOutcomeView = Contract::deploy(new_account_id) + .use_global_account_id(global_account_id) + .without_init_call() + .with_signer(my_signer) + .send_to_testnet() + .await.unwrap(); + + println!("{:?}", result); +} diff --git a/rust/examples/global_contract_hash.rs b/rust/examples/global_contract_hash.rs new file mode 100644 index 0000000..02d632b --- /dev/null +++ b/rust/examples/global_contract_hash.rs @@ -0,0 +1,73 @@ +use dotenv::from_filename; +use std::str::FromStr; +use std::time::{SystemTime, UNIX_EPOCH}; +use near_api::*; +use near_crypto::SecretKey; +use near_primitives::views::FinalExecutionOutcomeView; + +/// Example deploying a contract to the global contract code storage as hash +#[tokio::main] +async fn main() { + // Load environment variables + from_filename("../.env").unwrap(); + let private_key_string = std::env::var("PRIVATE_KEY").unwrap(); + let account_id_string = std::env::var("ACCOUNT_ID").unwrap(); + let private_key = SecretKey::from_str(&private_key_string).unwrap(); + + let account_id: AccountId = account_id_string.parse().unwrap(); + let code = std::fs::read("../contracts/contract.wasm").unwrap(); + let signer = Signer::new(Signer::from_secret_key(private_key)).unwrap(); + + // Deploy the global contract code using a hash + // This will deploy the contract to the global contract hash + // and return the final execution outcome + let result: FinalExecutionOutcomeView = Contract::deploy_global_contract_code(code.clone()) + .as_hash() + .with_signer(account_id.clone(), signer.clone()) + .send_to_testnet() + .await.unwrap(); + + println!("{:?}", result); + + // Deployed global contract's hash + let global_hash = near_primitives::hash::CryptoHash::hash_bytes(&code); + println!("Global contract hash: {:?}", global_hash); + + // Create a .testnet account with private key + // Generate a new account ID based on the current timestamp + let new_account_id: AccountId = format!( + "{}.testnet", + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() + ) + .parse() + .unwrap(); + + let private_key = signer::generate_secret_key().unwrap(); + let create_account_result = Account::create_account(new_account_id.clone()) + .fund_myself( + account_id.clone(), + NearToken::from_millinear(100), // Initial balance for new account in yoctoNEAR + ) + .public_key(private_key.public_key()).unwrap() + .with_signer(signer.clone()) // Signer is the account that is creating the new account + .send_to_testnet() + .await + .unwrap(); + + println!("{:?}", create_account_result); + + // Prepare a transaction to deploy a contract to the provided account using an immutable hash reference to the code from the global contract code storage. + let my_signer = Signer::new(Signer::from_secret_key(private_key)).unwrap(); + + let result: FinalExecutionOutcomeView = Contract::deploy(new_account_id) + .use_global_hash(global_hash.into()) + .without_init_call() + .with_signer(my_signer) + .send_to_testnet() + .await.unwrap(); + + println!("{:?}", result); +}