You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
tip: 712
title: TRON typed structured data hashing and signing
author: yanghang8612@163.com
discussions to: https://github.com/tronprotocol/TIPs/issues/443
status: Draft
type: Standards Track
category: Interface
created: 2022-07-25
Abstract
This TIP introduces a standard for hashing and signing of typed structured data as opposed to just bytestrings into TRON protocol to solve the problem that hashing structured data is non-trivial and errors result in loss of the security properties of the system, etc.
The encoding function, hashing algorithm and signing algorithm is identical to EIP-712. There are some differences in details. It includes a
address: need to remove TRON unique prefixe(0x41) and encoded as uint160
trcToken: should be treated as atomic type and encoded as uint256
chainId: use block.chainid & 0xffffffff instead
Motivation
This TIP aims to improve the usability of off-chain message signing for use on-chain. We are seeing growing adoption of off-chain message signing as it saves transaction fees and reduces the number of transactions on the blockchain. Currently signed messages are an opaque hex string displayed to the user with little context about the items that make up the message.
A signature scheme consists of hashing algorithm and a signing algorithm. A good hashing algorithm should satisfy security properties such as determinism, second pre-image resistance and collision resistance. Otherwise, it may cause security problems or replay problems, etc. This standard aims to solve these problems.
Specifications
For the structured data 𝕊, they are encoded to bytestrings suitable for hashing and signing as follows:
encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message) where domainSeparator and hashStruct(message) are defined below.
The encoding is compliant with TIP-191 and it`s totaly compatible with EIP-712. The 'version byte' is fixed to 0x01, the version specific data is the 32-byte domain separator domainSeparator and the data to sign is the 32-byte hashStruct(message).
Definition of typed structured data 𝕊
Definitions for all types are identical to EIP-712.
For example, the above AssetTransfer struct is encoded as AssetTransfer(address from,address to,trcToken id,uint256 amount,uint8 v,bytes32 r,bytes32 s).
Definition of encodeData
The encoding of a struct instance is enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ), i.e. the concatenation of the encoded member values in the order that they appear in the type. Each encoded member value is exactly 32-byte long.
It's totaly compatible with EIP-712.
The only difference between TRON address and Ethereum address is that TRON address starts with a byte prefix 0x41 and uses base58 encoding, so prefix needs to be removed when the address type is processed.
Definition of domainSeparator
domainSeparator = hashStruct(tip712Domain)
where the type of tip712Domain is identical to EIP712Domain struct defined in EIP-712. It also contains one or more of the below fields.
string name the user readable name of signing domain.
string version the current major version of the signing domain. Signatures from different versions are not compatible.
uint256 chainId the chain id. The user-agent should refuse signing if it does not match the currently active chain.
address verifyingContract the address of the contract that will verify the signature. The user-agent may do contract specific phishing prevention.
bytes32 salt an disambiguating salt for the protocol. This can be used as a domain separator of last resort.
The only difference is that we define the chainId data used in the domainSeparator to be equal to block.chainid & 0xffffffff. In other words, the chainId data used in the domainSeparator only take the higher four bytes of block.chainId.
The formula for calculating the chainid in domainSeparator is as follows:
The FullNode gRPC calls and SomeStruct.typeHash parameter are currently undefined. Defining them should not affect the behaviour of existing DApps.
The Solidity expression keccak256(someInstance) for an instance someInstance of a struct type SomeStruct is valid syntax. It currently evaluates to the keccak256 hash of the memory address of the instance. This behaviour should be considered dangerous. In some scenarios it will appear to work correctly but in others it will fail determinism and/or injectiveness. DApps that depend on the current behaviour should be considered dangerously broken.
The text was updated successfully, but these errors were encountered:
yanghang8612
changed the title
TIP-712: Tron typed structured data hashing and signing
TIP-712: TRON typed structured data hashing and signing
Jul 25, 2022
Close this issue as there has been no new discussion for more than 6 months.
The community has decided to adopt this issue.
Check TIP detail at TIP-712.
Abstract
This TIP introduces a standard for hashing and signing of typed structured data as opposed to just bytestrings into TRON protocol to solve the problem that hashing structured data is non-trivial and errors result in loss of the security properties of the system, etc.
The encoding function, hashing algorithm and signing algorithm is identical to EIP-712. There are some differences in details. It includes a
address
: need to remove TRON unique prefixe(0x41
) and encoded asuint160
trcToken
: should be treated as atomic type and encoded asuint256
chainId
: useblock.chainid & 0xffffffff
insteadMotivation
This TIP aims to improve the usability of off-chain message signing for use on-chain. We are seeing growing adoption of off-chain message signing as it saves transaction fees and reduces the number of transactions on the blockchain. Currently signed messages are an opaque hex string displayed to the user with little context about the items that make up the message.
A signature scheme consists of hashing algorithm and a signing algorithm. A good hashing algorithm should satisfy security properties such as determinism, second pre-image resistance and collision resistance. Otherwise, it may cause security problems or replay problems, etc. This standard aims to solve these problems.
Specifications
For the structured data 𝕊, they are encoded to bytestrings suitable for hashing and signing as follows:
encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)
wheredomainSeparator
andhashStruct(message)
are defined below.The encoding is compliant with TIP-191 and it`s totaly compatible with
EIP-712
. The 'version byte' is fixed to0x01
, theversion specific data
is the 32-byte domain separatordomainSeparator
and thedata to sign
is the 32-bytehashStruct(message)
.Definition of typed structured data
𝕊
Definitions for all types are identical to
EIP-712
.Definition of
hashStruct
The
hashStruct
function is defined ashashStruct(s : 𝕊) = keccak256(typeHash ‖ encodeData(s))
wheretypeHash = keccak256(encodeType(typeOf(s)))
It's totaly compatible with
EIP-712
.Definition of
encodeType
The type of a struct is encoded as
name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"
where each member is written astype ‖ " " ‖ name
.It's totaly compatible with
EIP-712
.For
trcToken
, it should be treated as atomic type.For example, the above
AssetTransfer
struct is encoded asAssetTransfer(address from,address to,trcToken id,uint256 amount,uint8 v,bytes32 r,bytes32 s)
.Definition of
encodeData
The encoding of a struct instance is
enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)
, i.e. the concatenation of the encoded member values in the order that they appear in the type. Each encoded member value is exactly 32-byte long.It's totaly compatible with
EIP-712
.The only difference between TRON address and Ethereum address is that TRON address starts with a byte prefix
0x41
and usesbase58
encoding, so prefix needs to be removed when the address type is processed.Definition of
domainSeparator
where the type of
tip712Domain
is identical toEIP712Domain
struct defined inEIP-712
. It also contains one or more of the below fields.string name
the user readable name of signing domain.string version
the current major version of the signing domain. Signatures from different versions are not compatible.uint256 chainId
the chain id. The user-agent should refuse signing if it does not match the currently active chain.address verifyingContract
the address of the contract that will verify the signature. The user-agent may do contract specific phishing prevention.bytes32 salt
an disambiguating salt for the protocol. This can be used as a domain separator of last resort.The only difference is that we define the
chainId
data used in thedomainSeparator
to be equal toblock.chainid & 0xffffffff
. In other words, thechainId
data used in thedomainSeparator
only take the higher four bytes ofblock.chainId
.The formula for calculating the
chainid
indomainSeparator
is as follows:Mainnet TIP-712
chainId
In HEX:
0x000000000000000000000000000000000000000000000000000000002b6653dc
In Decimal:
728126428
Example Contract
Nile Testnet TIP-712
chainId
In HEX:
0x00000000000000000000000000000000000000000000000000000000cd8690dc
In Decimal:
3448148188
Example Contract
Backwards Compatibility
The FullNode gRPC calls and
SomeStruct.typeHash
parameter are currently undefined. Defining them should not affect the behaviour of existing DApps.The Solidity expression
keccak256(someInstance)
for an instancesomeInstance
of a struct typeSomeStruct
is valid syntax. It currently evaluates to thekeccak256
hash of the memory address of the instance. This behaviour should be considered dangerous. In some scenarios it will appear to work correctly but in others it will fail determinism and/or injectiveness. DApps that depend on the current behaviour should be considered dangerously broken.The text was updated successfully, but these errors were encountered: