Hashing Examples

Here are some examples of evidence hashing and validation using archon. To see the full specification of Evidence and MetaEvidence see ERC 1497.

Note

All insignificant whitespace should be removed from JSON files before hashing. You can use JSON.stringify to remove whitespace.


Hash and Validate Hosted Evidence

In this example we will use an example evidence file hosted here: https://s3.us-east-2.amazonaws.com/kleros-examples/exampleEvidence.txt

var Archon = require('@kleros/archon');
var fs = require('fs');
var path = require('path');

// Bring in our evidence file downloaded from the link above to obtain the hash
var file = fs.readFileSync(path.resolve(__dirname, "./exampleEvidence.txt")).toString();

// Hash the file using keccak-256
var evidenceHash = Archon.utils.multihashFile(
  file,
  0x1B // keccak-256
);

console.log(evidenceHash); // Bce1WTQa7bfrJMFdEJuWV2xHsmj5JcDDyqBKGXu6PHZsn5e5oxkJ8cMJcuFDK1VsQYBtfrzgWkKCovWSvsacgN1XTj

// Validate the hosted file against the hash we just produced.
Archon.utils.validateFileFromURI(
  'https://s3.us-east-2.amazonaws.com/kleros-examples/exampleEvidence.txt',
  { hash: evidenceHash }
).then(data => {
  console.log(data.isValid); // true
})

Hash and Validate Local Evidence

In this example we will use an example evidence file hosted here: https://s3.us-east-2.amazonaws.com/kleros-examples/exampleEvidence.txt

var Archon = require('@kleros/archon');
var fs = require('fs');
var path = require('path');

// Bring in our evidence file downloaded from the link above to obtain the hash
var file = fs.readFileSync(path.resolve(__dirname, "./exampleEvidence.txt")).toString();

// Hash the file using keccak-256
var evidenceHash = Archon.utils.multihashFile(
  file,
  0x1B // keccak-256
);

console.log(evidenceHash); // Bce1WTQa7bfrJMFdEJuWV2xHsmj5JcDDyqBKGXu6PHZsn5e5oxkJ8cMJcuFDK1VsQYBtfrzgWkKCovWSvsacgN1XTj

// Validate the original file against the hash we just produced.
console.log(Archon.utils.validMultihash(
  evidenceHash
  file,
); // true

Custom Hash Functions

If you would like to use a custom hashing function in your multihash you can pass one as an optional last parameter to multihashFile and validMultihash or as option.customHashFn to validateFileFromURI. For full documentation on these individual functions see archon.utils. You might want to do this in cases where you used a non-standard implementation of the hashing algorithm, or where there needs to be some data transformations before you apply the hashing algorithm, as is the case with IPFS hashes. This is only for the initial hashing algorithm in the multihash. Your hashing function should take a single String argument and return a String that is the hex representation of the hash.

  1. Non standard hash function implementations

Note

You must still include a hashcode even if you are using a custom hash function. In order to have a valid multihash your hash must correspond to a valid hashcode. It is not recommended you use an unsupported hashing function that does not have a hashcode. If your hashes are not valid multihashes, consider validating your hashes outside of Archon.

Warning

If you use a custom hash function other interfaces may not be able to validate your hashes.

Example – Solidity keccak-256

Solidity uses a non standard implementation of the keccak-256 hashing algorithm. Therefore if we are using hashes produced by a smart contract we might need to validate using a custom hashing function.

Note

In this example the custom hash function is a non-standard implementation of keccak-256 so it can still use the hashcode 0x1B.

var Archon = require('@kleros/archon');
var Web3 = require('web3')

// Hash our "file" ('12345') using the soliditySha3.
var nonStandardSha3Hash = Archon.utils.multihashFile(
  '12345',
  0x1B, // keccak-256
  Web3.utils.soliditySha3 // custom hash function
);

console.log(nonStandardSha3Hash); // 4ZqgPBxZrZkSXnTBm8G162mXVCNNbWrZa25CcvfGtQV1pRHH6X8vfLi89RKTA4c6tyfQsD5vzGvJozs24XvcLysiC3U6b

// Validate using the standard keccak-256 hashing algorithm.
console.log(Archon.utils.validMultihash(
  nonStandardSha3Hash,
  '12345'
)) // false

// Validate using the solidity sha3 implementation.
console.log(Archon.utils.validMultihash(
  nonStandardSha3Hash,
  '12345',
  Web3.utils.soliditySha3
)) // true

Hash Validation Troubleshooting

Here are some common mistakes that can cause your hashes to fail validation:

  • Did not remove all insignificant whitespace before hashing JSON. This means all newlines and spaces in between your JSON values.
  • Using a non-standard hash function. Out of the box, Archon supports these hashing algorithms. They are from the javascript library js-sha3. If you used a different hashing algorithm you will need to pass an implementation of it to Archon. See Custom Hashing.
  • sha2 vs sha3. Many libraries will specify their hashes are sha256 without specifying if they are sha2 or sha3. sha2-256 and sha3-256 are different hashing algorithms and use different hashcodes.
  • Not using the base58 representation of the multihash hash. Multihash hashes can be expressed in many bases. Archon is expecting base58 hashes.
  • Did not include the original hash in some format to validateFileFromURI. Archon accepts hashes as the name of the file with no file type extension or using the property selfHash if the file is JSON. Otherwise if you have an alternate method of obtaining the hash pass it using options.hash.

Supported Hashing Algorithms and Hashcodes

Supported hashing algorithms:

Name Multicode
sha3-512 0x14
sha3-384 0x15
sha3-256 0x16
sha3-224 0x17
keccak-224 0x1A
keccak-256 0x1B
keccak-384 0x1C
keccak-512 0x1D

Tip

By default, IPFS uses sha2-256. Many ethereum hashes are keccak-256.

Warning

Solidity uses a different implementation of the keccak-256 algorithm. Hashes generated from smart contracts will need a customHashFn to verify.

Note

All insignificant whitespace should be removed from JSON files before hashing. You can use JSON.stringify to remove whitespace.

If a different hashing algorithm was used, pass it in the desired function with customHashFn. The function should expect a single string parameter.

A full list of possible algorithms and multicodes can be found here.