-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
eth/abi: implement encode_packed/decode_packed #103
Comments
I also tried with simple strings and I get the same result |
@tomiwaAdey Hi, I used Result of encode in eth.rbreturns [2] pry(main)> token_ids = [1,2,3]
=> [1, 2, 3]
[23] pry(main)> Eth::Util.bin_to_prefixed_hex(Eth::Util.keccak256(Eth::Abi.encode(['uint256[]'], [token_ids])))
=> "0x62e243217b24f0adeab63b697d9c38d64bd4cbf540c9915772ddc377b45b411c" Try it on Smart Contract with Remix (use abi.encodePacked() )returns Code// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.9;
import "./ECDSA.sol";
contract VerifySignature {
using ECDSA for bytes32;
function getMessageHash(uint256[] memory ids) public pure returns (bytes32) {
return keccak256(abi.encodePacked(ids));
}
function verify(bytes memory sig, uint256[] memory ids) external pure returns (bool) {
bytes32 messagehash = keccak256(
abi.encodePacked(ids)
);
return messagehash.toEthSignedMessageHash().recover(sig) == 0x2ceBaa61f571C38d41cFFc8605FB3C1ac4d7F6e7;
}
function getSigner(bytes memory sig, uint256[] memory ids) external pure returns (address) {
bytes32 messagehash = getMessageHash(ids);
return messagehash.toEthSignedMessageHash().recover(sig);
}
} Capture when executedTry it on Smart Contract with Remix (use abi.encode() )returns Code// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.9;
import "./ECDSA.sol";
contract VerifySignature {
using ECDSA for bytes32;
function getMessageHash(uint256[] memory ids) public pure returns (bytes32) {
return keccak256(abi.encode(ids));
}
function verify(bytes memory sig, uint256[] memory ids) external pure returns (bool) {
bytes32 messagehash = keccak256(
abi.encode(ids)
);
return messagehash.toEthSignedMessageHash().recover(sig) == 0x2ceBaa61f571C38d41cFFc8605FB3C1ac4d7F6e7;
}
function getSigner(bytes memory sig, uint256[] memory ids) external pure returns (address) {
bytes32 messagehash = getMessageHash(ids);
return messagehash.toEthSignedMessageHash().recover(sig);
}
} Capture when executed |
@kurotaky I appreciate you taking the time to look into this. I have since dug deeper into it and encoding in solidity works the same as encoding here. The only problem when it comes to signing the message hash with eth.rb and verifying using Openzeplin's ECDSA is that OZ uses encodePacked and I'm not exactly sure exactly why they are using encodePacked instead of encode. These are the options I'm considering:
I was leaning more towards option 3 but I'm a bit worried as to why OZ uses encodePacked considering their code has been audited multiple times. |
Unfortunately, no luck with option 2 either. The implementation in JS using ethers:
The sig return is verifiable with OZ ECDSA. I've tried to send the messageHash to ruby.eth so I just sign the hash, but even that produces the wrong signature.
|
@tomiwaAdey |
Hey @kurotaky :) I ended up using etherjs for signing just because I have a deadline coming up about a week from today. EncodePacked
Another path is to verify the signature manually instead of using OZ ECDSA (the lib relies heavily on encodePacked). I implemented it like this:
In terms of generating the signature But this is a common pattern generally with writing dapps, sign a message offchain and verify onchain. We should make it as seamless as possible for developers to keep to the ruby ethos. |
Right, we might need encode_packed then. |
Do you mind pointing me toward the specification of this? Edit: Apparently, it's in the solidity docs: https://docs.soliditylang.org/en/v0.8.17/abi-spec.html?highlight=encodepacked#non-standard-packed-mode |
Given: I sign a message with a private key generated using eth.rb
Then: I get a signature
Expected: The signer of the message to be the signer verified on the smart contract
Smart contract
getSigner
returns a different address from the new_wallet.address
@q9f @kurotaky
Is there a difference between how encodePacked in solidity works and encode in eth.rb?
Using v'0.5.3'
The text was updated successfully, but these errors were encountered: