forked from provable-things/liquidjs-lib
-
Notifications
You must be signed in to change notification settings - Fork 16
Open
Description
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
Labels
No labels