Skip to content

Commit

Permalink
add Address::new_p2pk(ErgoTree);
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat committed Nov 6, 2020
1 parent 6579efc commit 03870d0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 19 deletions.
13 changes: 4 additions & 9 deletions bindings/ergo-lib-wasm/src/address.rs
@@ -1,14 +1,11 @@
//! Address types

use ergo_lib::chain;
use wasm_bindgen::prelude::*;
use ergo_lib::{
serialization::{SigmaSerializable},
sigma_protocol::{
dlog_group::EcPoint,
sigma_boolean::{ProveDlog},
},
serialization::SigmaSerializable,
sigma_protocol::{dlog_group::EcPoint, sigma_boolean::ProveDlog},
};
use wasm_bindgen::prelude::*;

/// Network type
#[wasm_bindgen]
Expand Down Expand Up @@ -41,7 +38,6 @@ impl From<chain::address::NetworkPrefix> for NetworkPrefix {
}
}


/// Address types
#[wasm_bindgen]
#[repr(u8)]
Expand Down Expand Up @@ -76,7 +72,6 @@ impl From<chain::address::AddressTypePrefix> for AddressTypePrefix {
}
}


/**
* An address is a short string corresponding to some script used to protect a box. Unlike (string-encoded) binary
* representation of a script, an address has some useful characteristics:
Expand Down Expand Up @@ -142,7 +137,7 @@ impl Address {
.map_err(|e| JsValue::from_str(&format!("{}", e)))
}

/// Decode (base58) address from string
/// Decode (base58) address from string without checking the network prefix
pub fn from_base58(s: &str) -> Result<Address, JsValue> {
chain::address::AddressEncoder::unchecked_parse_address_from_str(s)
.map(Address)
Expand Down
51 changes: 41 additions & 10 deletions ergo-lib/src/chain/address.rs
@@ -1,6 +1,9 @@
//! Address types

use super::digest32;
use crate::ast::Constant;
use crate::ast::ConstantVal;
use crate::ErgoTreeParsingError;
use crate::{
ast::Expr,
serialization::{SerializationError, SigmaSerializable},
Expand Down Expand Up @@ -69,6 +72,29 @@ pub enum Address {
}

impl Address {
/// Create a P2PK address from an ergo tree if ProveDlog is the root of the tree, otherwise returns an error
pub fn new_p2pk(tree: &ErgoTree) -> Result<Address, AddressError> {
let expr = &*tree.proposition()?;
match expr {
Expr::Const(Constant {
tpe: _,
v: ConstantVal::SigmaProp(sp),
}) => match sp.value() {
SigmaBoolean::ProofOfKnowledge(SigmaProofOfKnowledgeTree::ProveDlog(
prove_dlog,
)) => Ok(Address::P2PK(prove_dlog.clone())),
_ => Err(AddressError::UnexpectedErgoTree(
tree.clone(),
"Expected ErgoTree with ProveDlog as root".to_string(),
)),
},
_ => Err(AddressError::UnexpectedErgoTree(
tree.clone(),
"Expected ErgoTree with ProveDlog as root".to_string(),
)),
}
}

/// address type prefix (for encoding)
pub fn address_type_prefix(&self) -> AddressTypePrefix {
match self {
Expand Down Expand Up @@ -98,11 +124,17 @@ impl Address {
Address::P2S(bytes) => ErgoTree::sigma_parse_bytes(bytes.to_vec()),
}
}
}

/// Create an address from an ergo tree
pub fn from_ergo_tree(tree: &ErgoTree) -> Address {
// TODO
}
/// Errors for Address processing
#[derive(Error, Eq, PartialEq, Debug, Clone)]
pub enum AddressError {
/// Unexpected ErgoTree encountered
#[error("Unexpected ErgoTree: {0:?}, \n reason: {1}")]
UnexpectedErgoTree(ErgoTree, String),
/// ErgoTree parsing error
#[error("ErgoTree parsing error: {0}")]
ErgoTreeParsingError(#[from] ErgoTreeParsingError),
}

/// Address types
Expand Down Expand Up @@ -232,7 +264,7 @@ impl AddressEncoder {
if bytes.len() < AddressEncoder::MIN_ADDRESS_LENGTH {
return Err(AddressEncoderError::InvalidSize);
};
self.check_head_byte(bytes[0])?;
self.check_head_byte(bytes[0])?;
AddressEncoder::try_parse_address(&bytes)
}

Expand All @@ -246,7 +278,7 @@ impl AddressEncoder {
}

/// parse address from Base58 encoded string
fn try_parse_address(bytes: &Vec<u8>) -> Result<Address, AddressEncoderError> {
fn try_parse_address(bytes: &[u8]) -> Result<Address, AddressEncoderError> {
let (without_checksum, checksum) =
bytes.split_at(bytes.len() - AddressEncoder::CHECKSUM_LENGTH);
let calculated_checksum = AddressEncoder::calc_checksum(without_checksum);
Expand Down Expand Up @@ -303,12 +335,11 @@ mod tests {
proptest! {

#[test]
fn ergo_tree_roundtrip(address in any::<Address>()) {
fn ergo_tree_p2pk_roundtrip(prove_dlog in any::<ProveDlog>()) {
let encoder = AddressEncoder::new(NetworkPrefix::Testnet);

let address = Address::P2PK(prove_dlog);
let ergo_tree = address.script().unwrap();
let address_copy = Address::from_ergo_tree(&ergo_tree);

let address_copy = Address::new_p2pk(&ergo_tree).unwrap();
let encoded_addr = encoder.address_to_str(&address);
let encoded_addr_copy = encoder.address_to_str(&address_copy);

Expand Down

0 comments on commit 03870d0

Please sign in to comment.