Reputation: 125
The code block of getting signer address via ecrecover in solidity contract code is working well with Ethereum but in TRON it is returning wrong address My contract side code is
function validate(string memory strTest,uint8 v, bytes32 r, bytes32 s) public view returns(address){
bytes32 prefixedHash = keccak256(strTest);
return ecrecover(keccak256(prefixedHash),v,r,s);
// return ecrecover(prefixedHash,v,r,s):
}
and dapp side code is
msg = tronWeb.sha3("this is test string");
var signature = await tronWeb.trx.sign(msg);
var r=signature.substr(0,66);
var s= "0x" + signature.substr(66,64);
var v="0x" + signature.substr(signature.length-2);
retValue = await thisContractInstance.validate("this is test string",v,r,s).call();
but in both cases ( one case is commented in contract side code) getting wrong signer address in TRON shasta network
Upvotes: 1
Views: 2457
Reputation: 43
According to https://github.com/tronprotocol/tronweb/blob/1435436f83b910f19e9205998e348ea093732ce5/src/lib/trx.js#L629
tronWeb.trx.sign()
does the following
keccak256
algorithmTherefore, when using solidity's ecrecover
, the hash of step 3 is passed in.
function getHash(hash) {
hash = hash.replace(/^0x/, '')
if (!tronWeb.utils.isHex(hash)) {
return
}
if (hash.length !== 64) {
return
}
const {
keccak256,
toUtf8Bytes
} = tronWeb.utils.ethersUtils
const hashArray = tronWeb.utils.code.hexStr2byteArray(hash)
const TRX_MESSAGE_PREFIX = toUtf8Bytes('\x19TRON Signed Message:\n32')
return keccak256([
...TRX_MESSAGE_PREFIX,
...hashArray
])
}
Upvotes: 0
Reputation: 11991
Taken from here:
The smart contract code:
contract Verifier {
function recoverAddr(bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) returns (address) {
return ecrecover(msgHash, v, r, s);
}
function isSigned(address _addr, bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) returns (bool) {
return ecrecover(msgHash, v, r, s) == _addr;
}
}
The client code:
const ethers = tronWeb.utils.ethersUtils;
let contract = await tronWeb.contract().at(contract_address);
let signingKey = new ethers.SigningKey(tronWeb.defaultPrivateKey);
let message = "This is some message";
let messageBytes = ethers.toUtf8Bytes(message);
let messageDigest = ethers.keccak256(messageBytes);
let signature = signingKey.signDigest(messageDigest);
let hexAddress = await contract.recoverAddr(messageDigest, signature.v, signature.r, signature.s).call();
Upvotes: 0
Reputation: 116
You could refer the article https://medium.com/@coredevs/verifying-elliptic-curve-digital-signature-with-tron-smart-contract-5d11347e7b5b. This will be useful to accomplish signing the strings, along with the above answer provided by @Aldo. Happy coding.
Upvotes: 1
Reputation: 168
Are you trying to sign a string or sign transaction? @ashwin
I had the same kind of issues signing a string, and the below helped me out. Tronweb uses different methods for signing transactions and signing strings.
1) For transactions you can refer this: https://github.com/TRON-US/tronweb/blob/master/src/lib/trx.js#L651,
2) Regarding signing string, it uses
ethers.utils.SigningKey.signDigest ()
of Ethereum: https://docs.ethers.io/ethers.js/html/api-advanced.html?highlight=signingkey#id8, note that the final v byte will always be nomalized for Solidity (either 27 or 28)
If you are trying to sign the msg as mentioned here,
var signature = await tronWeb.trx.sign(msg);
you can follow the second.
Upvotes: 1