Account Model¶
Introduction¶
TRON employs an account model for its ledger. All activities on the network, such as transfers, voting, and contract deployment, revolve around accounts.
- Unique Identifier: Each account is uniquely identified by its Address, which typically begins with a
T
. - Access Control: Any operation on an account (such as a transfer) requires a signature from the corresponding Private Key.
-
Account Assets and Capabilities: Each account can own and manage various resources, including:
- Assets: TRX, TRC-10, TRC-20, TRC-721/TRC-1155 NFTs, etc.
- Network Resources: Bandwidth and Energy.
- Permissions and Activities: Initiating transactions, deploying and calling smart contracts, participating in Super Representative elections (voting or becoming a candidate), and more.
How to Create an Account¶
There are two primary ways to create a new TRON account:
Method 1: Offline Generation and On-Chain Activation
- Generate Address: Use a wallet application (like TronLink) to generate a new key pair (private key and address).
- Activate Account: At this stage, the account exists only conceptually and must be "activated" to be used on the blockchain. Activation is accomplished by sending any amount of TRX or a TRC-10 token from an existing account to this new address. Once the transaction is successful, the new account is officially created on the TRON network.
Method 2: Creation via System Contract
- Developers can create an account by calling the
CreateAccount
system contract.
Account Creation Cost:
- A fixed fee of 1 TRX is required to create and activate a new account.
- Additionally, if the creator's account has sufficient bandwidth (either from staking TRX or delegated from others), the creation will only consume bandwidth. Otherwise, 0.1 TRX will be burned to pay for the bandwidth fee.
Key Pair Generation Algorithm¶
TRON's signature algorithm is ECDSA, and the selected curve is SECP256K1. Its private key is a random number, and the public key is a point on the elliptic curve. The generation process is as follows: first, generate a random number d
as the private key, then calculate P = d × G
as the public key, where G
is the base point of the elliptic curve, and the base point is public.
The private key is a 32-byte large number, and the public key consists of two 32-byte large numbers, which are the abscissa and ordinate of the above-mentioned P
point respectively.
TRON Address Generation¶
- Take the public key P as input, calculate SHA3 to get the result H, and SHA3 uses Keccak256.
- Take the last 20 bytes of H, and prepend a byte 0x41 to get address.
- Perform base58check calculation on address to get the final address.
Base58Check Calculation Process¶
-
Calculate the checksum
a. Perform SHA256 hash operation on
address
to geth1
b. Perform SHA256 operation onh1
again to geth2
c. Take the first 4 bytes ofh2
as the checksumcheck
-
Splice data Append
check
toaddress
to getaddress||check
- Base58 encoding Perform Base58 encoding on
address||check
. The character table for Base58 is:"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
, excluding easily confused characters:0
(Arabic numeral 0),O
(uppercase letter O),I
(uppercase letter I),l
(lowercase letter L).
TRON Address Characteristics¶
The principle of Base58 encoding is to convert a large integer with a base of 256 into a representation with a base of 58, and then map it to the character table. Since the first byte of address||check
is fixed as 0x41
, its decimal value N
satisfies: 65 × 256²⁴ ≤ N < 66 × 256²⁴
.
- Length is
34
: Because58³⁴ > 66 × 256²⁴
indicates that length of34
are sufficient, and58³³ < 65 × 256²⁴
indicates that length of33
are insufficient, so the length can only be34
. - The first character is
T
: First, the length is determined to be34
, and since27 × 58³³ > 66 × 256²⁴
indicates that the index of first character in base58 character table must be less than27
, and26 × 58³³ < 65 × 256²⁴
indicates that the index must be greater than or equal to26
, so the first index can only be26
, and26
corresponds toT
in the base58 character table (0
corresponds to1
).
Signature Specification¶
Algorithm¶
- Take the rawdata of the transaction, convert it to byte[] format, and record it as
data
. (For example, thebyte[]
type in Java.). - Perform
sha256
operation ondata
to get the hash value of the transaction, recorded ashash
. -
Use the private key d corresponding to the address in the transaction contract to sign hash. The signature algorithm is the ECDSA algorithm (using the SECP256K1 curve). The signature result includes three values:
r
,s
, andv
:- Calculate the
r
value: randomly generate a temporary private keyk
, calculate the temporary public keyK = k × G
(G: curve base point),r = K_x mod n
, that is, the abscissa ofK
modulon
, wheren
is the curve order (n and G satisfyn × G = O
, and O is the zero point of the elliptic curve group on the finite field).r
is 32 bytes. - Calculate the
s
value: first calculate the modular inverse of the temporary private keyk
with respect to n,k⁻¹
, that is,k⁻¹
satisfiesk⁻¹ × k = 1 mod n
, then calculate thes
value through the transaction'shash
, the user's private keyd
, and ther
value,s = (k⁻¹ × (hash + d × r)) mod n
.s
is 32 bytes. - Calculate the
v
value: thev
value is the recovery identifier. Due tor
value undergoes a modulo operation and the symmetry of the elliptic curve, if there is only ther
value, oner
can recover up to fourK
s. The value range ofv
is four integers: 0, 1, 2, 3. Historically, to be consistent with Ethereum, the finalv
value will be 27 added to 0, 1, 2, 3, that is, the final value range ofv
is 27, 28, 29, 30. With a determinedv
, the uniqueK
can be recovered.v
is 1 byte.
- Calculate the
-
Append the concatenated signature results
r
,s
,v
to the transaction, in the orderv || r || s
.
Java Code Sample¶
public static Transaction sign(Transaction transaction, ECKey myKey) {
Transaction.Builder transactionBuilderSigned = transaction.toBuilder();
byte[] hash = sha256(transaction.getRawData().toByteArray());
ECDSASignature signature = myKey.sign(hash);
ByteString bsSign = ByteString.copyFrom(signature.toByteArray());
transactionBuilderSigned.addSignature(bsSign);
}
Signature Verification¶
When a Fullnode receives a transaction, it uses the transaction hash and signature to recover a public key via the ECDSA recovery mechanism (ecrecover). An address is then derived from this public key. If the derived address matches the originator's address specified in the transaction, the signature is considered valid.
Algorithm¶
- Recover the public key point
K
: The temporary public key pointK
can be uniquely recovered throughv
andr
in the signature. -
Derive the public key
P
: -
Known signature equation:
s = k⁻¹(hash + d × r) mod n
- Multiply both sides by
k
:s × k = (hash + d × r) mod n
- Multiply both sides by the base point
G
of the curve (usingK = k × G
andP = d × G
):s × K = hash × G + r × P
-
Since
s
,K
,hash
,G
, andr
are all known,P
can be obtained. -
Generate TRON address: same as TRON Address Generation
- Address verification: compare whether the generated TRON address is consistent with the address in the transaction contract.
Example¶
Signature verification is performed by the Fullnode. For ECDSA algorithm signature verification, you can refer to java-tron, and the core function is signatureToAddress
.
Signature normalization¶
ECDSA
signatures (using the secp256k1
curve) are malleable, meaning that for a signature (r, s), where r, s \in [1, n-1], the pair (r, n - s) is also a valid signature. Since signatures affect transaction id in both Bitcoin and Ethereum, BIP-62 and EIP-2 require signatures to be normalized, i.e., s \leq n/2. However, for the TRON network, the transaction id does not include signature information, so there is no strict requirement for signature normalization, and signature verification does not need to check whether the signature is normalized. Although there is no strict restriction, both java-tron
and wallet-cli
currently perform signature normalization.