public bool TryReadBlock(ref SequenceReader <byte> r) { if (!TryReadBlockHeader(ref r)) { goto fail; } if (!r.TryReadVarint(out long count)) { goto fail; } _txs = new KzTransaction[count]; for (var i = 0L; i < count; i++) { var t = new KzTransaction(); _txs[i] = t; if (!t.TryReadTransaction(ref r)) { goto fail; } } if (!VerifyMerkleRoot()) { goto fail; } return(true); fail: return(false); }
public KzBTransaction(KzTransaction tx) { Version = tx.Version; Vin = tx.Vin.Cast <KzBTxIn>().ToList(); Vout = tx.Vout.Cast <KzBTxOut>().ToList(); LockTime = tx.LockTime; HashTx = tx.HashTx; if (HashTx.Value == KzUInt256.Zero) { HashTx = null; } }
public KzBTransaction(KzTransaction tx) { Version = tx.Version; Vin = tx.Vin.Cast <KzBTxIn>().ToList(); Vout = tx.Vout.Cast <KzBTxOut>().ToList(); LockTime = tx.LockTime; TxId = tx.TxId; if (TxId.Value == KzUInt256.Zero) { TxId = null; } }
/// <summary> /// Update the incremental state by one additional transaction hash. /// This creates at most one KzMerkleTreeNode per level of the tree. /// These are reused as subtrees fill up. /// </summary> /// <param name="tx"></param> void AddTransaction(KzTransaction tx) { _count++; var newHash = tx.TxId; if (_count == 1) { // First transaction. _nodes.Add(new KzMerkleTreeNode(newHash, null)); } else { var n = _nodes[0]; if (n.HasBoth) { // Reuse previously filled nodes. var n0 = n; while (n?.HasBoth == true) { n.RightOfParent = !n.RightOfParent; n.HasRight = false; n.HasLeft = false; n = n.Parent; } n0.SetLeftHash(newHash); } else { // Complete leaf node, compute completed hashes and propagate upwards. n.SetRightHash(newHash); do { newHash = ComputeHash(n); var np = n.Parent; if (np == null) { _nodes.Add(new KzMerkleTreeNode(newHash, n)); break; } if (n.LeftOfParent) { np.SetLeftHash(newHash); } else { np.SetRightHash(newHash); } n = np; } while (n.HasBoth); } } }
async public Task <KzTransaction> GetTransactionsByHash(KzUInt256 txId) { var url = $"https://api.whatsonchain.com/v1/bsv/{Kz.Params.strNetworkID}/tx/hash/{txId}"; var json = await _HttpClient.GetStringAsync(url); var woctx = JsonConvert.DeserializeObject <Transaction>(json); var tx = new KzTransaction(); var ros = new ReadOnlySequence <byte>(woctx.hex.HexToBytes()); if (!tx.TryReadTransaction(ref ros)) { tx = null; } return(tx); }
public bool TryParseBlock(ref SequenceReader <byte> r, int height, IKzBlockParser bp) { var offset = r.Consumed; if (!TryReadBlockHeader(ref r)) { goto fail; } Height = height; bp.BlockStart(this, offset); if (!r.TryReadVarint(out long count)) { goto fail; } _txs = new KzTransaction[count]; for (var i = 0L; i < count; i++) { var t = new KzTransaction(); _txs[i] = t; if (!t.TryParseTransaction(ref r, bp)) { goto fail; } } if (!VerifyMerkleRoot()) { goto fail; } bp.BlockParsed(this, r.Consumed); return(true); fail: return(false); }
KzBlock CreateGenesisBlock(string pszTimestamp, KzScript genesisOutputScript, UInt32 nTime, UInt32 nNonce, UInt32 nBits, Int32 nVersion, Int64 genesisReward) { var txs = new KzTransaction[] { new KzTransaction( version: 1, vin: new KzTxIn[] { new KzTxIn( prevout: new KzOutPoint(KzUInt256.Zero, -1), scriptSig: new KzScript(""), sequence: 0) }, vout: new KzTxOut[] { new KzTxOut( value: 0, scriptPub: new KzScript("") ) }, lockTime: 0 ) }; var hashMerkleRoot = KzMerkleTree.ComputeMerkleRoot(txs); var genesis = new KzBlock( txs: txs, version: 1, hashPrevBlock: KzUInt256.Zero, hashMerkleRoot: hashMerkleRoot, time: 1231006506, bits: 0x1d00ffff, nonce: 2083236893 ); return(genesis); }