admin管理员组

文章数量:1397093

I have tried a lot and used so many libraries for ZEC fund transfer but always getting an error lets say 16: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element but my UTXO is correct and I researched but did not find something which can be helped. Below is my code.

const Zcash = require('bitcore-lib-zcash');
const axios = require("axios");
const ECPair = require('ecpair');
const ecc = require('tiny-secp256k1');
const bs58 = require('bs58');
const bs58check = require('bs58check');
const ECPairFactory = ECPair.ECPairFactory(ecc);

const _ = require('lodash');
// Make sure lodash.sumBy is available
_.sumBy = _.sumBy || require('lodash/sumBy');

const apiKey = "My API Key";
const endpoint = `/`;
const broadcastEndpoint = '';

const ZEC_MAINNET = {
    messagePrefix: '\x19ZCash Signed Message:\n',
    bech32: 'zs',
    bip32: {
        public: 0x0488b21e,
        private: 0x0488ade4
    },
    pubKeyHash: 0x1c,  // ZCash t-address starts with 't1'
    scriptHash: 0xbd,  // ZCash t-address starts with 't3'
    wif: 0x80
};

async function fundTransfer(senderAddress, senderPrivKey, receiverAddress, amount) {
    try {
        const utxos = await getUTXOs(senderAddress);
        if (!utxos || utxos.length === 0) {
            throw new Error('No UTXOs available for this address');
        }
        console.log("UTXOs available:", utxos.length);

        // Initialize transaction
        const tx = new Zcash.Transaction();

        // Track total input amount
        let totalInput = 0;

        // Process UTXOs
        for (const utxo of utxos) {
            totalInput += utxo.value;

            // Get the complete transaction data to extract the correct scriptPubKey
            const txResponse = await axios.get(
                endpoint.concat(`tx/${utxo.txid}`),
                { headers: { 'api-key': apiKey } }
            );

            // Make sure we're getting the correct vout index
            const scriptPubKey = txResponse.data.vout[utxo.vout].hex;
            console.log("script pub key--", scriptPubKey);

            // Add input with proper parameters
            tx.from({
                txId: utxo.txid,
                outputIndex: utxo.vout,
                address: senderAddress,
                script: scriptPubKey,
                satoshis: Math.floor(utxo.value) // Ensure integer value
            });
        }

        // Calculate amount to send in satoshis - ensure it's an integer
        const satoshiToSend = Math.floor(amount * 1e8);

        // Add recipient output
        tx.to(receiverAddress, satoshiToSend);

        // Set appropriate transaction fee for ZCash
        const fee = 10000; // 0.0001 ZEC

        // Calculate change
        const changeAmount = totalInput - satoshiToSend - fee;

        // Only add change output if it's significant enough
        if (changeAmount > 546) { // Dust threshold
            tx.change(senderAddress);
        }

        // Create private key object correctly
        const privateKey = new Zcash.PrivateKey(senderPrivKey);

        // Use the correct sighash type for ZCash
        // const sighashType = Zcash.crypto.Signature.SIGHASH_ALL;
        const NU6_BRANCH_ID = "c8e71055"; 

        // Sign each input correctly
        for (let i = 0; i < tx.inputs.length; i++) {
            // tx.sign(privateKey, 1);
            tx.sign(privateKey, {
                sighashType: Zcash.crypto.Signature.SIGHASH_ALL,
                branchId: parseInt(NU6_BRANCH_ID, 16) 
            });
        }

        console.log("Has all UTXO info:", tx.hasAllUtxoInfo())

        if (!tx.isFullySigned()) {
            throw new Error('Transaction is not fully signed');
        }
        const rawTx = tx.serialize();

        const broadcastResponse = await axios.post(
            broadcastEndpoint,
            {
                jsonrpc: "1.0",
                id: "curltest",
                method: "sendrawtransaction",
                params: [rawTx]
            },
            { headers: { 'api-key': apiKey } }
        );

        console.log("Transaction broadcast successful");
        return broadcastResponse.data;
    } catch (error) {
        console.error('Error in fundTransfer:', error.response);
        throw new Error(`Failed to complete transaction: ${error.message || JSON.stringify(error)}`);
    }
}


const senderAddress = "t1UaKhHEBirdh22zfqLJkRdKDZPuxA5JL7r"
const senderPrivKey = "My Private Key"
const receiverAddress = "t1eHpWvJeYEVf98w4MiX59eEQNXRCigpPBP"
const amount = "0.0002" // amount in DOGE
fundTransfer(senderAddress, senderPrivKey, receiverAddress, amount)

// const privateKey = new Zcash.PrivateKey('L2E4qNZuP44oAWbrKutsZ1Eqe2GK2De56oBLgWrjtNrtpR5LrDUr');
// const address = privateKey.toAddress();
// console.log("Address from private key:", address.toString());



async function getUTXOs(address) {
    try {
        const response = await axios.get(
            endpoint.concat(`utxo/${address}?confirmed=true`),
            { headers: { 'api-key': apiKey } }
        );

        return response.data;
    } catch (error) {
        console.error('Error fetching UTXOs:', error);
        throw new Error(`Failed to get UTXOs: ${error.message}`);
    }
}

I have also used different library.

本文标签: ZEC (Zcash) fund transfer issueStack Overflow