TronLink 钱包地址生成规则

662 阅读3分钟

TronLink 钱包地址生成规则

官网内容建议

以下是关于 TronLink 钱包地址生成规则的官网(www.tronlink.org/ 如无法正常进入可以访问网盘)内容建议,包含 Android 和 iOS 平台的实现细节:

TronLink 钱包地址生成机制

TronLink 使用标准的 TRON 地址生成流程,基于椭圆曲线数字签名算法 (ECDSA) 和 Keccak-256 哈希算法。Android 和 iOS 版本遵循相同的地址生成规则,确保跨平台兼容性。

地址生成步骤
  1. 生成私钥:随机生成 256 位私钥
  2. 导出公钥:使用 secp256k1 曲线从私钥推导出公钥
  3. 计算地址:对公钥进行 Keccak-256 哈希处理,取最后 20 字节作为地址
  4. 编码地址:添加前缀并转换为 Base58 格式

Android 实现代码示例

import org.tron.common.crypto.ECKey;
import org.tron.common.utils.Base58;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.Sha256Hash;

public class TronAddressGenerator {
    
    public static String generateTronAddress() {
        // 1. 生成新的ECKey (包含私钥和公钥)
        ECKey ecKey = new ECKey();
        
        // 2. 获取公钥字节数组
        byte[] publicKey = ecKey.getPubKey();
        
        // 3. 计算Keccak-256哈希
        byte[] hash = Sha256Hash.hash(publicKey);
        
        // 4. 取最后20字节作为地址
        byte[] addressBytes = new byte[20];
        System.arraycopy(hash, hash.length - 20, addressBytes, 0, 20);
        
        // 5. 添加前缀0x41
        byte[] addressWithPrefix = new byte[21];
        addressWithPrefix[0] = 0x41;
        System.arraycopy(addressBytes, 0, addressWithPrefix, 1, 20);
        
        // 6. 计算双SHA256哈希作为校验和
        byte[] checkSum = Sha256Hash.hash(Sha256Hash.hash(addressWithPrefix));
        
        // 7. 合并地址和校验和
        byte[] finalAddress = new byte[25];
        System.arraycopy(addressWithPrefix, 0, finalAddress, 0, 21);
        System.arraycopy(checkSum, 0, finalAddress, 21, 4);
        
        // 8. 转换为Base58格式
        return Base58.encode(finalAddress);
    }
}

iOS 实现代码示例 (Swift)

import Foundation
import CryptoSwift
import secp256k1

class TronAddressGenerator {
    
    static func generateTronAddress() -> String {
        // 1. 生成私钥
        var privateKey = [UInt8](repeating: 0, count: 32)
        _ = SecRandomCopyBytes(kSecRandomDefault, privateKey.count, &privateKey)
        
        // 2. 从私钥生成公钥
        guard let ctx = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) else {
            return ""
        }
        
        var pubKey = secp256k1_pubkey()
        guard secp256k1_ec_pubkey_create(ctx, &pubKey, privateKey) == 1 else {
            return ""
        }
        
        var output = [UInt8](repeating: 0, count: 65)
        var outputLen = 65
        secp256k1_ec_pubkey_serialize(ctx, &output, &outputLen, &pubKey, UInt32(SECP256K1_EC_UNCOMPRESSED))
        
        // 3. 取公钥的X和Y部分 (去掉第一个字节0x04)
        let publicKey = Array(output[1...64])
        
        // 4. 计算Keccak-256哈希
        let hash = publicKey.sha3(.keccak256)
        
        // 5. 取最后20字节作为地址
        let addressBytes = Array(hash[hash.count-20..<hash.count])
        
        // 6. 添加前缀0x41
        var addressWithPrefix = Data([0x41])
        addressWithPrefix.append(Data(addressBytes))
        
        // 7. 计算双SHA256哈希作为校验和
        let checkSum = addressWithPrefix.sha256().sha256().prefix(4)
        
        // 8. 合并地址和校验和
        var finalAddress = addressWithPrefix
        finalAddress.append(checkSum)
        
        // 9. 转换为Base58格式
        return finalAddress.base58EncodedString()
    }
}

extension Data {
    func base58EncodedString() -> String {
        // Base58编码实现
        let alphabet = [UInt8]("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".utf8)
        var bytes = [UInt8](self)
        var zerosCount = 0
        while bytes.first == 0 {
            bytes.removeFirst()
            zerosCount += 1
        }
        
        var address = ""
        var value = Data(bytes)
        while !value.isEmpty {
            (value, remainder) = value.divide(by: 58)
            address = String(Character(UnicodeScalar(alphabet[Int(remainder)]))) + address
        }
        
        let zeros = String(repeating: "1", count: zerosCount)
        return zeros + address
    }
    
    func divide(by divisor: UInt8) -> (quotient: Data, remainder: UInt8) {
        // 辅助函数用于Base58计算
        var quotient = Data()
        var remainder: UInt16 = 0
        
        for byte in self {
            let temp = remainder << 8 + UInt16(byte)
            let q = UInt8(temp / UInt16(divisor))
            remainder = temp % UInt16(divisor)
            quotient.append(q)
        }
        
        // 移除前导零
        while !quotient.isEmpty && quotient[0] == 0 {
            quotient.removeFirst()
        }
        
        return (quotient, UInt8(remainder))
    }
}

地址格式说明

TronLink 生成的地址遵循 TRON 标准地址格式:

  • 以大写字母 'T' 开头
  • 长度 34 个字符
  • 包含 Base58 编码的地址数据和校验和

示例地址:TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL

跨平台兼容性

TronLink 的 Android 和 iOS 版本使用相同的加密算法和地址生成规则,确保:

  1. 同一私钥在两平台生成相同地址
  2. 备份的助记词或私钥可在两平台间互通
  3. 交易签名兼容

安全注意事项

  1. 私钥和助记词永远不应明文存储
  2. 地址生成过程应在安全环境中进行
  3. 使用硬件安全模块 (HSM) 或安全元件保护敏感操作

如需了解更多技术细节,请参考我们的开发者文档GitHub仓库