public static StealthPayment[] GetPayments(Transaction transaction, PubKey[] spendKeys, BitField bitField, Key scan) { List<StealthPayment> result = new List<StealthPayment>(); for(int i = 0 ; i < transaction.Outputs.Count ; i++) { var metadata = StealthMetadata.TryParse(transaction.Outputs[i].ScriptPubKey); if(metadata != null && bitField.Match(metadata.BitField)) { var payment = new StealthPayment(transaction.Outputs[i + 1].ScriptPubKey, metadata); if(scan != null && spendKeys != null) { if(payment.StealthKeys.Length != spendKeys.Length) continue; var expectedStealth = spendKeys.Select(s => s.UncoverReceiver(scan, metadata.EphemKey)).ToList(); foreach(var stealth in payment.StealthKeys) { var match = expectedStealth.FirstOrDefault(expected => expected.ID == stealth.ID); if(match != null) expectedStealth.Remove(match); } if(expectedStealth.Count != 0) continue; } result.Add(payment); } } return result.ToArray(); }
public static StealthMetadata CreateMetadata(Key ephemKey, BitField bitField = null) { for(uint nonce = 0 ; nonce < uint.MaxValue ; nonce++) { var metadata = new StealthMetadata(ephemKey, nonce); if(bitField == null || bitField.Match(metadata.BitField)) return metadata; } throw new ArgumentException("No nonce can satisfy the given bitfield, use another ephemKey"); }
public BitcoinStealthAddress(PubKey scanKey, PubKey[] pubKeys, int signatureCount, BitField bitfield, Network network) : base(GenerateBytes(scanKey, pubKeys, bitfield, signatureCount), network) { }
private static byte[] GenerateBytes(PubKey scanKey, PubKey[] pubKeys, BitField bitField, int signatureCount) { MemoryStream ms = new MemoryStream(); ms.WriteByte(0); //Options ms.Write(scanKey.Compress().ToBytes(), 0, 33); ms.WriteByte((byte)pubKeys.Length); foreach(var key in pubKeys) { ms.Write(key.Compress().ToBytes(), 0, 33); } ms.WriteByte((byte)signatureCount); if(bitField == null) ms.Write(new byte[] { 0 }, 0, 1); else { ms.WriteByte((byte)bitField.BitCount); var raw = bitField.GetRawForm(); ms.Write(raw, 0, raw.Length); } return ms.ToArray(); }