public static T Pair <T>(T left, T right) where T : IMerkleTreeNode <T> { if (left.Depth != right.Depth) { throw new InvalidOperationException(); } if (!left.Pruned) { throw new ArgumentException("left"); } if (!right.Pruned) { throw new ArgumentException("right"); } var expectedIndex = left.Index + (1 << left.Depth); if (right.Index != expectedIndex) { throw new InvalidOperationException(); } var pairHashBytes = new byte[64]; left.Hash.ToByteArray(pairHashBytes, 0); right.Hash.ToByteArray(pairHashBytes, 32); var pairHash = new UInt256(SHA256Static.ComputeDoubleHash(pairHashBytes)); return(left.AsPruned(left.Index, left.Depth + 1, pairHash)); }
// IBlockTxesStorage.TryGetTransaction private void TestTryGetTransaction(ITestStorageProvider provider) { using (var storageManager = provider.OpenStorageManager()) { var blockTxesStorage = storageManager.BlockTxesStorage; // create a block var block = CreateFakeBlock(); // add block transactions blockTxesStorage.TryAddBlockTransactions(block.Hash, block.BlockTxes); // verify missing transactions BlockTx transaction; Assert.IsFalse(blockTxesStorage.TryGetTransaction(UInt256.Zero, 0, out transaction)); Assert.IsFalse(blockTxesStorage.TryGetTransaction(block.Hash, -1, out transaction)); Assert.IsFalse(blockTxesStorage.TryGetTransaction(block.Hash, block.Transactions.Length, out transaction)); // verify transactions for (var txIndex = 0; txIndex < block.Transactions.Length; txIndex++) { Assert.IsTrue(blockTxesStorage.TryGetTransaction(block.Hash, txIndex, out transaction)); Assert.AreEqual(block.Transactions[txIndex].Hash, transaction.Hash); Assert.AreEqual(transaction.Hash, new UInt256(SHA256Static.ComputeDoubleHash(transaction.TxBytes.ToArray()))); } } }
// IBlockTxesStorage.ReadBlockTransactions private void TestReadBlockTransactions(ITestStorageProvider provider) { using (var storageManager = provider.OpenStorageManager()) { var blockTxesStorage = storageManager.BlockTxesStorage; // create a block var expectedBlock = CreateFakeBlock(); var expectedBlockTxHashes = expectedBlock.Transactions.Select(x => x.Hash).ToList(); // add block transactions blockTxesStorage.TryAddBlockTransactions(expectedBlock.Hash, expectedBlock.BlockTxes); // retrieve block transactions IEnumerator <BlockTx> rawActualBlockTxes; Assert.IsTrue(blockTxesStorage.TryReadBlockTransactions(expectedBlock.Hash, out rawActualBlockTxes)); var actualBlockTxes = rawActualBlockTxes.UsingAsEnumerable().ToList(); var actualBlockTxHashes = actualBlockTxes.Select(x => x.Hash).ToList(); // verify all retrieved transactions match their hashes Assert.IsTrue(actualBlockTxes.All(x => x.Hash == new UInt256(SHA256Static.ComputeDoubleHash(x.TxBytes.ToArray())))); // verify retrieved block transactions match stored block transactions CollectionAssert.AreEqual(expectedBlockTxHashes, actualBlockTxHashes); } }
public void TestUInt256Sha256() { var expected = SHA256Static.ComputeDoubleHash(UInt256.ParseHex(TestData.HEX_STRING_64).ToByteArray()); var actual = new UInt256(expected).ToByteArray(); CollectionAssert.AreEqual(expected, actual); }
public bool VerifySignature(byte[] scriptPubKey, Transaction tx, byte[] sig, byte[] pubKey, int inputIndex, out byte hashType, out byte[] txSignature, out byte[] txSignatureHash) { // get the 1-byte hashType off the end of sig hashType = sig[sig.Length - 1]; // get the DER encoded portion of sig, which is everything except the last byte (the last byte being hashType) var sigDER = sig.Take(sig.Length - 1).ToArray(); // get the simplified/signing version of the transaction txSignature = TxSignature(scriptPubKey, tx, inputIndex, hashType); // get the hash of the simplified/signing version of the transaction txSignatureHash = SHA256Static.ComputeDoubleHash(txSignature); if (this.ignoreSignatures) { return(true); } else { #if SECP256K1_DLL // verify that signature is valid for pubKey and the simplified/signing transaction's hash return(Signatures.Verify(txSignatureHash, sigDER, pubKey) == Signatures.VerifyResult.Verified); #else return(true); #endif } }
public static UInt256 PairHashes(UInt256 left, UInt256 right) { var bytes = new byte[64]; left.ToByteArray(bytes, 0); right.ToByteArray(bytes, 32); return(new UInt256(SHA256Static.ComputeDoubleHash(bytes))); }
public BlockHeader MineBlockHeader(BlockHeader blockHeader, UInt256 hashTarget) { var blockHeaderBytes = DataEncoder.EncodeBlockHeader(blockHeader); var hashTargetBytes = hashTarget.ToByteArray(); var start = 0; var finish = UInt32.MaxValue; var total = 0L; var nonceIndex = 76; var minedNonce = (UInt32?)null; var stopwatch = Stopwatch.StartNew(); Parallel.For( start, finish, () => new LocalMinerState(blockHeaderBytes), (nonceLong, loopState, localState) => { localState.total++; var nonce = (UInt32)nonceLong; var nonceBytes = Bits.GetBytes(nonce); Buffer.BlockCopy(nonceBytes, 0, localState.headerBytes, nonceIndex, 4); var headerBytes = localState.headerBytes; var hashBytes = SHA256Static.ComputeDoubleHash(headerBytes); if (BytesCompareLE(hashBytes, hashTargetBytes) < 0) { minedNonce = nonce; loopState.Stop(); } return(localState); }, localState => { Interlocked.Add(ref total, localState.total); }); stopwatch.Stop(); var hashRate = total / stopwatch.Elapsed.TotalSeconds; if (minedNonce == null) { throw new InvalidOperationException(); } var minedHeader = blockHeader.With(Nonce: minedNonce); logger.Debug($"Found block in {stopwatch.Elapsed.TotalMilliseconds:N3}ms at Nonce {minedNonce}, Hash Rate: {hashRate / 1.MILLION()} mHash/s, Total Hash Attempts: {total:N0}, Found Hash: {minedHeader.Hash}"); return(minedHeader); }
public static BlockHeader DecodeBlockHeader(UInt256 blockHash, byte[] buffer, ref int offset) { var initialOffset = offset; var version = DecodeUInt32(buffer, ref offset); var previousBlock = DecodeUInt256(buffer, ref offset); var merkleRoot = DecodeUInt256(buffer, ref offset); var time = DateTimeOffset.FromUnixTimeSeconds(DecodeUInt32(buffer, ref offset)); var bits = DecodeUInt32(buffer, ref offset); var nonce = DecodeUInt32(buffer, ref offset); blockHash = blockHash ?? new UInt256(SHA256Static.ComputeDoubleHash(buffer, initialOffset, 80)); return(new BlockHeader(version, previousBlock, merkleRoot, time, bits, nonce, blockHash)); }
public static DecodedTx EncodeTransaction(UInt32 Version, ImmutableArray <TxInput> Inputs, ImmutableArray <TxOutput> Outputs, UInt32 LockTime) { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { writer.WriteUInt32(Version); writer.WriteList(Inputs, input => EncodeTxInput(writer, input)); writer.WriteList(Outputs, output => EncodeTxOutput(writer, output)); writer.WriteUInt32(LockTime); var txBytes = stream.ToArray(); var txHash = new UInt256(SHA256Static.ComputeDoubleHash(txBytes)); var tx = new Transaction(Version, Inputs, Outputs, LockTime, txHash); return(new DecodedTx(txBytes.ToImmutableArray(), tx)); } }
public byte[] CreatePrivateKeyScript(Transaction tx, int inputIndex, byte hashType, ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey) { //TODO var scriptEngine = new ScriptEngine(); var publicAddress = CreatePublicAddress(publicKey); var publicKeyScript = CreatePublicKeyScript(publicAddress); var txSignature = scriptEngine.TxSignature(publicKeyScript, tx, inputIndex, hashType); var txSignatureHash = SHA256Static.ComputeDoubleHash(txSignature); //Debug.WriteLine("Signing Tx: {0}".Format2(txSignature.ToHexDataString())); //Debug.WriteLine("Signing Tx Hash: {0}".Format2(txSignatureHash.ToHexDataString())); var signer = new ECDsaSigner(); signer.Init(forSigning: true, parameters: privateKey); var signature = signer.GenerateSignature(txSignatureHash); var r = signature[0]; var s = signature[1]; byte[] sigEncoded; using (var stream = new MemoryStream()) { using (var asn1Stream = new Asn1OutputStream(stream)) { asn1Stream.WriteObject(new DerSequence(new DerInteger(r), new DerInteger(s))); } sigEncoded = stream.ToArray().Concat(hashType); } //Debug.WriteLine("Sig R: {0}".Format2(r.ToHexNumberStringUnsigned())); //Debug.WriteLine("Sig S: {0}".Format2(s.ToHexNumberStringUnsigned())); //Debug.WriteLine("Sig Encoded: {0}".Format2(sigEncoded.ToHexDataString())); using (var privateKeyScript = new ScriptBuilder()) { privateKeyScript.WritePushData(sigEncoded); privateKeyScript.WritePushData(publicAddress); //Debug.WriteLine("Private Script: {0}".Format2(privateKeyScript.GetScript().ToHexDataString())); return(privateKeyScript.GetScript()); } }
public static Transaction DecodeTransaction(UInt256 txHash, byte[] buffer, ref int offset) { var initialOffset = offset; // read version var version = DecodeUInt32(buffer, ref offset); // read inputs var inputs = DecodeTxInputList(buffer, ref offset); // read outputs var outputs = DecodeTxOutputList(buffer, ref offset); // read lockTime var lockTime = DecodeUInt32(buffer, ref offset); txHash = txHash ?? new UInt256(SHA256Static.ComputeDoubleHash(buffer, initialOffset, offset - initialOffset)); return(new Transaction(version, inputs, outputs, lockTime, txHash)); }
public static UInt256 CalculateBlockHash(UInt32 Version, UInt256 PreviousBlock, UInt256 MerkleRoot, DateTimeOffset Time, UInt32 Bits, UInt32 Nonce) { return(new UInt256(SHA256Static.ComputeDoubleHash(DataEncoder.EncodeBlockHeader(Version, PreviousBlock, MerkleRoot, Time, Bits, Nonce)))); }
public static UInt256 CalculateBlockHash(BlockHeader blockHeader) { return(new UInt256(SHA256Static.ComputeDoubleHash(DataEncoder.EncodeBlockHeader(blockHeader)))); }
public static UInt32 CalculatePayloadChecksum(byte[] payload) { return(Bits.ToUInt32(SHA256Static.ComputeDoubleHash(payload))); }