Ethers.js: Add a method to generate tightly packed encodings

Created on 22 Nov 2017  路  12Comments  路  Source: ethers-io/ethers.js

Is there a way to replicate the non-standard pack mode used by Solidity in Ethers.js?

My use case is I want to sign an EtherDelta order. This is later validated in the trade function with the following code

bytes32 hash = sha256(tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
if (!(ecrecover(hash,v,r,s) == user ...

So in JavaScript I want to be able to get the non-standard pack mode of the parameters tokenGet, amountGet, tokenGive, amountGive, expires and nonce which can then be passed into a sha256 function. Is that possible?

enhancement

Most helpful comment

Added in https://github.com/ethers-io/ethers.js/commit/8129f0cb8b932662561d8aa799e4963f44d90c75.

ethers.utils.soliditySha256(types, values)
ethers.utils.solidityKeccak256(types, values)

Both types and values should be arrays of the values you wish to work with.

Give it a try and let me know if you have any issues. There are ~2000 test cases for it procedurally generated in the make-contract-events.js file if curious about coverage.

All 12 comments

I'd read that little snippet of documentation before, and thought it would be nice to add, but can you find any additional information?

A few questions:

  • What does "short type" mean? How short is short? And from the single example, it appears to be more about short values than short types
  • How does twos-compliment work on negative numbers? Does sign extension go to the width of the type?
  • How is 0x2424 a valid uint8?

If you can find documentation though, I'd love to add it.

Here is another short example. Still not enough to implement the encoding by though.

I will bug Christian...

I tried to work out some of the types with trial and error but I didn't get very far.

I poked Christian and there are now a few more details on the site. I will use the events test case generator to generate a large suite of test cases for tightly packed data and give this a stab today/tomorrow.

Added in https://github.com/ethers-io/ethers.js/commit/8129f0cb8b932662561d8aa799e4963f44d90c75.

ethers.utils.soliditySha256(types, values)
ethers.utils.solidityKeccak256(types, values)

Both types and values should be arrays of the values you wish to work with.

Give it a try and let me know if you have any issues. There are ~2000 test cases for it procedurally generated in the make-contract-events.js file if curious about coverage.

You are a legend @ricmoo. I've tried a few types and it matches solidity.

Thanks for the super fast turn around.

@ricmoo Is there any chance you could add an encoding method that directly resolves like abi.encodedPacked does in solidity? Packed encoding can be useful.

@PhABC I think what you are looking for is ethers.utils.solidityPack? It does not support structs though. Do you need struct support?

Struck support would be nice, but I can work around not having struct support in the meantime. Thanks for the pointer!

Struct support, like with defaultAbiCoder.encode() and tuples, would make our code a little cleaner and simple :).

@ricmoo I'm going to go back on my words and say that supporting struct for solidityPack would make my life much easier. How difficult would it be to add this feature? Might be worth opening another issue.

I will have to look into it. There is zero documentation on how packed encoding works (well, epsilon, but half of that documentation is wrong), so it was a collection of a large number of test cases, reverse engineering and reading the source code.

I鈥檒l have to see if there is a concise way to try incorporating structs into some demo data. Maybe next week?

Thank you Richard, I appreciate it. Faced the same challenges when trying it on my end as well.

Chris pointed me to a PR where they updated the documentation on encodedPacked. Still pending review but it has a bit more info : https://github.com/ethereum/solidity/blob/7908764da2b2f6d237548a60be4c649f85f52994/docs/abi-spec.rst

Was this page helpful?
0 / 5 - 0 ratings