using NBitcoin;
using NBitcoin.DataEncoders;
using Newtonsoft.Json;
using System.Net;
namespace ConsoleApp10
{
public class Raw2Tx
{
public string txid { get; set; }
public uint version { get; set; }
public int locktime { get; set; }
public List<Raw2TxInput> inputs { get; set; }
public List<Raw2TxOutput> outputs { get; set; }
}
public class Raw2TxInput
{
public string txid { get; set; }
public int output { get; set; }
public string sigscript { get; set; }
public uint sequence { get; set; }
public string pkscript { get; set; }
public long value { get; set; }
public string address { get; set; }
public List<string> witness { get; set; }
}
public class Raw2TxOutput
{
public string address { get; set; }
public string pkscript { get; set; }
public long value { get; set; }
public bool spent { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
var tx_hash = "d518d87ad11da17325e3489ea15e1c5c1e1541fd078aa239158dff028e62cdeb";
WebClient webClient = new WebClient();
webClient.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
webClient.Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-CN,zh;q=0.8");
webClient.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0");
var url = $"https://api.blockchain.info/haskoin-store/btc/transaction/{tx_hash}";
var json = webClient.DownloadString(url);
var tx_raw = JsonConvert.DeserializeObject<Raw2Tx>(json);
Transaction tx = Network.Main.CreateTransaction();
tx.Version = tx_raw.version;
tx.LockTime = tx_raw.locktime;
for (int i = 0; i < tx_raw.inputs.Count; i++) {
WitScript witScript = null;
if (tx_raw.inputs[i].witness.Count > 0) {
witScript = new WitScript(string.Join('\t', tx_raw.inputs[i].witness));
}
TxIn txIn = tx.Inputs.CreateNewTxIn(new OutPoint(uint256.Parse(tx_raw.inputs[i].txid), i), new Script(tx_raw.inputs[i].sigscript), witScript, tx_raw.inputs[i].sequence);
tx.Inputs.Add(txIn);
}
for (int i = 0; i < tx_raw.outputs.Count; i++) {
TxOut txOut = tx.Outputs.CreateNewTxOut(new Money(tx_raw.outputs[i].value), new Script(tx_raw.outputs[i].pkscript));
tx.Outputs.Add(txOut);
}
for (int i = 0; i < tx_raw.inputs.Count; i++) {
var scriptCode = new Script(tx_raw.inputs[i].pkscript);
var input = new TxOut(new Money(tx_raw.inputs[i].value), new Script(tx_raw.inputs[i].pkscript));
var message = tx.GetSignatureHash(scriptCode, i, SigHash.All, input, HashVersion.Original);
if (VerifyMessage(i, message, tx_raw)) {
Console.WriteLine("message is " + message);
continue;
}
var message2 = tx.GetSignatureHash(scriptCode, i, SigHash.All, input, HashVersion.WitnessV0);
if (VerifyMessage(i, message2, tx_raw)) {
Console.WriteLine("message is " + message2);
} else {
Console.WriteLine("message is error ");
}
}
}
static bool VerifyMessage(int i, uint256 message, Raw2Tx tx)
{
byte[] bs = Encoders.Hex.DecodeData(tx.inputs[i].sigscript);
BinaryReader binaryReader = new BinaryReader(new MemoryStream(bs));//https://raghavsood.com/blog/2018/06/10/bitcoin-signature-types-sighash
var b1 = binaryReader.ReadByte(); // DER length
var b2 = binaryReader.ReadByte();//30 # DER Sequence tag
var b3 = binaryReader.ReadByte();//44 # Sequence length 0x44 (68) bytes
var b4 = binaryReader.ReadByte();//02 # Integer element
var len = (int)binaryReader.ReadByte();//20 # Element length 0x20 (32) bytes
var R = binaryReader.ReadBytes(len); //# ECDSA r value
var b5 = binaryReader.ReadByte();// 02 # Integer element
len = (int)binaryReader.ReadByte(); //20 # Element length 0x20 (32) bytes
var S = binaryReader.ReadBytes(len); //# ECDSA s value
var b6 = binaryReader.ReadByte(); // # SIGHASH flag
if (binaryReader.BaseStream.Position == bs.Length) {
// P2PK https://bitcoin.stackexchange.com/questions/73758/what-are-the-standard-formats-of-transaction-outputs
// PUSH (1 byte) + <compressed/uncompressed_pk> (33/65 bytes) + OP_CHECKSIG (1 byte)
byte[] bs2 = Encoders.Hex.DecodeData(tx.inputs[i].pkscript);
binaryReader = new BinaryReader(new MemoryStream(bs2));
}
var b7 = binaryReader.ReadByte();
var type = binaryReader.ReadByte();
byte[] X, Y;
if (type == 4) {
X = binaryReader.ReadBytes(32);
Y = binaryReader.ReadBytes(32);
} else if (type == 2) { // Even y-coordinate
X = binaryReader.ReadBytes(32);
} else if (type == 3) {// Odd y-coordinate
X = binaryReader.ReadBytes(32);
}
// TODO:
return false;
}
}
}
Currently, there is still a lack of verification code. Could you please help me write the remaining code.
How to use NBitcoin to verify historical tx transactions data?
data sources: https://api.blockchain.info/haskoin-store/btc/transaction/d518d87ad11da17325e3489ea15e1c5c1e1541fd078aa239158dff028e62cdeb
The partial completion code is as follows
Currently, there is still a lack of verification code. Could you please help me write the remaining code.