user6196: I want to generate the address from the plutus script's cborhex value, but so far without much luck. I am using the alwayssucceeds.plutus contract as an example for which the cborhex value is 4E4D01000033222220051200120011 and the for which the address is known to be addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8. What i want to do is derive the same address from the cboxhex by using the cardano-serialization-lib
Why not use the cardano-cli for this by running cardano-cli address build --payment-script-file alwayssucceeds.plutus --testnet-magic 1097911063 --out-file script.addr ?
Well, if it can be done in the cardano-serialization-lib then it means it can be done in the client's front end which is faster and requires less wiring to the backend. cardano-serialization-lib is already used for a lot of the interaction with the wallet and submitting transactions, so it is a natural place to derive the address from the cborhex
This is my code, but it does not produce the correct address
// cborhex of the alwayssucceeds.plutus
const cborhex = "4E4D01000033222220051200120011";
const cbor = Buffer.from(cborhex, "hex");
const blake2bhash = blake.blake2b(cbor, 0, 28); //blake2b-224 -> 28 bytes
const scripthash = ScriptHash.from_bytes(blake2bhash);
const cred = StakeCredential.from_scripthash(scripthash);
const networkId = NetworkInfo.testnet().network_id();
const baseAddr = EnterpriseAddress.new(networkId, cred);
const addr = baseAddr.to_address();
const addrBech32 = addr.to_bech32();

// hash of the address generated from script
console.log(Buffer.from(addr.to_bytes(), "utf8").toString("hex"))

// hash of the address generated using cardano-cli
const ScriptAddress = Address.from_bech32("addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8");
console.log(Buffer.from(ScriptAddress.to_bytes(), "utf8").toString("hex"))

And the hex outputs are:
geneated from cborhex: 70d4e0f6e402a19e086f2fb9914124604ece088db0fa5906fb0f66fc07
generated by cardano-cli: 7067f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656
The corresponding bech32 addresses are:
geneated from cborhex: addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8
generated by cardano-cli: addr_test1wr2wpahyq2seuzr097uezsfyvp8vuzydkra9jphmpan0cpczfflxx
The blake package is npm install blakejs
Similar question has been raised in the below 2 links, without an adequate answer so far:
Link1
Link2

user7460: I've answered this here, but as a reference I'll copy my answer below:

Plutus-Core script bytes are wrapped twice in a CBOR bytearray.
Use the following steps to calculate the script address:

unwrap one layer of CBOR
prepend a byte representing the PlutusScript version: 0x01 for PlutusScriptV1, 0x02 for PlutusScriptV2
calculate the 28-byte (224-bit) blake2b digest to get the payment part of the address
form the full script address using CIP19 (so for script addresses without a staking part simply prepend 0x70 to the digest)
encode the script address bytes using bech32 ("addr_test" prefix for testnet, "addr" prefix for mainnet)

The pseudo code of these steps would look as follows: encodeBech32("addr_test", prepend(hashBlake2b224(prepend(unwrapCborBytes(hexToBytes(cborHex)), 0x01)), 0x70))
As an example consider the commonly used AlwaysSucceeds script. It has
the following hexadecimal representation:
"4e4d01000033222220051200120011".

Unwrapping one layer of CBOR bytearray would give: "4d01000033222220051200120011".
Prepend 0x01: "014d01000033222220051200120011"
Blake2b 28-byte digest: "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
Prepend 0x70: "7067f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
Bech32 encoding of testnet address: "addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8"

Don't ask me why Plutus-Core scripts are wrapped twice in CBOR, and
then unwrapped once to calculate the address. Some smart guys
somewhere must have a good reason.
If you'd like to do these calculations in Javascript without some
complicated Rust/Haskell dependencies check out the Helios Lang
library. The library is UNLICENSEd so you can copy the relevant
functionality as you please.


6196: <p>I want to generate the address from the plutus script's cborhex value, but so far without much luck. I am using the <code>alwayssucceeds.plutus</code> contract as an example for which the cborhex value is <code>4E4D01000033222220051200120011</code> and the for which the address is known to be <code>addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8</code>. What i want to do is derive the same address from the cboxhex by using the cardano-serialization-lib</p>
<p>Why not use the <code>cardano-cli</code> for this by running <code>cardano-cli address build --payment-script-file alwayssucceeds.plutus --testnet-magic 1097911063 --out-file script.addr</code> ?</p>
<p>Well, if it can be done in the cardano-serialization-lib then it means it can be done in the client's front end which is faster and requires less wiring to the backend. cardano-serialization-lib is already used for a lot of the interaction with the wallet and submitting transactions, so it is a natural place to derive the address from the cborhex</p>
<p>This is my code, but it does not produce the correct address</p>
<pre><code>// cborhex of the alwayssucceeds.plutus
const cborhex = &quot;4E4D01000033222220051200120011&quot;;
const cbor = Buffer.from(cborhex, &quot;hex&quot;);
const blake2bhash = blake.blake2b(cbor, 0, 28); //blake2b-224 -&gt; 28 bytes
const scripthash = ScriptHash.from_bytes(blake2bhash);
const cred = StakeCredential.from_scripthash(scripthash);
const networkId = NetworkInfo.testnet().network_id();
const baseAddr = EnterpriseAddress.new(networkId, cred);
const addr = baseAddr.to_address();
const addrBech32 = addr.to_bech32();

// hash of the address generated from script
console.log(Buffer.from(addr.to_bytes(), &quot;utf8&quot;).toString(&quot;hex&quot;))

// hash of the address generated using cardano-cli
const ScriptAddress = Address.from_bech32(&quot;addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8&quot;);
console.log(Buffer.from(ScriptAddress.to_bytes(), &quot;utf8&quot;).toString(&quot;hex&quot;))
</code></pre>
<p>And the hex outputs are:
geneated from cborhex: <code>70d4e0f6e402a19e086f2fb9914124604ece088db0fa5906fb0f66fc07</code>
generated by cardano-cli: <code>7067f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656</code></p>
<p>The corresponding bech32 addresses are:
geneated from cborhex: <code>addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8</code>
generated by cardano-cli: <code>addr_test1wr2wpahyq2seuzr097uezsfyvp8vuzydkra9jphmpan0cpczfflxx</code></p>
<p>The <code>blake</code> package is <code>npm install blakejs</code></p>
<p>Similar question has been raised in the below 2 links, without an adequate answer so far:
<a href="https://github.com/Emurgo/cardano-serialization-lib/issues/233" rel="nofollow noreferrer">Link1</a>
<a href="https://cardano.stackexchange.com/questions/4573/how-to-generate-the-address-of-a-plutus-script-using-cardano-serialization-lib">Link2</a></p>
 7460: <p>I've answered this <a href="https://cardano.stackexchange.com/a/8820/7460">here</a>, but as a reference I'll copy my answer below:</p>
<blockquote>
<p>Plutus-Core script bytes are wrapped twice in a CBOR bytearray.</p>
<p>Use the following steps to calculate the script address:</p>
<ol>
<li>unwrap one layer of CBOR</li>
<li>prepend a byte representing the PlutusScript version: 0x01 for PlutusScriptV1, 0x02 for PlutusScriptV2</li>
<li>calculate the 28-byte (224-bit) blake2b digest to get the payment part of the address</li>
<li>form the full script address using CIP19 (so for script addresses without a staking part simply prepend 0x70 to the digest)</li>
<li>encode the script address bytes using bech32 (&quot;addr_test&quot; prefix for testnet, &quot;addr&quot; prefix for mainnet)</li>
</ol>
<p>The pseudo code of these steps would look as follows: <code>encodeBech32(&quot;addr_test&quot;, prepend(hashBlake2b224(prepend(unwrapCborBytes(hexToBytes(cborHex)), 0x01)), 0x70))</code></p>
<p>As an example consider the commonly used AlwaysSucceeds script. It has
the following hexadecimal representation:
&quot;4e4d01000033222220051200120011&quot;.</p>
<ol>
<li>Unwrapping one layer of CBOR bytearray would give: &quot;4d01000033222220051200120011&quot;.</li>
<li>Prepend 0x01: &quot;014d01000033222220051200120011&quot;</li>
<li>Blake2b 28-byte digest: &quot;67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656&quot;</li>
<li>Prepend 0x70: &quot;7067f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656&quot;</li>
<li>Bech32 encoding of testnet address: &quot;addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8&quot;</li>
</ol>
<p>Don't ask me why Plutus-Core scripts are wrapped twice in CBOR, and
then unwrapped once to calculate the address. Some smart guys
somewhere must have a good reason.</p>
<p>If you'd like to do these calculations in Javascript without some
complicated Rust/Haskell dependencies check out the <a href="https://github.com/Hyperion-BT/Helios" rel="nofollow noreferrer">Helios Lang
library</a>. The library is UNLICENSEd so you can copy the relevant
functionality as you please.</p>
</blockquote>
