This is a library, written in Rust, for serialization & deserialization of data structures used in Cardano's Haskell implementation of Alonzo along with useful utility functions.
I got this error when inputs is more than one after the Vasil (@emurgo/cardano-serialization-lib-nodejs v10->v11)
It was caught by txBuilder.add_change_if_needed(shelleyChangeAddress);
node_modules/@emurgo/cardano-serialization-lib-nodejs/cardano_serialization_lib.js:22275
throw takeObject(r1);
^
Insufficient input in transaction. shortage: {ada in inputs: 23032172179, ada in outputs: 72562186029, fee 164401
NOTE! "ada in inputs" must be >= ("ada in outputs" + fee) before adding change
and "ada in inputs" must be == ("ada in outputs" + fee) after adding change
}
From the perspective of error, only one input is used when comparing values. Is there a problem with my set input usage
This error is urgent for me. Please check it for me as soon as possible. Thank you!
Here is all my code:
const parse_address = (address) => {
// console.log('parse address:', address)
let addr = '';
try {
addr = CardanoWasm.Address.from_bech32(address);
return addr;
} catch (e) {
}
try {
addr = CardanoWasm.ByronAddress.from_base58(address).to_address();
return addr;
} catch (e) {
}
console.error('invalid address')
return false;
}
const set_vins = (txBuilder, vins) => {
for (let index in vins) {
let item = vins[index];
const transactionHash = CardanoWasm.TransactionHash.from_bytes(Buffer.from(item.hash, 'hex'));
const transactionInput = CardanoWasm.TransactionInput.new(transactionHash, item.index);
const amountBigNum = CardanoWasm.BigNum.from_str(item.amount);
console.log(item.amount,item.address)
const value = CardanoWasm.Value.new(amountBigNum);
if (item.tokens && item.tokens.length > 0) {
console.log('in token ')
const multiAsset = CardanoWasm.MultiAsset.new();
for (const token of item.tokens) {
const name = CardanoWasm.AssetName.new(Buffer.from(token.name, 'hex'));
const asset = CardanoWasm.Assets.new();
asset.insert(name, CardanoWasm.BigNum.from_str(token.amount));
const sHash = CardanoWasm.ScriptHash.from_bytes(Buffer.from(token.ScriptHash, 'hex'));
multiAsset.insert(sHash, asset);
}
value.set_multiasset(multiAsset);
}
let addr;
if (CardanoWasm.ByronAddress.is_valid(item.address)) {
console.log('ByronAddress')
addr = CardanoWasm.ByronAddress.from_base58(item.address);
txBuilder.add_bootstrap_input(addr, transactionInput, value);
} else {
console.log('not ByronAddress')
addr = CardanoWasm.Address.from_bech32(item.address);
// txBuilder.add_input(addr, transactionInput, value);
let inputBuilder = CardanoWasm.TxInputsBuilder.new();
inputBuilder.add_input(addr, transactionInput, value);
txBuilder.set_inputs(inputBuilder);
}
addr.free();
transactionHash.free();
transactionInput.free();
amountBigNum.free();
value.free();
}
return txBuilder;
}
const set_vouts = (txBuilder, vouts) => {
for (let index in vouts) {
let item = vouts[index];
let addr;
if (CardanoWasm.ByronAddress.is_valid(item.address)) {
addr = CardanoWasm.ByronAddress.from_base58(item.address).to_address();
} else {
addr = CardanoWasm.Address.from_bech32(item.address);
}
const amountBigNum = CardanoWasm.BigNum.from_str(item.amount);
const value = CardanoWasm.Value.new(amountBigNum);
if (item.tokens && item.tokens.length > 0) {
const multiAsset = CardanoWasm.MultiAsset.new();
for (const token of tokens) {
const name = CardanoWasm.AssetName.new(Buffer.from(token.name, 'hex'));
const asset = CardanoWasm.Assets.new();
asset.insert(name, CardanoWasm.BigNum.from_str(token.amount));
const sHash = CardanoWasm.ScriptHash.from_bytes(Buffer.from(token.ScriptHash, 'hex'));
multiAsset.insert(sHash, asset);
}
value.set_multiasset(multiAsset);
}
const transactionOutput = CardanoWasm.TransactionOutput.new(addr, value);
txBuilder.add_output(transactionOutput);
addr.free();
amountBigNum.free();
value.free();
transactionOutput.free();
}
return txBuilder;
}
const set_witnesses = (witnesses, vins, tx_hash) => {
const vkeyWitnesses = CardanoWasm.Vkeywitnesses.new();
let existed_in = {};
for (let index in vins) {
console.log('set_witnesses',index)
let item = vins[index];
if (existed_in[item.address]) {
console.log('same input address');
continue;
}
existed_in[item.address] = 1;
let prvKey = CardanoWasm.PrivateKey.from_bech32(item.private_key);
// add keyhash witnesses
const vkeyWitness = CardanoWasm.make_vkey_witness(tx_hash, prvKey); //PrivateKey
vkeyWitnesses.add(vkeyWitness);
}
witnesses.set_vkeys(vkeyWitnesses);
return witnesses;
}
/**
*
* @param data object
* @returns string
*/
const buildTX = (data) => {
if (!data.vins
|| !data.vins.length
|| !data.vouts
) {
console.error('invalid data input')
return false;
}
// instantiate the tx builder with the Cardano protocol parameters - these may change later on
let txBuilder = CardanoWasm.TransactionBuilder.new(
CardanoWasm.TransactionBuilderConfigBuilder.new()
//static new(coefficient: BigNum, constant: BigNum): LinearFee;
.fee_algo(CardanoWasm.LinearFee.new(CardanoWasm.BigNum.from_str('44'), CardanoWasm.BigNum.from_str('155381')))
.pool_deposit(CardanoWasm.BigNum.from_str('500000000'),)
.key_deposit(CardanoWasm.BigNum.from_str('2000000'),)
.coins_per_utxo_word(CardanoWasm.BigNum.from_str('34482'))
.max_value_size(5000)
.max_tx_size(16384)
.build()
);
console.log(1)
txBuilder = set_vins(txBuilder, data.vins);
console.log(2)
txBuilder = set_vouts(txBuilder, data.vouts);
console.log(3)
// change address
const shelleyChangeAddress = parse_address(data.change_address)
console.log(4)
// set the time to live - the absolute slot value before the tx becomes invalid
txBuilder.set_ttl(data.tx_TTL);
console.log(5)
// calculate the min fee required and send any change to an address
txBuilder.add_change_if_needed(shelleyChangeAddress);
console.log(6)
// once the transaction is ready, we build it to get the tx body without witnesses
const txBody = txBuilder.build();
const txHash = CardanoWasm.hash_transaction(txBody);
let witnesses = CardanoWasm.TransactionWitnessSet.new();
console.log(7)
witnesses = set_witnesses(witnesses, data.vins, txHash)
// create the finalized transaction with witnesses
const transaction = CardanoWasm.Transaction.new(
txBody,
witnesses,
undefined, // transaction metadata
);
const txSignedHex = Buffer.from(transaction.to_bytes()).toString("hex");
console.log('txSignedHex : ' + txSignedHex);
return (txSignedHex);
};
buildTX({
"vins": [{
"private_key": "222",
"address": "addr1vxy53esg0d875y4y2p7mh025pl7eta67q8u8nz0j053j8ygk556av",
"hash": "3bf958d53268ba20adae45c303590e2cedbdcc174bd155b3354d50ed917f1e59",
"amount": "72000000000",
"index": "0",
"tokens": []
}, {
"private_key": "222",
"address": "addr1v8t7t27gfjd8lc4wujpvstuv7k8ws6x58jhktdp2lpp0tzqr5fu0t",
"hash": "0f2c5ac6d40189b8203f29947f1ab63885f99a8b496af283d9f4741afc94f32c",
"amount": "23032172179",
"index": "1",
"tokens": []
}],
"vouts": [{
"address": "addr1vy0vup8cethyvgj6cc8m2ewmmn9zdy5zc9j0g40eppvmatgqqugae",
"amount": "72562186029",
"tokens": []
}],
"tx_TTL": "68093976",
"change_address": "addr1v83dz76q0c26n0esj3nh7367twll9m2g7nc4uqmzqkr49gsvhys4l"
});
I got this error when inputs is more than one after the Vasil (@emurgo/cardano-serialization-lib-nodejs v10->v11) It was caught by
txBuilder.add_change_if_needed(shelleyChangeAddress);
From the perspective of error, only one input is used when comparing values. Is there a problem with my set input usage This error is urgent for me. Please check it for me as soon as possible. Thank you! Here is all my code: