<p>Finally got my head around this, thanks to this version in Python: <a href="https://cardano.stackexchange.com/questions/486/re-implementing-policy-hashing-in-python">Re-Implementing Policy Hashing in Python</a> by @tycl.</p>
<p>Basically we need to</p>
<ol>
<li>Parse the policy (JSON)</li>
<li>Follow the CDDL specifications to translate the policy to an array
<em>(see link below)</em></li>
<li>Use the array as input to cbor.encode().</li>
<li>Prepend a &quot;0&quot; byte to the result.</li>
<li>Run that new byte array through blake2bHex.</li>
</ol>
<p>And we're done.</p>
<p>Here's an example:</p>
<p>The policy used is the one from above and I translate it manually to the array via <a href="https://github.com/input-output-hk/cardano-ledger/blob/683bef2e40cbd10339452c9f2009867c855baf1a/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L228-L246;" rel="nofollow noreferrer">https://github.com/input-output-hk/cardano-ledger/blob/683bef2e40cbd10339452c9f2009867c855baf1a/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L228-L246;</a></p>
<p>Cbor-Web used from here: <a href="https://github.com/hildjj/node-cbor/tree/main/packages/cbor-web" rel="nofollow noreferrer">https://github.com/hildjj/node-cbor/tree/main/packages/cbor-web</a></p>
<p>Blakejs package from here: <a href="https://github.com/dcposch/blakejs" rel="nofollow noreferrer">https://github.com/dcposch/blakejs</a></p>
<pre><code>// Values from policy json
const keyhash = &quot;46a26617f9b59cc48945ccc6c0aecee732f7698fadbe8b5624b44b9e&quot;;
const slot = 42863577;

// Translation via CDDL link above
// [1, [X]] =&gt; &quot;script_all&quot;
// [5, slot] =&gt; &quot;invalid_hereafter&quot; (~ &quot;valid before&quot;)
// [0, keyHashBytes] =&gt; &quot;script_pubkey&quot;
// Remember: 1) Buffer conversion and 2) Order matters.
const cborInput = [1, [[5, slot], [0, Buffer.from(hexToBytes(keyhash))]]]

// Cbor encode
let cborResult = cbor.encode(cborInput);

// Prepend the 0 byte
let tmp = new Uint8Array(cborResult.length + 1);
tmp.set(Uint8Array.of(0), 0);
tmp.set(cborResult, 1);
cborResult = tmp;

// Run the result through blake2d with digest size / output length of 28
const blakeHexResult = Blake.blake2bHex(cborResult, null, 28);
console.log(blakeHexResult);
</code></pre>

CC BY-SA 4.0
2021-11-22T08:19:42.367Z
awesome, thanks for linking to cddl!
andycandy
CC BY-SA 4.0
2021-11-21T15:19:26.993Z
2021-11-21T22:29:34.593Z
2021-11-21T22:29:34.593Z
sean
<p>You can do this using the 10.0 beta version of <code>cardano-serialization-lib</code> which should make it into stable pretty soon (I'm in the process of testing this, you can follow the status on <a href="https://github.com/Emurgo/cardano-serialization-lib/issues/141" rel="nofollow noreferrer">this Github issue</a>).</p>
<p>This should be enough to get you started:</p>
<pre><code>const ttl = protocolParameters.slot+invalidHereafter
const timelockExpiry = S.TimelockExpiry.new(ttl)
const timeLockedPolicyScript = S.NativeScript.new_timelock_expiry(timelockExpiry)
const policyScripts = S.NativeScripts.new()
const policyScripts.add(timeLockedPolicyScript)
const scriptHash = S.ScriptHash.from_bytes(timeLockedPolicyScript.hash().to_bytes())
const policyID = bytesToString(timeLockedPolicyScript.hash().to_bytes())
</code></pre>
<p>In order for that code to work, you'll need some valid protocolParameters object which can be retrieved from Blockfrost using <a href="https://github.com/Berry-Pool/nami-wallet/blob/58c924cfd98fd568ed2ff133d95fde16771e81d8/src/api/extension/wallet.js#L20" rel="nofollow noreferrer">this code from Nami wallet</a>, as well as the <code>bytesToString</code> function which is defined using Buffer:</p>
<pre><code>export const bytesToString = (bytes) =&gt; {
  return Buffer.from(bytes, &quot;hex&quot;).toString(&quot;hex&quot;)
}
</code></pre>

CC BY-SA 4.0
2021-11-22T16:11:32.373Z
Nice, thanks, that looks pretty elegant! 
sean
CC BY-SA 4.0
2021-11-22T10:05:55.433Z
2021-11-22T10:05:55.433Z
Thom
<p>I'm looking for a Javascript implementation of the CLI's <code>cardano-cli transaction policyid</code> function, can anyone point me in the right direction here?</p>
<p>Trying to replicate it with blakejs (<a href="https://github.com/dcposch/blakejs" rel="nofollow noreferrer">https://github.com/dcposch/blakejs</a>) and cbor-web (<a href="https://github.com/hildjj/node-cbor/tree/main/packages/cbor-web" rel="nofollow noreferrer">https://github.com/hildjj/node-cbor/tree/main/packages/cbor-web</a>), but failing to get the hashes to match the output of the CLI.</p>
<p><em>Eg I want to create a PolicyID / ScriptHash from this policy script:</em></p>
<pre><code>{
  &quot;type&quot;: &quot;all&quot;,
  &quot;scripts&quot;:
  [
   {
     &quot;type&quot;: &quot;before&quot;,
     &quot;slot&quot;: 42863577
   },
   {
     &quot;type&quot;: &quot;sig&quot;,
     &quot;keyHash&quot;: &quot;46a26617f9b59cc48945ccc6c0aecee732f7698fadbe8b5624b44b9e&quot;
   }
  ]
}
</code></pre>
<p><em>(CLI gives me this policyid: 463e9264962cea64efafa576d44c8d2821d09c0c7495c253d4101a9a)</em></p>
<p>In JS I'm trying something along these lines:</p>
<pre><code>[removed, see correct answer below]
</code></pre>
<p><em>(gives me this: 5db35cd45775e7d7b0d1bd5491a9baea7ac54b41772a8c96ce587579)</em></p>
<p>Any guidance is very much appreciated</p>

<cardano-cli><policy><javascript><cbor><blake2b>
Programmatically creating the policyid / scripthash in Javascript (Browser)
# Programmatically creating the policyid / scripthash in Javascript (Browser)

(Asked by: username_0 on 2021-11-20)

I'm looking for a Javascript implementation of the CLI's cardano-cli transaction policyid function, can anyone point me in the right direction here?
Trying to replicate it with blakejs (https://github.com/dcposch/blakejs) and cbor-web (https://github.com/hildjj/node-cbor/tree/main/packages/cbor-web), but failing to get the hashes to match the output of the CLI.
Eg I want to create a PolicyID / ScriptHash from this policy script:
{
  "type": "all",
  "scripts":
  [
   {
     "type": "before",
     "slot": 42863577
   },
   {
     "type": "sig",
     "keyHash": "46a26617f9b59cc48945ccc6c0aecee732f7698fadbe8b5624b44b9e"
   }
  ]
}

(CLI gives me this policyid: 463e9264962cea64efafa576d44c8d2821d09c0c7495c253d4101a9a)
In JS I'm trying something along these lines:
[removed, see correct answer below]

(gives me this: 5db35cd45775e7d7b0d1bd5491a9baea7ac54b41772a8c96ce587579)
Any guidance is very much appreciated

**Tags:** cardano-cli, policy, javascript, cbor, blake2b

---

## 2 answers

### Answer by username_2 on 2021-11-22. Score: 1 | Accepted answer

You can do this using the 10.0 beta version of cardano-serialization-lib which should make it into stable pretty soon (I'm in the process of testing this, you can follow the status on this Github issue).
This should be enough to get you started:
const ttl = protocolParameters.slot+invalidHereafter
const timelockExpiry = S.TimelockExpiry.new(ttl)
const timeLockedPolicyScript = S.NativeScript.new_timelock_expiry(timelockExpiry)
const policyScripts = S.NativeScripts.new()
const policyScripts.add(timeLockedPolicyScript)
const scriptHash = S.ScriptHash.from_bytes(timeLockedPolicyScript.hash().to_bytes())
const policyID = bytesToString(timeLockedPolicyScript.hash().to_bytes())

In order for that code to work, you'll need some valid protocolParameters object which can be retrieved from Blockfrost using this code from Nami wallet, as well as the bytesToString function which is defined using Buffer:
export const bytesToString = (bytes) => {
  return Buffer.from(bytes, "hex").toString("hex")
}

> **Comments:**
> **username_0**: Nice, thanks, that looks pretty elegant!   

---

### Answer by username_0 on 2021-11-21. Score: 3

Finally got my head around this, thanks to this version in Python: Re-Implementing Policy Hashing in Python by @tycl.
Basically we need to

Parse the policy (JSON)
Follow the CDDL specifications to translate the policy to an array
(see link below)
Use the array as input to cbor.encode().
Prepend a "0" byte to the result.
Run that new byte array through blake2bHex.

And we're done.
Here's an example:
The policy used is the one from above and I translate it manually to the array via https://github.com/input-output-hk/cardano-ledger/blob/683bef2e40cbd10339452c9f2009867c855baf1a/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L228-L246;
Cbor-Web used from here: https://github.com/hildjj/node-cbor/tree/main/packages/cbor-web
Blakejs package from here: https://github.com/dcposch/blakejs
// Values from policy json
const keyhash = "46a26617f9b59cc48945ccc6c0aecee732f7698fadbe8b5624b44b9e";
const slot = 42863577;

// Translation via CDDL link above
// [1, [X]] => "script_all"
// [5, slot] => "invalid_hereafter" (~ "valid before")
// [0, keyHashBytes] => "script_pubkey"
// Remember: 1) Buffer conversion and 2) Order matters.
const cborInput = [1, [[5, slot], [0, Buffer.from(hexToBytes(keyhash))]]]

// Cbor encode
let cborResult = cbor.encode(cborInput);

// Prepend the 0 byte
let tmp = new Uint8Array(cborResult.length + 1);
tmp.set(Uint8Array.of(0), 0);
tmp.set(cborResult, 1);
cborResult = tmp;

// Run the result through blake2d with digest size / output length of 28
const blakeHexResult = Blake.blake2bHex(cborResult, null, 28);
console.log(blakeHexResult);

> **Comments:**
> **username_1**: awesome, thanks for linking to cddl!  

---

