Skip to content

Instantly share code, notes, and snippets.

@Jackarain
Last active June 3, 2025 14:30
Show Gist options
  • Save Jackarain/644a7b6e7a786d10f54dcf4f23ddad7a to your computer and use it in GitHub Desktop.
Save Jackarain/644a7b6e7a786d10f54dcf4f23ddad7a to your computer and use it in GitHub Desktop.
btc/eth/tron 地址转换
/*
* 需要安装以下依赖:
* yarn add ethers bitcoinjs-lib ecpair tiny-secp256k1 bs58
* yarn add @types/bitcoinjs-lib @types/ecpair @types/tiny-secp256k1 @types/bs58
* yarn add ts-node typescript
*/
import { ethers } from 'ethers';
import { ECPairFactory } from 'ecpair';
import bitcoin from 'bitcoinjs-lib';
import * as tinysecp from 'tiny-secp256k1';
import bs58 from 'bs58';
// 确保 tinysecp 被正确注册
const ECPair = ECPairFactory(tinysecp);
// 生成以太坊公钥和地址
function getEthereumAddress(pKey: string): void {
try {
const wallet: ethers.Wallet = new ethers.Wallet(pKey);
console.log('以太坊地址:', wallet.address);
} catch (error) {
console.error('以太坊地址生成失败:', (error as Error).message);
}
}
// 生成比特币地址(BTC)
function getBitcoinAddress(pKey: string): void {
try {
const keyPair = ECPair.fromPrivateKey(Buffer.from(pKey, 'hex'));
bitcoin.initEccLib(tinysecp);
const pubkey: Buffer = Buffer.isBuffer(keyPair.publicKey)
? keyPair.publicKey
: Buffer.from(keyPair.publicKey);
// 生成 P2PKH 地址
const p2pkh = bitcoin.payments.p2pkh({ pubkey });
console.log('P2PKH 地址:', p2pkh.address);
// 生成 P2WPKH 地址
const p2wpkh = bitcoin.payments.p2wpkh({ pubkey });
console.log('P2WPKH 地址:', p2wpkh.address);
// 生成 P2TR 地址(隔离见证)
const internalPubkey: Buffer = pubkey.subarray(1, 33);
const p2tr = bitcoin.payments.p2tr({ internalPubkey });
console.log('P2TR 地址:', p2tr.address);
} catch (error) {
console.error('比特币地址生成失败:', (error as Error).message);
}
}
// 生成波场(TRON)地址
function getTronAddress(pKey: string): void {
try {
const signingKey = new ethers.SigningKey(Buffer.from(pKey, 'hex'));
const publicKey: string = signingKey.publicKey; // 非压缩公钥(含04前缀)
const publicKeyBuffer: Buffer = Buffer.from(publicKey.slice(2), 'hex');
// 使用顶层 keccak256 方法
const hash: string = ethers.keccak256(publicKeyBuffer.subarray(1));
const addressHex: string = hash.slice(-40);
const addressBuffer: Buffer = Buffer.from(addressHex, 'hex');
const prefix: Buffer = Buffer.from([0x41]);
const rawAddress: Buffer = Buffer.concat([prefix, addressBuffer]);
const sha256Once: Buffer = bitcoin.crypto.sha256(rawAddress);
const sha256Twice: Buffer = bitcoin.crypto.sha256(sha256Once);
const checksum: Buffer = sha256Twice.subarray(0, 4);
const finalBuffer: Buffer = Buffer.concat([rawAddress, checksum]);
const tronAddress: string = bs58.encode(finalBuffer);
console.log('波场地址:', tronAddress);
} catch (error) {
console.error('波场地址生成失败:', (error as Error).message);
}
}
// 主函数
function main(pKey : string) {
// 移除私钥开头的 '0x'(如果有),生成一个干净的私钥字符串
const cleanPrivateKey: string = pKey.startsWith('0x') ? pKey.slice(2) : pKey;
// 验证私钥格式(必须是64位16进制)
if (!/^[0-9a-fA-F]{64}$/.test(cleanPrivateKey)) {
console.error('无效的私钥格式!私钥必须是64位16进制字符串。');
return;
}
// 获取比特币地址
getBitcoinAddress(cleanPrivateKey);
// 获取以太坊地址
getEthereumAddress(cleanPrivateKey);
// 获取波场地址
getTronAddress(cleanPrivateKey);
}
// 从命令行获取私钥参数 [6,7,8](@ref)
const args: string[] = process.argv.slice(2);
if (args.length === 0) {
console.error('错误:请提供私钥作为命令行参数');
console.error('示例:yarn start e3ee395e5aeee67299e93bef917e8462e458da6543a3b52e041bc754b5132dbc');
process.exit(1);
}
// 执行
main(args[0]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment