feat: use to_b58() and from_b58() for human readable peg_wallet_address field

This commit is contained in:
Aaron Blankstein
2023-01-19 16:43:15 -06:00
parent 3dd41c7357
commit d4a8d3e7f4
3 changed files with 86 additions and 8 deletions

View File

@@ -3,14 +3,8 @@
{
"amount": 1337,
"block_height": 217,
"burn_header_hash": "7ce0139a3fe356316409fe704dbdb9ac8f1847c168fe68bd913d0df75c359fe1",
"peg_wallet_address": {
"Addr32": [
false,
"P2TR",
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
]
},
"burn_header_hash": "66b2f18530ccf0e57e82dd054cca9fa41bf5f645f7757171ad9c1546b86387e1",
"peg_wallet_address": "tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkgkkf5",
"recipient": "S0000000000000000000002AA028H",
"recipient_contract_name": null,
"txid": "84808f747841fb26e74f171487e56eda1a51373581eb04a8c87a421a77bd46d2",

View File

@@ -332,6 +332,8 @@ pub struct PegInOp {
#[serde(deserialize_with = "crate::chainstate::stacks::address::address_deser")]
pub recipient: StacksAddress,
pub recipient_contract_name: Option<String>, // If set, makes the recepient a smart contract principal
#[serde(serialize_with = "crate::chainstate::stacks::address::pox_addr_b58_serialize")]
#[serde(deserialize_with = "crate::chainstate::stacks::address::pox_addr_b58_deser")]
pub peg_wallet_address: PoxAddress,
pub amount: u64, // BTC amount to peg in, in satoshis

View File

@@ -32,6 +32,7 @@ use crate::chainstate::stacks::{
C32_ADDRESS_VERSION_TESTNET_MULTISIG, C32_ADDRESS_VERSION_TESTNET_SINGLESIG,
};
use crate::net::Error as net_error;
use clarity::address::b58::{check_encode_slice, from_check};
use clarity::vm::types::{PrincipalData, SequenceData, StandardPrincipalData};
use clarity::vm::types::{TupleData, Value};
use serde::{Deserialize, Deserializer, Serializer};
@@ -106,6 +107,21 @@ pub fn address_deser<'de, D: Deserializer<'de>, T: Address>(deser: D) -> Result<
.ok_or_else(|| serde::de::Error::custom("Failed to decode address from string"))
}
/// Serializes a PoxAddress as a B58 check encoded address or a bech32 address
pub fn pox_addr_b58_serialize<S: Serializer>(
input: &PoxAddress,
ser: S,
) -> Result<S::Ok, S::Error> {
ser.serialize_str(&input.clone().to_b58())
}
/// Deserializes a PoxAddress from a B58 check encoded address or a bech32 address
pub fn pox_addr_b58_deser<'de, D: Deserializer<'de>>(deser: D) -> Result<PoxAddress, D::Error> {
let string_repr = String::deserialize(deser)?;
PoxAddress::from_b58(&string_repr)
.ok_or_else(|| serde::de::Error::custom("Failed to decode PoxAddress from string"))
}
impl std::fmt::Display for PoxAddress {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_db_string())
@@ -421,6 +437,15 @@ impl PoxAddress {
}
}
// Convert from a B58 encoded bitcoin address
pub fn from_b58(input: &str) -> Option<Self> {
let btc_addr = BitcoinAddress::from_string(input)?;
PoxAddress::try_from_bitcoin_output(&BitcoinTxOutput {
address: btc_addr,
units: 0,
})
}
/// Convert this PoxAddress into a Bitcoin tx output
pub fn to_bitcoin_tx_out(&self, value: u64) -> TxOut {
match *self {
@@ -1202,6 +1227,63 @@ mod test {
);
}
#[test]
fn test_pox_addr_from_b58() {
// representative test PoxAddresses
let pox_addrs: Vec<PoxAddress> = vec![
PoxAddress::Standard(
StacksAddress {
version: C32_ADDRESS_VERSION_MAINNET_SINGLESIG,
bytes: Hash160([0x01; 20]),
},
Some(AddressHashMode::SerializeP2PKH),
),
PoxAddress::Addr20(true, PoxAddressType20::P2WPKH, [0x01; 20]),
PoxAddress::Addr20(false, PoxAddressType20::P2WPKH, [0x01; 20]),
PoxAddress::Addr32(true, PoxAddressType32::P2WSH, [0x01; 32]),
PoxAddress::Addr32(false, PoxAddressType32::P2WSH, [0x01; 32]),
PoxAddress::Addr32(true, PoxAddressType32::P2TR, [0x01; 32]),
PoxAddress::Addr32(false, PoxAddressType32::P2TR, [0x01; 32]),
PoxAddress::Standard(
StacksAddress {
version: C32_ADDRESS_VERSION_MAINNET_MULTISIG,
bytes: Hash160([0x01; 20]),
},
Some(AddressHashMode::SerializeP2SH),
),
PoxAddress::Standard(
StacksAddress {
version: C32_ADDRESS_VERSION_MAINNET_SINGLESIG,
bytes: Hash160([0x01; 20]),
},
Some(AddressHashMode::SerializeP2SH),
),
PoxAddress::Standard(
StacksAddress {
version: C32_ADDRESS_VERSION_MAINNET_MULTISIG,
bytes: Hash160([0x01; 20]),
},
Some(AddressHashMode::SerializeP2WSH),
),
PoxAddress::Standard(
StacksAddress {
version: C32_ADDRESS_VERSION_MAINNET_MULTISIG,
bytes: Hash160([0x01; 20]),
},
Some(AddressHashMode::SerializeP2WPKH),
),
];
for addr in pox_addrs.iter() {
let addr_str = addr.clone().to_b58();
let addr_parsed = PoxAddress::from_b58(&addr_str).unwrap();
let mut addr_checked = addr.clone();
if let PoxAddress::Standard(_, ref mut hash_mode) = addr_checked {
hash_mode.take();
}
assert_eq!(&addr_parsed, &addr_checked);
}
}
#[test]
fn test_try_from_bitcoin_output() {
assert_eq!(