Skip to content

Instantly share code, notes, and snippets.

@leejw51crypto
Created May 24, 2021 01:45
Show Gist options
  • Save leejw51crypto/0586941b2c44e3866b249763010e539b to your computer and use it in GitHub Desktop.
Save leejw51crypto/0586941b2c44e3866b249763010e539b to your computer and use it in GitHub Desktop.
bitcoin, eth address test
[package]
name = "AddressConverter"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bech32 = "0.8.0"
tiny-hderive = "0.3.0"
tiny-bip39 = "0.8.0"
ethsign = "0.8.0"
failure = ""
bitcoin = { version = "=0.26", features = ["use-serde"] }
hdpath = { version = "0.6.0", features = ["with-bitcoin"] }
ripemd160 = "0.9.1"
sha2 = "0.9.3"
hex= "0.4.3"
use bech32::{self, FromBase32, ToBase32, Variant};
use bip39::{Language, Mnemonic, MnemonicType, Seed};
use ethsign::SecretKey;
use std::convert::{TryFrom, TryInto};
//use tiny_hderive::bip32::ExtendedPrivKey;
use bitcoin::{
network::constants::Network,
secp256k1::Secp256k1,
util::bip32::{DerivationPath, ExtendedPrivKey, ExtendedPubKey},
};
use failure::format_err;
use hdpath::StandardHDPath;
use ripemd160::Ripemd160;
use sha2::{Digest, Sha256};
fn generate_eth(mnemonicwords: &str, coin_type: u32) -> Result<(), failure::Error> {
println!("eth");
let mnemonic = Mnemonic::from_phrase(mnemonicwords, Language::English)
.map_err(|e| failure::format_err!("get mnemonics"))?;
let seed = Seed::new(&mnemonic, "");
let seed_bytes: &[u8] = seed.as_bytes();
println!("seed bytes {}", hex::encode(seed_bytes).to_uppercase());
let ext = tiny_hderive::bip32::ExtendedPrivKey::derive(
seed_bytes,
format!("m/44'/{}'/0'/0/0", coin_type).as_str(),
)
.map_err(|_| format_err!("tiny_hderive"))?;
let secret_key = SecretKey::from_raw(&ext.secret())?;
let public_key = secret_key.public();
let v=public_key.bytes();
println!("publickey {} {}", public_key.bytes().len(), hex::encode(v).to_uppercase());
//println!("address {:?}", public_key.address());
let encoded = bech32::encode("cro", public_key.address().to_base32(), Variant::Bech32)
.map_err(|_| format_err!("bech32"))?;
//println!("{:?}", public_key.address().len());
//println!("{}", encoded);
Ok(())
}
/// Decode an extended private key from a mnemonic
fn private_key_from_mnemonic(
mnemonic_words: &str,
coin_type: u32,
) -> Result<ExtendedPrivKey, failure::Error> {
let mnemonic = Mnemonic::from_phrase(mnemonic_words, Language::English)
.map_err(|e| format_err!("get menmonic"))?;
let seed = Seed::new(&mnemonic, "");
println!("seed bytes {}", hex::encode(seed.as_bytes()).to_uppercase());
// Get Private Key from seed and standard derivation path
let hd_path_format = format!("m/44'/{}'/0'/0/0", coin_type);
println!("hd_path_format {}", hd_path_format);
let hd_path =
StandardHDPath::try_from(hd_path_format.as_str()).map_err(|_| format_err!("hdpath"))?;
let private_key = ExtendedPrivKey::new_master(Network::Bitcoin, seed.as_bytes())
.and_then(|k| k.derive_priv(&Secp256k1::new(), &DerivationPath::from(hd_path)))
.map_err(|_| format_err!("derivekey"))?;
Ok(private_key)
}
fn get_address(pk: ExtendedPubKey) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(pk.public_key.to_bytes().as_slice());
// Read hash digest over the public key bytes & consume hasher
let pk_hash = hasher.finalize();
// Plug the hash result into the next crypto hash function.
let mut rip_hasher = Ripemd160::new();
rip_hasher.update(pk_hash);
let rip_result = rip_hasher.finalize();
rip_result.to_vec()
}
fn generate_bitcoin(mnemonics: &str, coin_type: u32) -> Result<(), failure::Error> {
println!("bitcoin");
println!("mnemonics {}", mnemonics);
println!("coin type {:?}", coin_type);
// Get the private key from the mnemonic
let private_key = private_key_from_mnemonic(mnemonics, coin_type)?;
// Get the public Key from the private key
let mut public_key = ExtendedPubKey::from_private(&Secp256k1::new(), &private_key);
public_key.public_key.compressed=false;
let buf= public_key.public_key.to_bytes();
let buf2=&buf[1..65];
println!("publickey {} {}", buf2.len(), hex::encode(buf2).to_uppercase());
// Get address from the public Key
let address = get_address(public_key);
//println!("addres {:?}", address);
// Compute Bech32 account
let account = bech32::encode("cro", address.to_base32(), Variant::Bech32)
.map_err(|e| format_err!("get account error"))?;
//println!("account {}", account);
Ok(())
}
fn main() -> Result<(), failure::Error> {
println!("address converter");
let mnemonics = std::env::var("MYMNEMONICS")?;
generate_bitcoin(&mnemonics, 394)?;
println!("#####################################################");
generate_eth(&mnemonics, 394)?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment