First you need to know that sha256
and keccak256
functions are not the same. Check the docs to see available functions.
sha256
(with pyhton):
>>> sha256("Hello World!").hexdigest()
'7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069'
keccak256
(with web3):
web3.utils.keccak256("Hello World!")
'0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0'
To get the same hash:
contract Hash {
function func() external pure returns (bytes32) {
return keccak256(abi.encodePacked("Hello World!")) ;
}
}
Output:
decoded output
{
"0": "bytes32: 0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0"
}
Choose:
truffle(development)> web3.utils.soliditySha3("Hello World!")
'0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0'
truffle(development)> web3.utils.keccak256("Hello World!")
'0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0'
truffle(development)> web3.utils.sha3("Hello World!")
'0x3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0'
About abi.encodePacked(...)
abi.encodePacked(...) returns (bytes memory)
: Performs packed
encoding of the given arguments. Note that packed encoding can be
ambiguous!
You can test it, but with one argument, the result hash will be the same if you don't use abi.encodePacked(...)
.
EDIT:
From docs:
If you use keccak256(abi.encodePacked(a, b))
and both a
and b
are dynamic types, it is easy to craft collisions in the hash value by
moving parts of a
into b
and vice-versa. More specifically,
abi.encodePacked("a", "bc") == abi.encodePacked("ab", "c")
.
abi.encodePacked(...)
encode dynamic types without length and
static types are not padded if they are shorter than 32 bytes.
abi.encode(...)
ABI-encodes the given arguments
abi.encode("a", "bc")
result:
0x0000000000000000000000000000000000000000000000000000000000000040 // Start offset for the first parameter ("a")
0x0000000000000000000000000000000000000000000000000000000000000080 // Start offset for the second parameter ("bc")
0x0000000000000000000000000000000000000000000000000000000000000001 // Length of the first parameter ("a")
0x6100000000000000000000000000000000000000000000000000000000000000 // Padded to 32 bytes ("a") UTF-8 encoded
0x0000000000000000000000000000000000000000000000000000000000000002 // Length of the second parameter ("bc")
0x6263000000000000000000000000000000000000000000000000000000000000 // Padded to 32 bytes ("bc") UTF-8 encoded
keccak256: 0x68cd083d4c97fcbd081751d5390da5b37f5c485fd0879180d4816c456e8e532c
abi.encode("ab", "c")
result:
0x0000000000000000000000000000000000000000000000000000000000000040 // Start offset for the first parameter ("ab")
0x0000000000000000000000000000000000000000000000000000000000000080 // Start offset for the second parameter ("c")
0x0000000000000000000000000000000000000000000000000000000000000002 // Length of the first parameter ("ab")
0x6162000000000000000000000000000000000000000000000000000000000000 // Padded to 32 bytes ("ab") UTF-8 encoded
0x0000000000000000000000000000000000000000000000000000000000000001 // Length of the second parameter ("c")
0x6300000000000000000000000000000000000000000000000000000000000000 // Padded to 32 bytes ("c") UTF-8 encoded
keccak256: 0x8c98d57214b9f76c3240d1fc677eb9fc1529ec2a4f56949bb6abe31d50b4b7c6
abi.encodePacked("a", "bc")
result:
0x61 // ("a") UTF-8 encoded without padding
0x6263 // ("bc") UTF-8 encoded without padding
keccak256: 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45
abi.encodePacked("ab", "c")
result:
0x6162 // ("ab") UTF-8 encoded without padding
0x63 // ("c") UTF-8 encoded without padding
keccak256: 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45