public Transaction Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } var transactionSequence = rlpStream.PeekNextItem(); int transactionLength = rlpStream.ReadSequenceLength(); int lastCheck = rlpStream.Position + transactionLength; Transaction transaction = new Transaction(); transaction.Nonce = rlpStream.DecodeUInt256(); transaction.GasPrice = rlpStream.DecodeUInt256(); transaction.GasLimit = rlpStream.DecodeLong(); transaction.To = rlpStream.DecodeAddress(); transaction.Value = rlpStream.DecodeUInt256(); if (transaction.To == null) { transaction.Init = rlpStream.DecodeByteArray(); } else { transaction.Data = rlpStream.DecodeByteArray(); } if (rlpStream.Position < lastCheck) { Span <byte> vBytes = rlpStream.DecodeByteArraySpan(); Span <byte> rBytes = rlpStream.DecodeByteArraySpan(); Span <byte> sBytes = rlpStream.DecodeByteArraySpan(); if (vBytes == null || rBytes == null || sBytes == null) { throw new RlpException("VRS null when decoding Transaction"); } if (vBytes.Length == 0 || rBytes.Length == 0 || sBytes.Length == 0) { throw new RlpException("VRS is 0 length when decoding Transaction"); } if (vBytes[0] == 0 || rBytes[0] == 0 || sBytes[0] == 0) { throw new RlpException("VRS starting with 0"); } if (rBytes.Length > 32 || sBytes.Length > 32) { throw new RlpException("R and S lengths expected to be less or equal 32"); } int v = vBytes.ReadEthInt32(); if (rBytes.SequenceEqual(Bytes.Zero32) && sBytes.SequenceEqual(Bytes.Zero32)) { throw new RlpException("Both 'r' and 's' are zero when decoding a transaction."); } Signature signature = new Signature(rBytes, sBytes, v); transaction.Signature = signature; transaction.Hash = Keccak.Compute(transactionSequence); } if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { rlpStream.Check(lastCheck); } return(transaction); }
public BlockHeader Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } var headerRlp = rlpStream.PeekNextItem(); int headerSequenceLength = rlpStream.ReadSequenceLength(); int headerCheck = rlpStream.Position + headerSequenceLength; Keccak parentHash = rlpStream.DecodeKeccak(); Keccak ommersHash = rlpStream.DecodeKeccak(); Address beneficiary = rlpStream.DecodeAddress(); Keccak stateRoot = rlpStream.DecodeKeccak(); Keccak transactionsRoot = rlpStream.DecodeKeccak(); Keccak receiptsRoot = rlpStream.DecodeKeccak(); Bloom bloom = rlpStream.DecodeBloom(); UInt256 difficulty = rlpStream.DecodeUInt256(); UInt256 number = rlpStream.DecodeUInt256(); UInt256 gasLimit = rlpStream.DecodeUInt256(); UInt256 gasUsed = rlpStream.DecodeUInt256(); UInt256 timestamp = rlpStream.DecodeUInt256(); byte[] extraData = rlpStream.DecodeByteArray(); BlockHeader blockHeader = new BlockHeader( parentHash, ommersHash, beneficiary, difficulty, (long)number, (long)gasLimit, timestamp, extraData) { StateRoot = stateRoot, TxRoot = transactionsRoot, ReceiptsRoot = receiptsRoot, Bloom = bloom, GasUsed = (long)gasUsed, Hash = Keccak.Compute(headerRlp) }; if (rlpStream.PeekPrefixAndContentLength().ContentLength == Keccak.Size) { blockHeader.MixHash = rlpStream.DecodeKeccak(); blockHeader.Nonce = (ulong)rlpStream.DecodeUBigInt(); } else { blockHeader.AuRaStep = (long)rlpStream.DecodeUInt256(); blockHeader.AuRaSignature = rlpStream.DecodeByteArray(); } if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { rlpStream.Check(headerCheck); } return(blockHeader); }