static async Task SignBitcoinTransactionAsync() { //get address path for address in Trezor var addressPath = AddressPathBase.Parse <BIP44AddressPath>("m/49'/0'/0'/0/0").ToArray(); // previous unspent input of Transaction var txInput = new TxInputType() { AddressNs = addressPath, Amount = 100837, ScriptType = InputScriptType.Spendp2shwitness, PrevHash = "3becf448ae38cf08c0db3c6de2acb8e47acf6953331a466fca76165fdef1ccb7".ToBytes(), // transaction ID PrevIndex = 0, Sequence = 4294967293 // Sequence number represent Replace By Fee 4294967293 or leave empty for default }; // TX we want to make a payment var txOut = new TxOutputType() { AddressNs = new uint[0], Amount = 100837, Address = "18UxSJMw7D4UEiRqWkArN1Lq7VSGX6qH3H", ScriptType = OutputScriptType.Paytoaddress // if is segwit use Spendp2shwitness }; // Must be filled with basic data like below var signTx = new SignTx() { Expiry = 0, LockTime = 0, CoinName = "Bitcoin", Version = 2, OutputsCount = 1, InputsCount = 1 }; Log.Information($"TxSignature: {await _soterDevice.SignTransactionAsync(signTx, new List<TxInputType> { txInput }, new List<TxOutputType> { txOut })}"); }
public async Task SignBitcoinTransactionAsync() { // initialize connection with device await GetAndInitialize(); //get address path for address in Trezor var addressPath = AddressPathBase.Parse <BIP44AddressPath>("m/49'/0'/0'/0/0").ToArray(); // previous unspent input of Transaction var txInput = new TxInputType() { AddressNs = addressPath, Amount = 100837, ScriptType = InputScriptType.Spendp2shwitness, PrevHash = "797ad8727ee672123acfc7bcece06bf648d3833580b1b50246363f3293d9fe20".ToHexBytes(), // transaction ID PrevIndex = 0, Sequence = 4294967293 // Sequence number represent Replace By Fee 4294967293 or leave empty for default }; // TX we want to make a payment var txOut = new TxOutputType() { AddressNs = new uint[0], Amount = 100837, Address = "3HN7CbEPY7FiuUKGq51g9e3UegFak1WZb5", ScriptType = OutputScriptType.Paytoaddress // if is segwit use Spendp2shwitness }; // Must be filled with basic data like below var signTx = new SignTx() { Expiry = 0, LockTime = 0, CoinName = "Bitcoin", Version = 2, OutputsCount = 1, InputsCount = 1 }; // For every TX request from Trezor to us, we response with TxAck like below var txAck = new TxAck() { Tx = new TransactionType() { Inputs = { txInput }, // Tx Inputs Outputs = { txOut }, // Tx Outputs Expiry = 0, InputsCnt = 1, // must be exact number of Inputs count OutputsCnt = 1, // must be exact number of Outputs count Version = 2 } }; // If the field serialized.serialized_tx from Trezor is set, // it contains a chunk of the signed transaction in serialized format. // The chunks are returned in the right order and just concatenating all returned chunks will result in the signed transaction. // So we need to add chunks to the list var serializedTx = new List <byte>(); // We send SignTx() to the Trezor and we wait him to send us Request var request = await KeepKeyManager.SendMessageAsync <TxRequest, SignTx>(signTx); // We do loop here since we need to send over and over the same transactions to trezor because his 64 kilobytes memory // and he will sign chunks and return part of signed chunk in serialized manner, until we receive finall type of Txrequest TxFinished while (request.RequestType != RequestType.Txfinished) { switch (request.RequestType) { case RequestType.Txinput: { //We send TxAck() with TxInputs request = await KeepKeyManager.SendMessageAsync <TxRequest, TxAck>(txAck); // Now we have to check every response is there any SerializedTx chunk if (request.Serialized != null) { // if there is any we add to our list bytes serializedTx.AddRange(request.Serialized.SerializedTx); } break; } case RequestType.Txoutput: { //We send TxAck() with TxOutputs request = await KeepKeyManager.SendMessageAsync <TxRequest, TxAck>(txAck); // Now we have to check every response is there any SerializedTx chunk if (request.Serialized != null) { // if there is any we add to our list bytes serializedTx.AddRange(request.Serialized.SerializedTx); } break; } case RequestType.Txextradata: { // for now he didn't ask me for extra data :) break; } case RequestType.Txmeta: { // for now he didn't ask me for extra Tx meta data :) break; } } } Debug.WriteLine($"TxSignature: {serializedTx.ToArray().ToHexCompact()}"); }