<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](https://github.com/Emurgo/cardano-serialization-lib/issues/141)).

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](https://github.com/Berry-Pool/nami-wallet/blob/58c924cfd98fd568ed2ff133d95fde16771e81d8/src/api/extension/wallet.js#L20), 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](https://cardano.stackexchange.com/questions/486/re-implementing-policy-hashing-in-python) by @tycl.

Basically we need to

1. Parse the policy (JSON)
2. Follow the CDDL specifications to translate the policy to an array
   *(see link below)*
3. Use the array as input to cbor.encode().
4. Prepend a "0" byte to the result.
5. 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!  

---

