base on TRX documents and some search in GitHub I tried to generate wallet offline and I can't use API for some reasons.
- Generate a key pair and extract the public key (a 64-byte byte array representing its x,y coordinates).
- Hash the public key using sha3-256 function and extract the last 20 bytes of the result.
- Add 0x41 to the beginning of the byte array. The length of the initial address should be 21 bytes.
- Hash the address twice using sha256 function and take the first 4 bytes as verification code.
- Add the verification code to the end of the initial address and get an address in base58check format through base58 encoding.
- An encoded Mainnet address begins with T and is 34 bytes in length.
Please note: the sha3 protocol adopted is KECCAK-256.
I find mattvb91/tron-trx-php
in GitHub and this repository there is a wallet generator method /src/Wallet.php
but the generated key validation return an Error Exception and validation get failed.
I try to recode mattvb91/tron-trx-php
Wallet generator method and create my wallet generator
class walletGenerator
{
private $addressPrefix = "41";
private $addressPrefixByte = 0x41;
private $addressSize = 34;
public function __construct()
{
}
public function generateWallet()
{
$key = new Key();
$odd = false;
while (!$odd)
{
$keyPair = $key->GenerateKeypair();
if(strlen($keyPair['public_key']) % 2 == 0) $odd = true;
}
$privateKeyHex = $keyPair['private_key_hex'];
$pubKeyHex = $keyPair['public_key'];
$pubKeyBin = hex2bin($pubKeyHex);
$addressHex = $this->getAddressHex($pubKeyBin);
$addressBin = hex2bin($addressHex);
$addressBase58 = $this->getBase58CheckAddress($addressBin);
$validAddress = $this->validateAddress($addressBase58);
}
private function getAddressHex($pubKeyBin)
{
if (strlen($pubKeyBin) == 65) {
$pubKeyBin = substr($pubKeyBin, 1);
}
$hash = Keccak::hash($pubKeyBin , 256);
$hash = substr($hash, 24);
return $this->addressPrefix . $hash;
}
private function getBase58CheckAddress($addressBin){
$hash0 = Hash::SHA256($addressBin);
$hash1 = Hash::SHA256($hash0);
$checksum = substr($hash1, 0, 4);
$checksum = $addressBin . $checksum;
$result = Base58::encode(Crypto::bin2bc($checksum));
return $result;
}
private function validateAddress($walletAddress){
if(strlen($walletAddress) !== $this->addressSize) return false;
$address = Base58Check::decode($walletAddress , false , 0 , false);
$utf8 = hex2bin($address);
if(strlen($utf8) !== 25) return false;
if(strpos($utf8 , $this->addressPrefixByte) !== 0) return false; // strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior
$checkSum = substr($utf8, 21);
$address = substr($utf8, 0, 21);
$hash0 = Hash::SHA256($address);
$hash1 = Hash::SHA256($hash0);
$checkSum1 = substr($hash1, 0, 4);
if ($checkSum === $checkSum1) {
return true;
}
}
validateAddress
method has an Error Exceptionif(strpos($utf8 , $this->addressPrefixByte) !== 0) return false; // strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior
I used ionux/phactor
to generating keyPair and iexbase/tron-api
Support classes for Hash and ...
I can debug and solved the problem and share the solutions with you
if(strpos($utf8 , $this->addressPrefixByte) !== 0) return false; // strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior
this problem because of PHP 7.3 bugs and fix with PHP 7.2 ( Exception: stripos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior #770 )
in the Key Pair array, I remove 0x
from first of Private Key Hex and I can access to the wallet in Tron Link Extention don't remember to have a transition for wallet activation