- Published on
Keccak Abi encodePacked with JavaScript
- Authors
- Name
- Yair Mark
- @yairmark
One thing that can be quite confusing when working with Ethereum is that keccak is often used interchangeably with sha3. In the Ethereum space they do appear to be the same thing. Where it can get confusing is when you are using a library on the JavaScript side to try generate them (for testing or in your dApp).
To illustrate this lets say we have a person contract that has a function that simply returns the keccak256 hash of a hardcoded value as below:
pragma solidity ^0.4.24;
contract Person {
struct PersonDetails{
string name;
string surname;
uint256 age;
address someRandomAddress;
}
PersonDetails private john = PersonDetails({
name: "John",
surname: "Smith",
age: 33,
someRandomAddress: 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d
});
function personHash() external view returns (bytes32) {
return keccak256(
abi.encodePacked(
john.name,
john.surname,
john.age,
john.someRandomAddress
)
);
}
}
How do you generate a keccak like this in JavaScript/Web3?
This stumped me for a while but after a bit of digging I worked out how. I wrote a simple truffle test to demonstrate:
const Person = artifacts.require('Person')
const { soliditySha3 } = require('web3-utils')
contract('Person', ([admin]) => {
let personContract
beforeEach(async () => {
personContract = await Person.new()
})
describe('personHash', () => {
it('should hash the inputs using keccack256', async () => {
const personHash = await personContract.personHash.call()
const soliditySha3Expected = soliditySha3(
'John',
'Smith',
33,
'0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'
)
expect(personHash).to.equal(soliditySha3Expected)
})
})
})
If you run this test you will see that it passes without issue. Some things to note about the above setup:
web3-utils
: you will need tonpm install web3-utils --save
to use this.- Ordering of Parameters: In a hashing function the order is very important and will result in a different hash if changed.
- Random Address: I threw in the cryptokitties address just to illustrate how it works if you have that in your struct.
- soliditySha3 parameter type inference: Based on the documentation you do not need to specify the types for the parameters you use - the util infers the types.
- These rules are detailed here.
soliditySha3
: as I mentioned in the beggining of this post sha3 is the same as keccak in the Ethereum world- The JavaScript util for this also seems
abi.encodePacked
for you on the JavaScript side.
- The JavaScript util for this also seems