createDRTransaction function
Future
createDRTransaction(
- DataRequestOutput dataRequestOutput,
- WitPrivateKey privateKey,
- Address? changeAddress,
- dynamic networkSource,
- FeeType feeType,
- UtxoSelectionStrategy utxoStrategy, [
- int fee = 0,
Implementation
Future<dynamic> createDRTransaction(
DataRequestOutput dataRequestOutput,
WitPrivateKey privateKey,
Address? changeAddress,
dynamic networkSource,
FeeType feeType,
UtxoSelectionStrategy utxoStrategy,
[int fee = 0]) async {
List<Input> inputs = [];
List<ValueTransferOutput> outputs = [];
// value owed from the data request
int droValue =
dataRequestOutput.witnesses * dataRequestOutput.witnessReward.toInt();
int amountOwed = droValue;
print('Total Witness Reward -> $droValue');
dataRequestOutput;
Address signerAddress = Address.fromAddress(privateKey.publicKey.address);
// if the changeAddress param is left blank send the change to the signer
Address _changeAddress = changeAddress ?? signerAddress;
await signerAddress.getUtxoInfo(source: networkSource);
List<Utxo> utxoPool = signerAddress.utxoPool!.sortUtxos(utxoStrategy);
int totalUtxoValue = 0;
utxoPool.forEach((utxo) {
totalUtxoValue += utxo.value;
});
if (utxoPool.isEmpty) {
return TransactionError(-1, 'Insufficient funds.');
}
assert(totalUtxoValue > amountOwed, 'Insufficient funds.');
List<Utxo> selectedUtxos = [];
int selectedUtxoValue = 0;
switch (feeType) {
case FeeType.Absolute:
amountOwed += fee;
var _outputValue = amountOwed;
while (_outputValue > 0) {
Utxo utxo = utxoPool.first;
utxoPool.removeAt(0);
selectedUtxos.add(utxo);
_outputValue -= utxo.value;
}
selectedUtxos.forEach((Utxo utxo) {
inputs.add(utxo.toInput());
selectedUtxoValue += utxo.value;
});
int change = selectedUtxoValue - amountOwed;
if (change > 0) {
outputs.add(_changeAddress.receive(change));
}
break;
case FeeType.Weighted:
// get utxos to cover the base value before weight
var _outputValue = amountOwed;
while (_outputValue > 0) {
Utxo utxo = utxoPool.first;
utxoPool.removeAt(0);
selectedUtxos.add(utxo);
_outputValue -= utxo.value;
}
selectedUtxos.forEach((Utxo utxo) {
inputs.add(utxo.toInput());
selectedUtxoValue += utxo.value;
});
int change = selectedUtxoValue - amountOwed;
int inputCount = inputs.length;
int outputCount = outputs.length;
int droWeight = dataRequestOutput.weight;
int droExtraWeight = dataRequestOutput.extraWeight;
// estimate at least 1 output, currently zero in the list
int currentWeight =
drWeight(inputCount, outputCount + 1, droWeight, droExtraWeight);
if (currentWeight == change) {
} else if (currentWeight < change) {
outputs.add(_changeAddress.receive(change - currentWeight));
} else {}
break;
}
DRTransactionBody body = DRTransactionBody(
inputs: inputs, outputs: outputs, drOutput: dataRequestOutput);
DRTransaction transaction = DRTransaction(body: body, signatures: []);
KeyedSignature signature =
signerAddress.signHash(transaction.transactionID, privateKey);
for (int i = 0; i < transaction.body.inputs.length; i++) {
transaction.signatures.add(signature);
}
return transaction;
}