/// <summary> /// Special handling to check if we have a valid byte array for both header and transactions /// </summary> /// <returns></returns> public override byte[] BitcoinSerialize() { byte[] cached=getCachedBitcoinSerialization(); if(cached!=null) { return cached; } // At least one of the two cacheable components is invalid // so fall back to stream write since we can't be sure of the length. using(ByteStreamUnsafe stream=new ByteStreamUnsafe(Length==UnknownLength?HeaderSize+guessTransactionsLength():Length)) { BitcoinSerializeToStream(stream); return stream.GetWritenStreamIrreversible(); } }
/// <summary> /// Returns the script bytes of inputScript with all instances of the specified script object removed /// </summary> /// <param name="inputScript"></param> /// <param name="chunkToRemove"></param> /// <returns></returns> public static byte[] removeAllInstancesOf(byte[] inputScript,byte[] chunkToRemove) { // We usually don't end up removing anything using(ByteStreamUnsafe stream=new ByteStreamUnsafe(inputScript.Length)) { int cursor=0; while(cursor<inputScript.Length) { bool skip=equalsRange(inputScript,cursor,chunkToRemove); int opcode=inputScript[cursor++] & 0xFF; int additionalBytes=0; if(opcode>=0 && opcode<OP_PUSHDATA1) { additionalBytes=opcode; } else if(opcode==OP_PUSHDATA1) { additionalBytes=inputScript[cursor]+1; } else if(opcode==OP_PUSHDATA2) { additionalBytes=((0xFF & inputScript[cursor]) | ((0xFF & inputScript[cursor+1])<<8)) +2; } else if(opcode==OP_PUSHDATA4) { additionalBytes=((0xFF & inputScript[cursor]) | ((0xFF & inputScript[cursor+1])<<8) | ((0xFF & inputScript[cursor+1])<<16) | ((0xFF & inputScript[cursor+1])<<24)) +4; } if(!skip) { stream.Write((byte)opcode); stream.Write(inputScript,cursor,additionalBytes); } cursor+=additionalBytes; } return stream.ToArrayIrreversible(); } }
public static byte[] createOutputScript(Address to) { // TODO: Do this by creating a Script *first* then having the script reassemble itself into bytes. using(ByteStreamUnsafe stream=new ByteStreamUnsafe(24)) { stream.Write(OP_DUP); stream.Write(OP_HASH160); writeBytes(stream,to.Hash160); stream.Write(OP_EQUALVERIFY); stream.Write(OP_CHECKSIG); return stream.ToArrayIrreversible(); } }
/// <summary> /// Create a script that sends coins directly to the given public key (eg in a coinbase transaction). /// </summary> /// <param name="pubkey"></param> /// <returns></returns> public static byte[] createOutputScript(byte[] pubkey) { // TODO: Do this by creating a Script *first* then having the script reassemble itself into bytes. using(ByteStreamUnsafe stream=new ByteStreamUnsafe(pubkey.Length+1)) { writeBytes(stream,pubkey); stream.Write(OP_CHECKSIG); return stream.ToArrayIrreversible(); } }
public static byte[] createInputScript(byte[] signature) { // TODO: Do this by creating a Script *first* then having the script reassemble itself into bytes. using(ByteStreamUnsafe stream=new ByteStreamUnsafe(signature.Length+2)) { writeBytes(stream,signature); return stream.ToArrayIrreversible(); } }