Unable to verify TronLink/TronWeb.js signed message in tron-api
mdn522 opened this issue · 10 comments
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
plugin hasn't been updated for a long time, let's check
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))
thanks, let's check this signature feature
message = tron.trx.sign(tron.toHex(text="test"))
print(
tron.trx.verify_message(tron.toHex(text="test"), message)
)
How to convert tronweb.trx.sign(hexMessage) to UTF format in tronlink wallet
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
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?
Currently, this code does solve the issue for verifying TronWeb generated signature
where does header.encode('utf-8')
come from?
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())