Created
May 24, 2021 01:45
-
-
Save leejw51crypto/0586941b2c44e3866b249763010e539b to your computer and use it in GitHub Desktop.
bitcoin, eth address test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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