mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00

* Add fee estimation to wallet * Add fee rate to kaspawallet parse * Update go version * Get rid of golint * Add RBF support to wallet * Fix bump_fee UTXO lookup and fix wrong change address * impl storage mass as per KIP9 * Use CalculateTransactionOverallMass where needed * Some fixes * Minor typos * Fix test * update version * BroadcastRBF -> BroadcastReplacement * rc3 * align proto files to only use camel case (fixed on RK as well) * Rename to FeePolicy and add MaxFee option + todo * apply max fee constrains * increase minChangeTarget to 10kas * fmt * Some fixes * fix description: maximum -> minimum * put min feerate check in the correct location * Fix calculateFeeLimits nil handling * Add validations to CLI flags * Change to rc6 * Add checkTransactionFeeRate * Add failed broadcast transactions on send error` * Fix estimateFee change value * Estimate fee correctly for --send-all * On estimateFee always assume that the recipient has ECDSA address * remove patch version --------- Co-authored-by: Michael Sutton <msutton@cs.huji.ac.il>
106 lines
3.5 KiB
Go
106 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"strings"
|
|
|
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/daemon/server"
|
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/keys"
|
|
"github.com/kaspanet/kaspad/cmd/kaspawallet/libkaspawallet/serialization"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/txscript"
|
|
"github.com/kaspanet/kaspad/util/txmass"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func parse(conf *parseConfig) error {
|
|
if conf.Transaction == "" && conf.TransactionFile == "" {
|
|
return errors.Errorf("Either --transaction or --transaction-file is required")
|
|
}
|
|
if conf.Transaction != "" && conf.TransactionFile != "" {
|
|
return errors.Errorf("Both --transaction and --transaction-file cannot be passed at the same time")
|
|
}
|
|
|
|
keysFile, err := keys.ReadKeysFile(conf.NetParams(), conf.KeysFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
transactionHex := conf.Transaction
|
|
if conf.TransactionFile != "" {
|
|
transactionHexBytes, err := ioutil.ReadFile(conf.TransactionFile)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "Could not read hex from %s", conf.TransactionFile)
|
|
}
|
|
transactionHex = strings.TrimSpace(string(transactionHexBytes))
|
|
}
|
|
|
|
transactions, err := server.DecodeTransactionsFromHex(transactionHex)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
txMassCalculator := txmass.NewCalculator(conf.NetParams().MassPerTxByte, conf.NetParams().MassPerScriptPubKeyByte, conf.NetParams().MassPerSigOp)
|
|
for i, transaction := range transactions {
|
|
|
|
partiallySignedTransaction, err := serialization.DeserializePartiallySignedTransaction(transaction)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Transaction #%d ID: \t%s\n", i+1, consensushashing.TransactionID(partiallySignedTransaction.Tx))
|
|
fmt.Println()
|
|
|
|
allInputSompi := uint64(0)
|
|
for index, input := range partiallySignedTransaction.Tx.Inputs {
|
|
partiallySignedInput := partiallySignedTransaction.PartiallySignedInputs[index]
|
|
|
|
if conf.Verbose {
|
|
fmt.Printf("Input %d: \tOutpoint: %s:%d \tAmount: %.2f Kaspa\n", index, input.PreviousOutpoint.TransactionID,
|
|
input.PreviousOutpoint.Index, float64(partiallySignedInput.PrevOutput.Value)/float64(constants.SompiPerKaspa))
|
|
}
|
|
|
|
allInputSompi += partiallySignedInput.PrevOutput.Value
|
|
}
|
|
if conf.Verbose {
|
|
fmt.Println()
|
|
}
|
|
|
|
allOutputSompi := uint64(0)
|
|
for index, output := range partiallySignedTransaction.Tx.Outputs {
|
|
scriptPublicKeyType, scriptPublicKeyAddress, err := txscript.ExtractScriptPubKeyAddress(output.ScriptPublicKey, conf.ActiveNetParams)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
addressString := scriptPublicKeyAddress.EncodeAddress()
|
|
if scriptPublicKeyType == txscript.NonStandardTy {
|
|
scriptPublicKeyHex := hex.EncodeToString(output.ScriptPublicKey.Script)
|
|
addressString = fmt.Sprintf("<Non-standard transaction script public key: %s>", scriptPublicKeyHex)
|
|
}
|
|
|
|
fmt.Printf("Output %d: \tRecipient: %s \tAmount: %.2f Kaspa\n",
|
|
index, addressString, float64(output.Value)/float64(constants.SompiPerKaspa))
|
|
|
|
allOutputSompi += output.Value
|
|
}
|
|
fmt.Println()
|
|
|
|
fee := allInputSompi - allOutputSompi
|
|
fmt.Printf("Fee:\t%d Sompi (%f KAS)\n", fee, float64(fee)/float64(constants.SompiPerKaspa))
|
|
mass, err := server.EstimateMassAfterSignatures(partiallySignedTransaction, keysFile.ECDSA, keysFile.MinimumSignatures, txMassCalculator)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Mass: %d grams\n", mass)
|
|
feeRate := float64(fee) / float64(mass)
|
|
fmt.Printf("Fee rate: %.2f Sompi/Gram\n", feeRate)
|
|
}
|
|
|
|
return nil
|
|
}
|