UNPKG

thebigguy-contract

Version:

A library to generate P2SH scripts and create spend transactions for permissionless share-based distribution of UTXOs

61 lines 2.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createOutputs = createOutputs; const ecash_lib_1 = require("ecash-lib"); const script_1 = require("./script"); /** * Calculates the only list of outputs that will be valid for a transaction * that spends `value` from an outpoint locked with `script`. * * @param value The input value being split * @param fee The same fee used for the contract script * @param contract The P2SH contract script generated with the same fee and parsties * @param parties The same parties used for the contract script * * @returns The list of transaction outputs that must be in a transaction that * spends the given value, in an output locked by the contract script. */ function createOutputs(value, fee, contract, parties) { const outputValue = value - fee; const outputs = []; // check for minimally encoding errors in script math // // eCash script math opcodes only support 32-bit numbers. Since numbers are // signed this means that the maximum value that can be directly used must // be no greater than 0x7fffffff. // if (value > 0x7fffffff) { // the share math won't work so the script detects than and validates that // all outputs are back to the contract and the values add up const contractP2sh = ecash_lib_1.Script.p2sh((0, ecash_lib_1.shaRmd160)(contract.bytecode)); // splitting in half is the simplest way to get to validatable utxos const halfValue = (0, script_1.quotient)(outputValue, 2); // this ensures that input = fee + output1 + output2, when input is odd outputs.push({ sats: BigInt(outputValue - halfValue), script: contractP2sh }); outputs.push({ sats: BigInt(halfValue), script: contractP2sh }); } else { // the share math will work so the script will validate output amounts // based on the contract shares and a unit of 1/1000th of the output value const valueUnit = (0, script_1.quotient)(outputValue, 1000); // add one output per party... for (let i = 0; i < parties.length; i++) { const party = parties[i]; const partyValue = party.share * valueUnit; // ... but skip values below dust if (partyValue < 546) { continue; } outputs.push({ sats: BigInt(partyValue), script: ecash_lib_1.Script.fromAddress(party.address) }); } // if no party got a share, then add the expected OP_RETURN if (outputs.length == 0) { outputs.push({ sats: BigInt(0), script: script_1.SCRIPT_NOPAY }); } } return outputs; } //# sourceMappingURL=payment.js.map