Closed r-anjirabi closed 1 year ago
finally it solved, thanks to NBitcoin. share my solution:
`public async Task<string> MakePayment(string walletName, string receiverAddress, decimal amount)
{
var network = Settings.Network == BitcoinNetwork.TestNet ? Network.TestNet : Network.Main;
var hsmWallet = HSMWallet.Load(walletName, Session);
var pubKey = new NBitcoin.PubKey(hsmWallet.PubKey.RawPubKey);
var destination = BitcoinAddress.Create(receiverAddress, network);
var sender = pubKey.GetAddress(ScriptPubKeyType.Legacy, network).ToString();
var unspentCoins = GetUnSpentCoins(sender, network) ?? throw new Exception("no more mony to spend!");
var builder = network.CreateTransactionBuilder();
var unsignedTx = builder
.AddCoins(unspentCoins)
.Send(destination.ScriptPubKey, Money.Coins(amount))
.SendEstimatedFees(new FeeRate(2m))
.SetChange(pubKey)
.BuildTransaction(sign: false);
var rebuild = network.CreateTransactionBuilder();
rebuild.AddCoins(unspentCoins);
foreach (var coin in unspentCoins)
{
var indexedIn = unsignedTx.Inputs.FindIndexedInput(coin.Outpoint);
if (indexedIn == null) continue;
var signHash = indexedIn.GetSignatureHash(coin, SigHash.All);
var sign = hsmWallet.SignTransaction(signHash.ToBytes());
var signature = new TransactionSignature(sign, SigHash.All).MakeCanonical();
rebuild.AddKnownSignature(pubKey, signature, coin.Outpoint);
}
var signedTx = rebuild.SignTransaction(unsignedTx);
var error = rebuild.Check(signedTx);
var verify = rebuild.Verify(signedTx);
if (verify)
{
var result = await BroadcastTransaction(signedTx.ToHex(), Settings.BlockcypherToken, network);
return signedTx.GetHash().ToString();
}
return string.Concat(error.Select(e => e.ToString()), ",");
}
sign method :
public byte[] SignTransaction(byte[] signHash)
{
var mechanism = Session.Factories.MechanismFactory.Create(CKM.CKM_ECDSA);
var signature = Session.Sign(mechanism, PrivateKeyHandle, signHash);
Session.Verify(mechanism, PublicKeyHandle, signHash, signature, out bool isValid);
if (isValid == false)
throw new Exception("error in signing transaction!");
return ConstructEcdsaSigValue(signature);
}
I have implemented signing transactions with HSM as a private key storage, but i encounter some errors!
`
var network = Network.TestNet;
check method
(builder.Check(tx))
i get two errors :i use PKCS11Introp.Net and connect to Utimaco HSM for generate key pair and signing operation:
` public string SignTransaction(string hex) { var mechanism = Session.Factories.MechanismFactory.Create(CKM.CKM_ECDSA);
How can I make this work? Thanks a lot