Skip to content

Instantly share code, notes, and snippets.

@thor314
Created May 6, 2021 16:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thor314/1c790da7b5938fa2dfb0c9dc4a468eab to your computer and use it in GitHub Desktop.
Save thor314/1c790da7b5938fa2dfb0c9dc4a468eab to your computer and use it in GitHub Desktop.

Review:

public key

updated w public key. I think this means that the deployer of the factory can call near deploy <wasm_blob> <address of any store created by the factory>

  pub fn new() -> Self {
    assert!(!env::state_exists());
    let storage_price_per_byte = 10_000_000_000_000_000_000; // 10^19
    Self {
      ...
        public_key: env::signer_account_pk(),
    }
  }

    pub fn create_store(
    &mut self,
    metadata: NFTContractMetadataArgs,
    owner_id: ValidAccountId,
  ) -> Promise {
//...
  Promise::new(store_account_id.to_string())
  .create_account()
  .transfer(self.store_cost)
  .add_full_access_key(self.public_key.clone())
//...

like so:

near deploy --wasmFile new_mintbase_store.wasm --initFunction "new" --initArgs '{...}' --accountId $STORE

But then, how does the chain know I’m signing the transaction with the Factory public key?

market predecessor-base-account refactor

/// Assume accounts can have format:
/// 0. "12345678901234567890123456789012" return "12345678901234567890123456789012"
/// 1. "abc.near" => return "abc.near"
/// 2. "sub.abc.near" => return "abc.near"
/// 3. "dub.sub.abc.near" => return "sub.abc.near"
/// 4. "wub.dub.sub.abc.near" return "dub.sub.abc.near"
/// ... more periods
///
/// In other words:
/// case 0,1: return the whole account
/// case 2..:  return the account stripping the first prefix off
pub(crate) fn get_pred_base_account(&self) -> near_sdk::AccountId {
  let account = env::predecessor_account_id();
  if let Some(strip_prefix) = account.splitn(2, '.').nth(1) {
    match strip_prefix.splitn(2, '.').nth(1) {
      // case 2...
      Some(_) => strip_prefix.to_string(),
      // case 1
      None => account,
    }
  } else {
    // case 0
    account
  }
}

ext_nft_holder: circle back on this, there should be a way to do this.

/// Helper to get the holder of a top-level token on another contract.
pub(crate) fn ext_nft_holder(&self, token_id: U64, account_id: AccountId) -> Option<String> {
  ext_on_compose::nft_holder(token_id, &account_id, NO_DEPOSIT, DEFAULT_GAS / 5).then(
    ext_self::ext_nft_holder_callback(&env::current_account_id(), NO_DEPOSIT, DEFAULT_GAS / 5),
  );
  todo!();
}

this was a pretty useful demo of keys. Good link.

Migration

berryclub link - pre-planned migration

This seems like the least useful version of migration, as it seems to be predicated on knowldege of what the future contract state will need to be.

 #[init]
pub fn migrate_from_version_avocado() -> Self {
    let place_avocado: PlaceVersionAvocado = env::state_read().expect("Not initialized");
    Self {
        account_indices: place_avocado.account_indices,
        board: place_avocado.board,
        num_accounts: place_avocado.accounts.len() as u32,
        legacy_accounts: place_avocado.accounts,
        accounts: LookupMap::new(b"u".to_vec()),
        initialization_timestamp: place_avocado.initialization_timestamp,
        bought_balances: vec![place_avocado.minted_amount, 0],
        burned_balances: vec![place_avocado.burned_amount, 0],
        farmed_balances: vec![0, 0],
        vaults: LookupMap::new(b"v".to_vec()),
        next_vault_id: VaultId(0),
    }
}

near-sdk standard: seems nicer, but also I’m not certain how it would be used.

In particular, how does one call this method?

fn stage_code(&mut self, code: Vec<u8>, timestamp: Timestamp) {

Eg (see previous bullet): Two methods:

pub fn stage_blob_a(&mut self, blob: Vec<u8>);
pub fn stage_blob_b(&mut self, #[serializer(borsh)] blob: Vec<u8>);

How do I call either?

@evgenykuzyakov
Copy link

/// Helper to get the holder of a top-level token on another contract.
pub(crate) fn ext_nft_holder(&self, token_id: U64, account_id: AccountId) -> PromiseOrValue<String> {
  if account_id == env::current_account_id() {
    PromiseOrValue::Value(self.get_local_holder(token_id.0)) 
  } else {
    ext_on_compose::nft_holder(token_id, &account_id, NO_DEPOSIT, DEFAULT_GAS / 5).into()
  } 
}

@evgenykuzyakov
Copy link

Deployed example with the following methods:

pub fn stage_blob_a(&mut self, blob: Vec<u8>) {
        log!("stage_blob_a: {:?}", blob);
    }
    pub fn stage_blob_b(&mut self, #[serializer(borsh)] blob: Vec<u8>) {
        log!("stage_blob_b: {:?}", blob);
    }

Basic JSON call:

near call dev-1620322900771-3829357 stage_blob_a '{"blob": [10, 20, 30]}' --accountId=dev-1620322900771-3829357
Scheduling a call: dev-1620322900771-3829357.stage_blob_a({"blob": [10, 20, 30]})
Receipt: 127Ur4jYwF4FDT59iRg5EaCiAfQxyJDFB1ULJF1LRjnm
	Log [dev-1620322900771-3829357]: stage_blob_a: [10, 20, 30]

Equivalent borsh call:

Encode blob to borsh and then into base64 using python3:

import base64
blob = bytes([10, 20, 30])
blob_len = len(blob)
borsh_blob = blob_len.to_bytes(4, 'little') + blob
print(borsh_blob)
# b'\x03\x00\x00\x00\n\x14\x1e'
print(base64.b64encode(borsh_blob))
# b'AwAAAAoUHg=='
near call dev-1620322900771-3829357 stage_blob_b 'AwAAAAoUHg==' --base64 --accountId=dev-1620322900771-3829357
Scheduling a call: dev-1620322900771-3829357.stage_blob_b(AwAAAAoUHg==)
Receipt: GTp41KSwkEeieku54b5op7xU6gRCgb3eMP23AERbeNk1
	Log [dev-1620322900771-3829357]: stage_blob_b: [10, 20, 30]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment