iexbase / tron-api-python

A Python API for interacting with Tron (TRX)
https://tronapi-for-python.readthedocs.io
MIT License
166 stars 84 forks source link

Unable to verify TronLink/TronWeb.js signed message in tron-api #77

Open mdn522 opened 4 years ago

mdn522 commented 4 years ago

Javascript Code for Signing Message:

const original_message = "557e3517549cf8ed47d8b205654ea2a7"
const signedtxn = await tronWeb.trx.sign(original_message);
// result 0x862e16c28684bed7162e9a1dd34962882d887610de6c775054ffbad989baec65707b2ba898366c02e9f20730bc2daf54bb7e6d33d77c64f8930f8c9365f5993a1b

Python Code for Verifying Signed Message

from tronapi import Tron
from hexbytes import HexBytes

tron = Tron()

class signed_message:
     # signedtxn variable in javascript
    signature = HexBytes('0x862e16c28684bed7162e9a1dd34962882d887610de6c775054ffbad989baec65707b2ba898366c02e9f20730bc2daf54bb7e6d33d77c64f8930f8c9365f5993a1b')

original_message = "557e3517549cf8ed47d8b205654ea2a7"
address = "<!-- Tron Base58 Address in TronLink/TronWeb -->"
tron.trx.verify_message(original_message, signed_message, address=address)

I am getting this error ValueError: Signature does not match

serderovsh commented 4 years ago

plugin hasn't been updated for a long time, let's check

mdn522 commented 4 years ago

Currently, this code does solve the issue for verifying TronWeb generated signature

from eth_hash.auto import keccak as keccak_256
# message length is 32 chars and message is a hex string without 0x prefix
# eg message = "557e3517549cf8ed47d8b205654ea2a7"
message_hash = keccak_256(header.encode('utf-8') + bytes.fromhex(message))
serderovsh commented 3 years ago

thanks, let's check this signature feature

serderovsh commented 3 years ago
message = tron.trx.sign(tron.toHex(text="test"))

print(
    tron.trx.verify_message(tron.toHex(text="test"), message)
)
manish8561 commented 3 years ago

How to convert tronweb.trx.sign(hexMessage) to UTF format in tronlink wallet

blackcatpolice commented 2 years ago

Here is the document code: https://cn.developers.tron.network/reference/verifymessage ` // sign a string message

var str = "helloworld"; // convert to hex format and remove the beginning "0x" var hexStrWithout0x = tronWeb.toHex(str).replace(/^0x/, ''); // conert hex string to byte array var byteArray = tronWeb.utils.code.hexStr2byteArray(hexStrWithout0x) // keccak256 computing, then remove "0x" var strHash= tronWeb.sha3(byteArray).replace(/^0x/, ''); // sign var signedStr = await tronWeb.trx.sign(strHash); var tail = signedStr.substring(128, 130); if(tail == '01') { signedStr = signedStr.substring(0,128)+'1c'; } else if(tail == '00') { signedStr = signedStr.substring(0,128)+'1b'; }

// verify the signature var res = await tronWeb.trx.verifyMessage(strHash,signedStr,'TPNcZ1j55FrGpsaw6K6rVjuL4HfT8ZbBf7') console.log(res); true `

so , JS verifyMsg : txid = tron.toHex(text="test").replace(/^0x/,'') signedMsg = tron.trx.sign(tron.toHex(text="test"))

Java verifyMsg: You can find class: SignatureValidator

it is same as tron.trx.sign

mvshvets commented 2 years ago

Do I understand correctly, this library is not suitable for me to verify the signature if the signature is done on the frontend via tronweb?

mvshvets commented 2 years ago

@mdn522

Currently, this code does solve the issue for verifying TronWeb generated signature

where does header.encode('utf-8') come from?

mvshvets commented 2 years ago

For those who will come here. TronLink expects a fixed message length of 32.

To comply with compatibility, you can use something like this:

from tronapi.common.account import Account, Address
from tronapi.trx import TRX_MESSAGE_HEADER
from trx_utils import to_text, to_hex
from tronapi import Tron

TronClient = Tron()
message_hash = TronClient.keccak(text=TRX_MESSAGE_HEADER + '32' + to_text(hexstr=body.nonce))
recovered = Account.recover_hash(to_hex(message_hash), body.sign)
print(address == Address.from_hex('41' + recovered[2:]).decode())
mdn522 commented 2 years ago

@mdn522

Currently, this code does solve the issue for verifying TronWeb generated signature

where does header.encode('utf-8') come from?

Unfortunately, The HDD where this testing code was stored has failed. But I guess it should be Tron or Ethereum header