elements icon indicating copy to clipboard operation
elements copied to clipboard

Combining unblinded issuance with an unblinded re-issuance does not work

Open tiero opened this issue 3 years ago • 8 comments

I am trying to make in the same transaction

  • an unblinded issuance of a new asset (amount 1, precision 0 and NO reissuance tokens)
  • a unblinded reissuance of a previously issued asset (amount whatever)

In this transaction the re-issuance token input and change output are blinded (and eventually the L-BTC input and change output)

broadcasting I got bad-txns-in-ne-out, value in != value out

Bash script to replicate

https://github.com/vulpemventures/liquidjs-lib/blob/issuance-mixed-reissuance/issuance-mixed-reissuance.sh

Decoded raw transaction

{
  "txid": "bd5ba95822b15979567655c4b9d1e5d886868548d19a2c22698f7af44afea069",
  "hash": "027ca81ab73f51f65284337cad90f5bbae554c59f693f4c19ef814a78e7ee459",
  "wtxid": "027ca81ab73f51f65284337cad90f5bbae554c59f693f4c19ef814a78e7ee459",
  "withash": "0702e167c7468291ff37b0f965669deea3244a574e10ab8d7e302e27265fcb3f",
  "version": 2,
  "size": 17957,
  "vsize": 5071,
  "weight": 20282,
  "locktime": 0,
  "vin": [
    {
      "txid": "77241409eaa7ef6663bd9ea9df6a2834e288c0d0368591304e87db365643b7f1",
      "vout": 1,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "is_pegin": false,
      "sequence": 4294967295,
      "txinwitness": [
        "304402207e193a17f501f5659ebcb7d93f716158b30876561a6590cfdc159a40d2f50c3102205ca8d81ab4c74cc5d2621d0d5a1ac275671dca208fbbd1c4c614e9f4e6f3305b01",
        "0387992ef847f40f0d21c1d800767a9a3c1c026b29034fcf5a658cfac0214cd87f"
      ],
      "issuance": {
        "assetBlindingNonce": "9a64d614f476cc765e83b4bb8838f8735cef8efd9d240d5148b88b0d83d722de",
        "assetEntropy": "cd84bbf7f5a71fb106b6a068ce14e9dd2eea9fc8d3574810cbdbe6b2241e9a1a",
        "isreissuance": true,
        "asset": "94de85cdbffc86809cf6f75b467eb15d34b4c514a0fa6bd328080eefaa447802",
        "assetamountcommitment": "082c76489b2c1d11ae135c560dd7987e0c37c8fc23952c62734a4676c6481a4d36"
      }
    },
    {
      "txid": "77241409eaa7ef6663bd9ea9df6a2834e288c0d0368591304e87db365643b7f1",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "is_pegin": false,
      "sequence": 4294967293,
      "txinwitness": [
        "3044022073efd4815b052d4e308adadbe5ac7b49dd6fff7e2dad2fc3c408ed75e54572f702206ba7467e72848db16436a54da002bb546cd611d60e0bdea2f40efa47add2de3101",
        "03ffd5241b1169ad8e4d2e47ef109b0ebf307706a73061c2ff312999346801c8c9"
      ],
      "issuance": {
        "assetBlindingNonce": "0000000000000000000000000000000000000000000000000000000000000000",
        "assetEntropy": "1912695fe201c87a0261c5cff698750eacd302b5872e21c4aef6cd1d61fffc54",
        "isreissuance": false,
        "token": "ba6e34baff190106e8a13a7b26a977b0678cc228bbe51fd3f9ccdbd43d872ff9",
        "asset": "fb2f6da74f5a671040c172f78fb536bcdf41ac4ee63d34b04d27d46caf6b4a3a",
        "assetamountcommitment": "08c1c81de668c97bcfb0758673f0b081d53f7331e37985c17831bb3ba56c0c768a"
      }
    }
  ],
  "vout": [
    {
      "value-minimum": 0.00000001,
      "value-maximum": 45035996.27370496,
      "ct-exponent": 0,
      "ct-bits": 52,
      "surjectionproof": "040007c62324c1b5bdc9dd8145d6b96e1a66c920fd98e9687e00c9e684c1428e0ccd20502b1c6cc1262db0879fd8cf98b5d438e12754b05d8b10eb6bd8a7e4970c74f62cdedb152f9a623d9b8615d1b3e670dc9d22fa818a49be033b7a133f9ae1632acf90acc52eea2bc42e9e9422baa73ada28fe5e69e4dbdd61f3ce42cfdf9ea783",
      "valuecommitment": "0876095d6a9a0ad58f670e8822ab72cd1813a3438fb5004356d67595951cf508ba",
      "assetcommitment": "0b0d16e55fc5c955ae564f01fc4453a0e8424fcd5d255c2c87bc3f0ea7735514f9",
      "commitmentnonce": "03d4846036858e0685c4c298e1a0fa266af2a23207bb4f3b1f5e3ad1455791c240",
      "commitmentnonce_fully_valid": true,
      "n": 0,
      "scriptPubKey": {
        "asm": "0 1b21b036c01b77909b89449fa455efc88ecd8cd0",
        "hex": "00141b21b036c01b77909b89449fa455efc88ecd8cd0",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "ert1qrvsmqdkqrdmepxufgj06g400ez8vmrxscpq84s"
        ]
      }
    },
    {
      "value-minimum": 0.00000001,
      "value-maximum": 45035996.27370496,
      "ct-exponent": 0,
      "ct-bits": 52,
      "surjectionproof": "040007415f7a42ab05c8626c361fcbcbe732d474fe85fc17e3747475b3e91f65b41a23ba9aed36cda781c4bec8dccc7efa7f53d9cb758fa88a61848c83e0289660fa95a1ce3cb51ee3e59cec5eddbbb789466d36e10d7646a2385854184e22032fca05dc19172dd9f9b28e8f2f163353cdcb7417879efa0a3edabc58134e713248dd3c",
      "valuecommitment": "091181e7c636c6acd45eb464111f6e05324d3bc1b209b1f1ea0b08e9de377c26b5",
      "assetcommitment": "0b59f43e3febd8d2339fd45b7e24e941cc816afec3863a414c4a10bdf5606991a0",
      "commitmentnonce": "02735519f76fb1afef099c64d86552a623e945523e56f632b6a31cceb4cf98130d",
      "commitmentnonce_fully_valid": true,
      "n": 1,
      "scriptPubKey": {
        "asm": "0 4d7c56d8c207475f95a8638685921e1211407820",
        "hex": "00144d7c56d8c207475f95a8638685921e1211407820",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "ert1qf479dkxzqar4l9dgvwrgtys7zgg5q7pqxw6lle"
        ]
      }
    },
    {
      "value": 0.00150000,
      "asset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225",
      "commitmentnonce": "",
      "commitmentnonce_fully_valid": false,
      "n": 2,
      "scriptPubKey": {
        "asm": "0 588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "hex": "0014588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "ert1qtz89cfq54fdgekhu9m759pn3xpr64ek7mmm5ds"
        ]
      }
    },
    {
      "value": 0.00000001,
      "asset": "fb2f6da74f5a671040c172f78fb536bcdf41ac4ee63d34b04d27d46caf6b4a3a",
      "commitmentnonce": "",
      "commitmentnonce_fully_valid": false,
      "n": 3,
      "scriptPubKey": {
        "asm": "0 588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "hex": "0014588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "ert1qtz89cfq54fdgekhu9m759pn3xpr64ek7mmm5ds"
        ]
      }
    },
    {
      "value": 0.00250000,
      "asset": "94de85cdbffc86809cf6f75b467eb15d34b4c514a0fa6bd328080eefaa447802",
      "commitmentnonce": "",
      "commitmentnonce_fully_valid": false,
      "n": 4,
      "scriptPubKey": {
        "asm": "0 588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "hex": "0014588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "ert1qtz89cfq54fdgekhu9m759pn3xpr64ek7mmm5ds"
        ]
      }
    },
    {
      "value": 0.00000264,
      "asset": "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225",
      "commitmentnonce": "",
      "commitmentnonce_fully_valid": false,
      "n": 5,
      "scriptPubKey": {
        "asm": "",
        "hex": "",
        "type": "fee"
      }
    }
  ]
}

tiero avatar Mar 18 '22 15:03 tiero

Sorry for letting this issue sit so long.

The wallet appears to be balancing the transaction correctly. The error txns-in-ne-out is a generic "something in CT validation failed" error, which in this case appears to be that the asset entropy is incorrect. I'm digging into this.

Edit The mixing of issuance and reissuance is a red herring -- the issue is hit even when you don't add the issuance, only the reissuance.

apoelstra avatar Mar 28 '22 23:03 apoelstra

Ok, so reading this code it actually looks like it's impossible to do a blind reissuance of an asset that was originall issued in a non-blinded way. The reason is that the reissuance token is actually computed based on a hash of (among other things) the blindedness of the issuance. So if you create a nonblinded asset, then try to do a blinded reissueance, the validation logic will reject your token.

I seem to remember this being a design decision, way back in 2016 when we were whiteboarding this, but I don't remember now. The premise was that you either want to have a transparent asset supply or you don't.

In any case we should have much better error detection/reporting about this.

Independently of this, I highly doubt that our RPC can handle doing nonblinded and blinded things in the same transaction.

cc @stevenroose do you know any more about this?

apoelstra avatar Mar 29 '22 00:03 apoelstra

I am aware the reissuance token must be "blinded when spent" to grant powers to make a re-issuance.

That being said, in the current transaction the original issuance is unblinded, and in the re-issuance is unblinded too, as you can see from here. It's the vout 4 in the pasted decode raw transaction.

If I try to split up the transaction, ie. I only do a re-issuance or I only do an issuance of the NFT separately it works just fine.

tiero avatar Mar 29 '22 09:03 tiero

The quoted line does not determine whether or not the reissuance is blinded, I think. This is decided by blindrawtransaction which defaults to blinding issuances.

apoelstra avatar Mar 29 '22 17:03 apoelstra

The resulting raw transaction decoded says otherwise tho:

  • commitmentnonce is empty
  • value and asset are explicit

I just ran again the script, you can reproduce it all the times, this is the output attached by rawreissueasset

  {
      "value": 0.00250000,
      "asset": "2dcf5a8834645654911964ec3602426fd3b9b4017554d3f9c19403e7fc1411d3",
      "commitmentnonce": "",
      "commitmentnonce_fully_valid": false,
      "n": 2,
      "scriptPubKey": {
        "asm": "0 588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "hex": "0014588e5c2414aa5a8cdafc2efd4286713047aae6de",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "ert1qtz89cfq54fdgekhu9m759pn3xpr64ek7mmm5ds"
        ]
      }
    },

In case this is a "bug" of blindrawtransaction (ie. to always blind outputs of assets being reissued, regardless of address type passed) seems very akward to me

How it can blind if I am not passing a confidential address? Which blind pub key will be used? If it picks it from Elements core wallet seem very reckless behavior for a rawreissueasset command, since is supposed to be used to create complex transactions, most likely that address is not from the Elements Core wallet, but of someone else (like in this case).

tiero avatar Mar 29 '22 23:03 tiero

the issue is hit even when you don't add the issuance, only the reissuance.

I tried with Elements Core to do this instead (attaching an unblinded reissuance ) and yes, you right it does not work, but pretty sure it's doable 100%

I made this with LiquidJS and Go Elements, both allowed me to do it and broadcast 👉 https://blockstream.info/liquidtestnet/tx/e422f8d71d59f176b80dc36a88cea1ccbee4d92eb2f888d8478987a5143fb60f

only the token input and the change is blinded, the rest is fully unblinded (vout 2 is the asset output being reissued). If you follow the trail of that asset, has been issued as unblinded originally too.

tiero avatar Mar 29 '22 23:03 tiero

The output of rawissueasset will always be unblinded, because rawissueasset does not do blinding.

When blinding issuances, the wallet just generates a random blinding pubkey. The message sidechannel is not used on this rangeproof so it doesn't matter at all what key is used.

case this is a "bug" of blindrawtransaction (ie. to always blind outputs of assets being reissued, regardless of address type passed) seems very akward to me

Yes, the entire rawtransaction API is very awkward :(. We are moving to PSET, which is much better-designed to handle so many moving parts.

apoelstra avatar Mar 30 '22 12:03 apoelstra

The output of rawissueasset will always be unblinded, because rawissueasset does not do blinding.

The output I show in the previous comment is the output of signed_tx so it already passed through blindrawtransaction

We are moving to PSET, which is much better-designed to handle so many moving parts.

Yep, we tried it there, Looking forward to use that indeed.

tiero avatar Mar 30 '22 14:03 tiero