Skip to content

Asset issuance not working as expected #108

@Distance71

Description

@Distance71

Hello community,

I'm trying to create an asset with no success.

Everything looks well during the process of creation, but when I try to broadcast to the network I get this error:

sendrawtransaction RPC error: {"code":-26,"message":"mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)"}

To broadcast, I used https://blockstream.info/liquidtestnet/api/tx, passing the transactionHex in the body as 'text'

I've used the same methods as described in the examples provided

This's the full code needed to reproduce. Any help would be appreciated :)

const ecc = require('tiny-secp256k1');
  const secp256k1 = require('@vulpemventures/secp256k1-zkp');
  const liquid = require('liquidjs-lib');
  const { ECPairFactory } = require('ecpair');

  const ECPair = ECPairFactory(ecc);
  const TESTNET = liquid.networks.testnet;

  const makeAddressOne = () => {
  const keyPair = ECPair.fromPrivateKey(
    Buffer.from('acbc28e59c0122f97d479d1e22806534f5bc4ff0bf127505be7dd8a8e11dc726', 'hex'),
  );

  const { address } = liquid.payments.p2pkh({
    pubkey: keyPair.publicKey,
    network: TESTNET,
  });

  const blindkey = keyPair.publicKey;

  const { confidentialAddress } = liquid.payments.p2pkh({
    address,
    blindkey,
    network: TESTNET,
  });

  return {
    address,
    confidentialAddress,
    keys: keyPair,
  };
};

const convertAddressToScript = address => liquid.address.toOutputScript(address, TESTNET);


function signTransaction(pset, signers, sighashType, ecclib = ecc) {
  const signer = new liquid.Signer(pset);

  signers.forEach((keyPairs, i) => {
    const preimage = pset.getInputPreimage(i, sighashType);
    const partialSig = {
      partialSig: {
        pubkey: keyPairs.publicKey,
        signature: liquid.script.signature.encode(keyPairs.sign(preimage), sighashType),
      },
    };
    signer.addSignature(i, partialSig, liquid.Pset.ECDSASigValidator(ecclib));
  });

  if (!pset.validateAllSignatures(liquid.Pset.ECDSASigValidator(ecclib))) {
    throw new Error('Failed to sign pset');
  }

  const finalizer = new liquid.Finalizer(pset);
  finalizer.finalize();
  return liquid.Extractor.extract(pset);
}

  const addressAlice = makeAddressOne();
  const lbtc = liquid.networks.testnet.assetHash;

  const unspentConfidential = {
    txid: '337b9c5c8a4e83a56875d53b1ad9e7caa1c0862537bf040e4165b717560d9b38',
    vout: 1,
    txHex:
      '020000000101a16e6cfaecf3132c6b993862efd7ca882609850cf16332bc9ba48a729a2afed5010000006a473044022056a5198901f4b0d0e6d9cde19d0865ddd2028aece8b3b6740ba02e7d4aed85cc022050079be073d30b3e2cc5e2823e74e6ac139d48ea46c5601d433e8d69084ff2d701210382375b3986feb6f33d96f86c4bc5e09f53d7b3e4eb5b90eeca6d487b7eb40a65ffffffff0301499a818545f6bae39fc03b637f2a4e1e64e590cac1bc3a6f6d71aa4443654c140100000000000003e8001976a914539cc65863ecfbfce0dd163e9353cb29ea222c0a88ac0b6821f161c20add66bd7a4c3d4a85caf0dd69fcef2fc95a7a15485343e93e61ba093159ac773433fb919b9831f65dfddd250ce1e9afa9f00150a4fba2d79a868a4d033f3ba42f7268beebd479da75e97cd5bb6f791fec5dc545cd0db294110cbb38cc1976a9146db5192bb9ef2b8ba234d8e5b9399d4219419f9588ac01499a818545f6bae39fc03b637f2a4e1e64e590cac1bc3a6f6d71aa4443654c140100000000000003e800000000000000000000000043010001f59a88d5ac142a8dc48b088ad822e0e00305c1ded821d36e3dd2545e6c3dbdf9767d040e34a1d794e61ef558875435d3c953a1631fcc9c072b60eb64adf2691afd4e1060330000000000000001f5f06c009fc8e7035dc105984b6e61199fbac515d51ca3a0d8480675d927918f363b4b97cdd6ad2be78493dbdb268454c752df01c4cbba762ece262ba78e4a8bf014172304bc39b687269fa60354620178c11fd2f12261ab9e38d111d6d64214f7424b90ec96eef050d9fab83954d889d964d4607f8dab2939353d3f0d11ca3736e9ecf92cb94fe9b8ab3c56ddad2ec153ab226487d996f2debe0e247fa0448841a3ddaf09801ced01157d3876a82c6b6a9e3b610e529c33d5cbde73ff8a040a266c874182dc5f685e4bca2ba6b0b6cc03f328887c5457e65c600fd09027abb7c61231b71099fc5c8f386ad86313e3f096a89edfc18f52a151d8ec4627e418241dd040807c753d91e9c7feced79f80572e9cb01ad5dd4b63d1c0ba020d5371f15b0951d11873d277ba0959b88ffd50b7dc1abb1b7d046bfc754d629f477fc9bae94273763dd87a83dfd2dc599c99beef32163e900b0d678c589890d7b8d746e4dff39311919bc2add316acb35d2fcda02a8f428c50bead5d8784f323f490db4d5704b3d2a32edb0a46df72f69345aa3ff90c5e440df0f527ffdf3751763b9b00ee749d46d65672ffbcf880d274b08a74ea526c51db93bc45e22d4329ca7eef60084a26d1daf3a376721a2185d8c119518931d8d7e4fcf9799156e1e71c1bc65cfb6048062787655f67f8b3e51bfd2eb65612f0e86e547480b9890385e8101f0a8d566c71d5263da2257009f78a65aa51fa8dd8c5210f37f7ab7709e36e501937699a871f86ea08913cb14afbddc58bfd987b983bedab6aec29416b373fb84f6ec857f4959a215b403f0553966a4b9a90a99603c9d478fc18331d07cbcd4e59e911404152cc2526e25f7bc00d3e47f85c290047a4c88cd60190d2e432d34abeb6f6ac5852cb30ca12faf4d084ccf7f48e8a1144c640bcbcda5f4257e213e38cb17e174f6cbedc2f44c141bdafcfe4f3cdafcfa8abba1a25b168c405711a365a46145dafc65fdeff276138e822f4145bdf81f09eefb2cde5407a768dc2d460700327630e760625daf720e3f4ead348fea8651d20619ef05b45176ea4b97f45a946b742b7e52e3babc9d0a08cd6aeb7a06774302be3781d34e1d376d3a40315c02008a22da5037bd0adec9a9e0ec3f390c0325315b20aafa98736e184eb0ff3463660c8df6257ecfa4d27bb6c7019ca3649cf705401e02f5d9ef67b22abda8affc68becf290cb62da5fa4070a6c2aba2e76ac2d5c2347acec0458d6f53c446afe45867cdc81efb111c5da8b5b30ca2c0cb74b8c99a023737a9e6e4b0a1854056b69d662073764ef6dfd4f41f3bebda52e222528cd7758b09acf16bd253a1be01e55c4609b600ce148cd9daedd083d532ef200b4f5ebcffbd450e8f565ea5cba568670c7c80ab6104f4934c9d93d96ee5fe56bc2ec24f3915324e680cab7a1f46f79ddfdca13ca4d6fbb2fe2444261d2b6c4568b3cd0a555c29b97b483c645e7b40a478d4f8a1081cc34655860d05568a98dac98d00871bce511e1f062fa1f9d1a919327f6138f04307a618a8002c1dc42ff531ef985bc7a39e64d0a8da9a3aa23c639525d9ba05e3c0bfcc959413e0975ec6d67958016de07f9d5d782511546c3d8f22fbf21556e9b866181d101fe5367f4f5d0df3db30c289211f6adf88b0a186d08fad31b7672607117769045321d8b891e1c798fe1a14305f9fc47d820b2c36cddc106d1aa89ec21567f9f4cba037651276c820b3c410af61f52b5cb19499a1bc25b9e6edf3ba7dbaf8ecd302e40a20a6d411ceb717d25ce6e5f3a31c4afd0dd28b1317fc6edf7ddd28b5a6d44ec9ce47555120f3e76431f9133c477ad192c7df4d800f53ec7c9dc9b999c7d670f9d83c7849d33977f915296a0eefac14881e482a1b2c1d388769c0f5e47d77ffc765f4f74d152389246491e3a2545ece18f715b3afcf3dcd612f6902395ba69eeae2dd5540c74ff88516f19535579fb038f3e492286c10472a74f308a1d73e63aff33470a5c50401b3f671118c1146e0e671a737b12adb6d12a73d360bab1b4915a56265703c85921640502417498db9cd73f6a18c91b8d7c7412c359b1ab79f5e1a631ac7a1dc39567f03617b476b8f6fbb28eeb309c505eb01ed218ed687eedc41a55437763b71bb810ff2b2dd1332cd56346a99bf92e0cef1801afed09c5ee6a9112c40e29c854bfbeb0bd7988689a7f23c6363b4080d62934c8d6fa39485410e0dc54ddd78a231528cfdb2cf2465f9464a9b5f3a6ac5a821dfda6511a569fd488c434c3b5cc9cc88f25dcdea17fd0a7114793cc4b49800115059fdfb9b52781db0bb1e76e6260f927a1698154bebb701bb8f3e33c44f94cae3605e1627fafe392738e908a78da8115ca99382bda27fe6a184e5e865715de0092904cbde1f897ff63857e14e8390bcf965f7057ace53fb32388dd824ad622507c3e0f3df25e31f7ba0af33943d44630c6b15a0f78e1b54760905d23a481c3eedeeb3443009f76e5f9597f83c4ee3f4e376cf6a98bad707530038fe584eac28543dd3fcaccfefdd6b23a03a9a274d9f90fb8f06aae766a675e596cb279433477a9b41e60c9505d11e7335a4e116951cb2305b9cbf3a1ecc2521b66ed1cb111aaad5faaee99b6dbbaa2e12cb191658dae9abcab51ee273b384865b0fcc55c608ca6e4aa97eca8837cce737589a7370770681c9661159923bd12f36d73b0dbfb516628380357b8c50176d7cac52eb4118d2435e1f6386f796f7f152bba3c3b397ba32c2f0a2f7ab57e2df71301928e09971f1e9ce8859c00f46a98a02cf5633729d05838cb14aadab2dfe3a7510b1fce146d387f48f95b97e5177483a38902f98f771248e4b65ed23617db24c17ecd9733b675144cff0f8dd5a5a910355a94af5aa5bd8e718be1b22975853a4b4f9d8cbb69ae189fd4dda571b274484aed920a716295e1b637c5dd9c465fe89e5ccf8c6986e0a0defcf429145b86d40cefd03dc284c0dd8b8dfcc2e99ec7c0b7fd4b8fdf88b558ac0355cce913a254bdb427632ae032f91e3d82c1ee9bb7f08a3171d4fd01121f3b8e9c9941de5543de29309f6de0ef5113a88d66420b9d1926d1e42a2209f991aa5b58b2757f15fe3024bece53f490436ac91b0d6d9dcaa9c0116d5da4707f69d84c0b8bfeba931e8ba767d4f3b3f74854dbbe0799fb03671d4c1836677fa32df079a68e21e36e9dc877d06c1ce7e3da0f368094d32fc15f72e1d859acf37904d5cc86c16e829901893ca9e84c54764b883c885a4110083fce6db292af304f7e7f905cbdb12d519951758060b53c8c0f7e5bfba0664564e37cee01915d4f629ad1772537d5b1d33db5a09ed0ee0fd425502355f42c5d0906c2269405f6617e13552f619c03e3fd700ec61958fcd80cc209f15155c5bb16c4831a4759027a22e78389146818862209c503f6459df2d2db4228217b0e21f9f12b329e8d22841b044dbe2767bd407a2b033160680b928838097f89d63ed19f1091afe467f7589ae927373d56c82f9ea926ecc0238cb474676d22fe0aa3c1bd858570497fc467dd021c3764b27d84562f7420f320a8feea1d542e277280f5f65c637b8282c5bb8a1a1d566cc106ff26227f99fdb91df11bb7f98fc6313555ce21ea43c2492894329523473e58c74371cba40a0fec683cfb990c158f09eb2bf9166da0028b525f053c59ec00e4c5f79b014ce15a5accb1e0a02f60e6f416b53448f451cf44a7e892fdd4052abd92d30965f7716bb03b418e8b133f1a9116ba9fdd88621a1aa84932c67b5e0538f0980a6981bc946b4337c92fd91cd60ec4d2f116ad1ed7ea06cead4257255c9321c36fa6f53fc4d18df23f5f94c2662492982f93e1fa0277ac162fe145ebaf3c9c123e1c496bbaeca45b135b0c30f2b56d0a7692588bf8ec26406cf983e91f167f2a9bd8e8ffac9fcc704d8814352ec491e6cf00dbb388870dfcd8a126a50021dbb4b76da75d57277bf13d0b38c387bd4f84a333d0ad1e07420be83c6be593c23e34d3c7a626f90e11714cb98f4e4dc23daad01cd1a41580fba7c7f89dec325f240baaf9799d4ac99e983f9657219d011121e29b07e88dec8b1aea7b79466abd90518230dd4256fd8f3bf56ae1bf526daa41de9f3b4c82d5ff9efccc7a074c510d76748dd087431ebf9e96e7b626ef66a89a8c23383cd35f7b5d08e87fea79354431e30c30ce10ff9dc5acc6db3e084384343903aee579204182f061baa646f258ff3aa62d22172eb5ddabe45a17168db2fe5a051b6385967eab9cff2d4d065dcdc2142938e23caa54bf27b70f9a0710ae7499d817bd0937468e01130f874f93c988cb237b8c378bb0ec5d4a9b4466452e951a0a542cd736d28f9000368040ee7d53ac25651c1053508f145f92bef1a06c5301a702cc5aa0c1943089879878863f5413f18410942cb1517e1396d4dfa3f7b532566e3ac80612f422b2c9d5fed25381f786fa0ea79280921e532b997efcc1e5e13ffff5de30501eaea228c50004d90ad6f8e5604cf47e24d025558675ce07f007be3207ad9f7d4deeb89eb1f5267190baa3f7c663cb05d71c6a869976a259c2c2b70938dc922c87781bfebeb850d30b9a62a007ffca68b9bdc165565e3b2c14a9b36f09e46bc583ab14b5a8140cd1a6ec4d5c71115ceb3e37e82d803c3ad11bb134eb63899c33d6c98b0992ef6b7b9a552f3ddd812d467fdbf1f3af167c9c492d4360b425fc2ae2a8ab9997efb077174ac280770e72752bf16f7db0a2d6842387b392950185789f748130a9d67797fdc6d26cfac556ea08a3e14e084efe0a1df703eb8084994bf372939b8c9f80cc70b90f1627280653811e1253612b7bf0bed43dfd74636195f9a94066a17906b98fbb0979cd5d64d24a98618eab2254fb8eae726fb58a184ae6fdcd536709dd3338f3537e3ea1122c8b61518643c0f80c02fc15778efd297e36cf2a83fef59b2af9bea6d90a0057cc23773d28b2fd42a9122679aa858294f4739695be481b0ea5354b146119ad2a5b6ce3626c1447ee7768133afe7eb929a08613a1ca50614c247ce091d5f5b87a4702b8674e7ae850b6c26155d31c009c608dde266854a801bd4c73f68ee97d52c2475c4c5636e0e83863a2672e0a4f95d6875d0dcc10395d77dd11a6b448330ebd65dce4ec66cb430a55848bdc3c06738eb2c27aa24ef55722175a38ac2ef599ed346016a5db3c85a7c791607acc4e8bdca219032ed224648a3dddbab450deec0acb8ea7a2313afb5d40e386de05695cbd2a6e51e2fe4fb02ce8e4f41b5d2a4128cabd448c023e88a4fc1826cffd5d837c7236b6eb3b60353b1557e8ce7e7cdb5e7f8238a5db490ea5639e93a46778a6d64b4792ccad63f6b0aa3b05ff7e1347810a0ce553f58867b278bab4be3089be6fdae1eaf89e7d6e4b4141fcd33b87e0f3461aad9bb619791845c7bddcf9224b170ad3583b870b53634074e7f40524451925d21c39a35d7ba0c6a4c3c6d3f9fbcfbce04c3fd300cf91b63d981b6eceed8dfe26503395e075a9bfaf18b4e5e6725c187e86a338d9f149ed6b80d7d7b81b4f9ed108fa4843de62b685ea6162e8dd45b64c48d5ab6a9ae5c37142a077f1102e45d1941e4f506f0da83460d91dc3e12deef9bcb4945247cca64bd79780449475012b3084e6a6d442667df14199a2cc6eee54e6f39766087244c0d829aa2b1e83ac98f347910c5b106fea8fd9b4de3ea7954e5fafde3362414deaa1f864d24403c92be0d0db3504dd749445a9e5c345be9274a2cbc8a32a7c0839c6c1d5f30e0770cf048fd915d6dfa4212e2bbc1a56d93810a371b491fec13d46c13013dea5dcb3aca37cd193d79d8055613ddf3cca72f041799c282c584b0206fded0000',
    amount: 100000,
    asset: '144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49',
  };

  const alice = {
    payment: {
      output: Buffer.from(convertAddressToScript(addressAlice.address), 'hex'),
      blindkey: addressAlice.keys.publicKey,
    },
    keys: addressAlice.keys,
    blindingKeys: [addressAlice.keys.privateKey],
  };

  const aliceInputData = {
    hash: Buffer.from(unspentConfidential.txid, 'hex').reverse(),
    index: unspentConfidential.vout, // index of utxo
    nonWitnessUtxo: unspentConfidential.txHex,
  };

  const inputs = [aliceInputData].map(({ hash, index }) => {
    const txid = hash
      .slice()
      .reverse()
      .toString('hex');
    return new liquid.CreatorInput(txid, index);
  });

  const outputs = [
    new liquid.CreatorOutput(
      unspentConfidential.asset,
      97000,
      alice.payment.output,
      alice.payment.blindkey,
      0,
    ),
    new liquid.CreatorOutput(lbtc, 1000),
  ];

  const zkpLib = await secp256k1();

  const pset = liquid.Creator.newPset({ inputs, outputs });
  const updater = new liquid.Updater(pset);

  updater.addInNonWitnessUtxo(0, liquid.Transaction.fromHex(aliceInputData.nonWitnessUtxo));
  updater.addInSighashType(0, liquid.Transaction.SIGHASH_ALL);

  const zkpValidator = new liquid.ZKPValidator(zkpLib);
  const zkpGenerator = new liquid.ZKPGenerator(
    zkpLib,
    liquid.ZKPGenerator.WithBlindingKeysOfInputs(alice.blindingKeys),
  );

  updater.addInIssuance(0, {
    assetAmount: 1000,
    assetAddress: addressAlice.confidentialAddress,
    blindedIssuance: true,
    contract: {
      entity: {
        domain: 'www.testbtset.com',
      },
      issuer_pubkey: addressAlice.confidentialAddress,
      name: 'TESTBTSET',
      precision: 0, // NFT
      ticker: 'TESTBTSET',
      version: 1.0,
      collection: 'test-btset-collection',
    },
  });

  const issuanceBlindingArgs = zkpGenerator.blindIssuances(pset, {
    0: alice.blindingKeys[0],
  });

  const ownedInputs = zkpGenerator.unblindInputs(pset);
  const outputBlindingArgs = zkpGenerator.blindOutputs(pset, liquid.Pset.ECCKeysGenerator(ecc));
  const blinder = new liquid.Blinder(pset, ownedInputs, zkpValidator, zkpGenerator);
  blinder.blindLast({ issuanceBlindingArgs, outputBlindingArgs });
  const rawTx = signTransaction(pset, [alice.keys], liquid.Transaction.SIGHASH_ALL);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions