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

SdkAddress refactor #1809

Merged
merged 3 commits into from
Oct 7, 2024
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
6 changes: 3 additions & 3 deletions contracts/examples/multisig/interact/src/multisig_interact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ impl MultisigInteract {

MultiValueVec::from([
self.wallet_address.to_address(),
carol.address().to_bytes().into(),
dan.address().to_bytes().into(),
eve.address().to_bytes().into(),
carol.to_address(),
dan.to_address(),
eve.to_address(),
])
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use hex_literal::hex;
use multiversx_chain_core::types::Address;
use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput};

use crate::{
Expand Down Expand Up @@ -26,6 +27,10 @@ impl ESDTSystemSCAddress {
ManagedAddress::from(SYSTEM_SC_ADDRESS_BYTES)
}

pub fn to_address(&self) -> Address {
SYSTEM_SC_ADDRESS_BYTES.into()
}

pub fn to_bech32_str(&self) -> &str {
SYSTEM_SC_ADDRESS_BECH32
}
Expand Down
13 changes: 6 additions & 7 deletions framework/meta/src/cmd/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use core::str;

use crate::cli::{WalletAction, WalletArgs, WalletBech32Args, WalletConvertArgs, WalletNewArgs};
use multiversx_sc::types::{self};
use multiversx_sc_snippets::sdk::{
crypto::public_key::PublicKey, data::sdk_address::SdkAddress, wallet::Wallet,
};
use multiversx_sc::types::{self, Address};
use multiversx_sc_snippets::sdk::bech32;
use multiversx_sc_snippets::sdk::{crypto::public_key::PublicKey, wallet::Wallet};
use multiversx_sc_snippets::{hex, imports::Bech32Address};
use std::{
fs::{self, File},
Expand Down Expand Up @@ -137,9 +136,9 @@ fn bech32_conversion(bech32_args: &WalletBech32Args) {
}
}

fn get_wallet_address(private_key: &str) -> SdkAddress {
fn get_wallet_address(private_key: &str) -> Address {
let wallet = Wallet::from_private_key(private_key).unwrap();
wallet.address()
wallet.to_address()
}

fn new(new_args: &WalletNewArgs) {
Expand All @@ -151,7 +150,7 @@ fn new(new_args: &WalletNewArgs) {
let (private_key_str, public_key_str) = Wallet::get_wallet_keys_mnemonic(mnemonic.to_string());
let address = get_wallet_address(private_key_str.as_str());

println!("Wallet address: {}", address);
println!("Wallet address: {}", bech32::encode(&address));

match format {
Some("pem") => {
Expand Down
25 changes: 11 additions & 14 deletions framework/snippets-base/src/account_tool.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::sdk_core::data::{esdt::EsdtBalance, sdk_address::SdkAddress};
use crate::sdk_core::data::esdt::EsdtBalance;
use multiversx_chain_scenario_format::interpret_trait::IntoRaw;
use multiversx_sc_scenario::{
imports::Bech32Address,
Expand Down Expand Up @@ -40,34 +40,31 @@ fn build_scenario(set_state: SetStateStep) -> Scenario {
pub async fn retrieve_account_as_scenario_set_state<GatewayProxy: GatewayAsyncService>(
api: &GatewayProxy,
use_chain_simulator: bool,
address: &Bech32Address,
bech32_address: &Bech32Address,
) -> SetStateStep {
let sdk_address = SdkAddress::from_bech32_string(address.to_bech32_str()).unwrap();
let sdk_account = api
.request(GetAccountRequest::new(&sdk_address))
.await
.unwrap();
let address = bech32_address.as_address();
let sdk_account = api.request(GetAccountRequest::new(address)).await.unwrap();

let (account_esdt, account_esdt_roles, account_storage) = if use_chain_simulator {
(HashMap::new(), HashMap::new(), HashMap::new())
} else {
let account_esdt = api
.request(GetAccountEsdtTokensRequest::new(&sdk_address))
.request(GetAccountEsdtTokensRequest::new(address))
.await
.unwrap_or_else(|err| {
panic!("failed to retrieve ESDT tokens for address {address}: {err}")
panic!("failed to retrieve ESDT tokens for address {bech32_address}: {err}")
});
let account_esdt_roles = api
.request(GetAccountEsdtRolesRequest::new(&sdk_address))
.request(GetAccountEsdtRolesRequest::new(address))
.await
.unwrap_or_else(|err| {
panic!("failed to retrieve ESDT roles for address {address}: {err}")
panic!("failed to retrieve ESDT roles for address {bech32_address}: {err}")
});
let account_storage = api
.request(GetAccountStorageRequest::new(&sdk_address))
.request(GetAccountStorageRequest::new(address))
.await
.unwrap_or_else(|err| {
panic!("failed to retrieve storage for address {address}: {err}")
panic!("failed to retrieve storage for address {bech32_address}: {err}")
});

(account_esdt, account_esdt_roles, account_storage)
Expand All @@ -81,7 +78,7 @@ pub async fn retrieve_account_as_scenario_set_state<GatewayProxy: GatewayAsyncSe
);

let set_state_step = SetStateStep::new();
set_state_step.put_account(address, account_state)
set_state_step.put_account(bech32_address, account_state)
}

fn set_account(
Expand Down
6 changes: 2 additions & 4 deletions framework/snippets-base/src/interactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,9 @@ where
}

pub async fn register_wallet(&mut self, wallet: Wallet) -> Address {
let wallet_address = wallet.address();
let address = wallet.to_address();

self.send_user_funds(&wallet_address).await.unwrap();

let address: Address = wallet_address.into();
self.send_user_funds(&address).await.unwrap();
self.sender_map.insert(
address.clone(),
Sender {
Expand Down
14 changes: 5 additions & 9 deletions framework/snippets-base/src/interactor_chain_simulator.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use anyhow::Error;
use multiversx_sdk::{
data::sdk_address::SdkAddress,
gateway::{
ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest, GatewayAsyncService,
},
use multiversx_sc_scenario::imports::Address;
use multiversx_sdk::gateway::{
ChainSimulatorGenerateBlocksRequest, ChainSimulatorSendFundsRequest, GatewayAsyncService,
};

use crate::InteractorBase;
Expand All @@ -12,15 +10,13 @@ impl<GatewayProxy> InteractorBase<GatewayProxy>
where
GatewayProxy: GatewayAsyncService,
{
pub async fn send_user_funds(&self, receiver: &SdkAddress) -> Result<String, Error> {
pub async fn send_user_funds(&self, receiver: &Address) -> Result<String, Error> {
if !self.use_chain_simulator {
return Ok(String::from("no-simulator"));
}

self.proxy
.request(ChainSimulatorSendFundsRequest::to_address(
receiver.to_bech32_string().unwrap(),
))
.request(ChainSimulatorSendFundsRequest::to_address(receiver))
.await
}

Expand Down
2 changes: 1 addition & 1 deletion framework/snippets-base/src/interactor_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ where
pub async fn recall_nonce(&self, address: &Address) -> u64 {
let account = self
.proxy
.request(GetAccountRequest::new(&address.clone().into()))
.request(GetAccountRequest::new(address))
.await
.expect("failed to retrieve account nonce");
account.nonce
Expand Down
2 changes: 1 addition & 1 deletion framework/snippets-base/src/network_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ fn process_new_issued_token_identifier(tx: &TransactionOnNetwork) -> Option<Stri
let original_tx_data = String::from_utf8(base64_decode(tx.data.as_ref().unwrap())).unwrap();

for scr in tx.smart_contract_results.iter() {
if scr.sender.to_bech32_string().unwrap() != ESDTSystemSCAddress.to_bech32_string() {
if scr.sender.0 != ESDTSystemSCAddress.to_address() {
continue;
}

Expand Down
9 changes: 4 additions & 5 deletions framework/snippets-base/tests/test_tx_deployed_address.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use multiversx_sc_scenario::imports::Address;
use multiversx_sc_snippets_base::network_response;
use multiversx_sc_snippets_base::sdk::data::transaction::{TransactionInfo, TransactionOnNetwork};
use multiversx_sdk::bech32;

#[test]
fn test_deployed_address() {
Expand Down Expand Up @@ -54,11 +55,9 @@ fn test_deployed_address() {
.unwrap()
.transaction;
let tx_response = network_response::parse_tx_response(tx_on_network);
let opt_address = tx_response.new_deployed_address.map(|e| {
multiversx_sc_snippets_base::sdk::data::sdk_address::SdkAddress::from_bytes(*e.as_array())
.to_bech32_string()
.unwrap()
});
let opt_address = tx_response
.new_deployed_address
.map(|address| bech32::encode(&address));

let expected =
Some("erd1qqqqqqqqqqqqqpgqwpdf84ggxzqzmr2zmw959q4nlf9nz562q33sak25ze".to_string());
Expand Down
21 changes: 21 additions & 0 deletions sdk/core/src/bech32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! Duplicated between sdk and scnearios.
//!
//! TODO: de-duplicate, place in chain core crate, if possible.

use bech32::{Bech32, Hrp};
use multiversx_chain_core::types::Address;

pub fn decode(bech32_address: &str) -> Address {
let (_hrp, dest_address_bytes) = bech32::decode(bech32_address)
.unwrap_or_else(|err| panic!("bech32 decode error for {bech32_address}: {err}"));
if dest_address_bytes.len() != 32 {
panic!("Invalid address length after decoding")
}

Address::from_slice(&dest_address_bytes)
}

pub fn encode(address: &Address) -> String {
let hrp = Hrp::parse("erd").expect("invalid hrp");
bech32::encode::<Bech32>(hrp, address.as_bytes()).expect("bech32 encode error")
}
8 changes: 3 additions & 5 deletions sdk/core/src/crypto/public_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Display;

use super::private_key::PrivateKey;
use anyhow::Result;
use bech32::{self, Bech32, Hrp};
use multiversx_chain_core::types::Address;
use serde::{
de::{Deserialize, Deserializer},
ser::{Serialize, Serializer},
Expand All @@ -22,10 +22,8 @@ impl PublicKey {
&self.0
}

pub fn to_address(&self) -> Result<String> {
let hrp = Hrp::parse("erd")?;
let address = bech32::encode::<Bech32>(hrp, &self.0)?;
Ok(address)
pub fn to_address(&self) -> Address {
self.0.into()
}

pub fn from_hex_str(pk: &str) -> Result<Self> {
Expand Down
53 changes: 20 additions & 33 deletions sdk/core/src/data/sdk_address.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,52 @@
use std::fmt::{Debug, Display};

use crate::crypto::public_key::PublicKey;
use anyhow::Result;
use bech32::{Bech32, Hrp};
use multiversx_chain_core::types::Address;
use serde::{
de::{Deserialize, Deserializer},
ser::{Serialize, Serializer},
};

/// Wrapper around a regular Address.
///
/// Provides:
/// - serde serialization/deserialization as bech32
/// - conversions to/from bech32
///
/// It should only be used in the sdk, to serialize/deserialize to JSON as bech32.
///
/// It exists primarily because it is currently inconvenient to provide
/// bech32 and serde functionality to the base Address directly.
#[derive(Clone)]
pub struct SdkAddress([u8; 32]);
pub struct SdkAddress(pub Address);

impl SdkAddress {
pub fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
Self(Address::from(bytes))
}

pub fn to_bytes(&self) -> [u8; 32] {
self.0
*self.0.as_array()
}

pub fn from_bech32_string(bech32: &str) -> Result<Self> {
let (_hrp, data) = bech32::decode(bech32)?;

let mut bits: [u8; 32] = [0u8; 32];
bits.copy_from_slice(&data);

Ok(Self(bits))
Ok(SdkAddress(crate::bech32::decode(bech32)))
}

pub fn to_bech32_string(&self) -> Result<String> {
let hrp = Hrp::parse("erd")?;
let address = bech32::encode::<Bech32>(hrp, &self.0)?;
Ok(address)
}

pub fn is_valid(&self) -> bool {
self.0.len() == 32
Ok(crate::bech32::encode(&self.0))
}
}

impl From<multiversx_chain_core::types::Address> for SdkAddress {
fn from(value: multiversx_chain_core::types::Address) -> Self {
SdkAddress(*value.as_array())
SdkAddress(value)
}
}

impl From<SdkAddress> for multiversx_chain_core::types::Address {
fn from(value: SdkAddress) -> Self {
multiversx_chain_core::types::Address::new(value.0)
}
}

impl<'a> From<&'a PublicKey> for SdkAddress {
fn from(public_key: &PublicKey) -> SdkAddress {
let bytes = public_key.to_bytes();

let mut bits: [u8; 32] = [0u8; 32];
bits.copy_from_slice(&bytes);

SdkAddress(bits)
value.0
}
}

Expand All @@ -77,7 +64,7 @@ impl Debug for SdkAddress {

impl Default for SdkAddress {
fn default() -> Self {
SdkAddress::from_bytes([0u8; 32])
SdkAddress(Address::zero())
}
}

Expand Down Expand Up @@ -110,7 +97,7 @@ pub mod tests {
"erd1qqqqqqqqqqqqqpgqyfjjn43spw7teklwtpz4x5waygq2mluyj9ts0mdwn6",
)
.unwrap();
let encode = hex::encode(addr.to_bytes());
let encode = hex::encode(addr.0.as_bytes());
assert_eq!(
encode,
"00000000000000000500226529d6300bbcbcdbee58455351dd2200adff849157"
Expand Down
6 changes: 3 additions & 3 deletions sdk/core/src/gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ pub const DEVNET_GATEWAY: &str = "https://devnet-gateway.multiversx.com";
// MetachainShardId will be used to identify a shard ID as metachain
pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF;

const ACCOUNT_ENDPOINT: &str = "address/";
const KEYS_ENDPOINT: &str = "/keys/";
const ACCOUNT_ENDPOINT: &str = "address";
const KEYS_ENDPOINT: &str = "keys";
const NETWORK_CONFIG_ENDPOINT: &str = "network/config";
const NETWORK_ECONOMICS_ENDPOINT: &str = "network/economics";
const GET_NETWORK_STATUS_ENDPOINT: &str = "network/status";
Expand All @@ -51,7 +51,7 @@ const GET_HYPER_BLOCK_BY_HASH_ENDPOINT: &str = "hyperblock/by-hash";
const COST_TRANSACTION_ENDPOINT: &str = "transaction/cost";
const SEND_TRANSACTION_ENDPOINT: &str = "transaction/send";
const SEND_MULTIPLE_TRANSACTIONS_ENDPOINT: &str = "transaction/send-multiple";
const GET_TRANSACTION_INFO_ENDPOINT: &str = "transaction/";
const GET_TRANSACTION_INFO_ENDPOINT: &str = "transaction";
const WITH_RESULTS_QUERY_PARAM: &str = "?withResults=true";
const VM_VALUES_ENDPOINT: &str = "vm-values/query";

Expand Down
Loading
Loading