Understanding this is the key to making sense of compressed keys and WIFs too.
I understand compressed keys and WIF's
Anyway, I've decided not to do a simple memcmp, but rather something more generic:
internal static Hash160 GetAddress(byte[] aScript)
{
Hash160 hash = null;
ParseState parseState = ParseState.OP_ANY;
ScriptParser parser = new ScriptParser(aScript, delegate(Opcode aOpcode, byte[] aData)
{
switch (parseState)
{
case ParseState.OP_ANY:
if (aOpcode == Opcode.OP_HASH160)
parseState = ParseState.OP_20;
if ((aOpcode == (Opcode)33) || (aOpcode == (Opcode)65))
{
if (hash != null)
return false;
if (Utils.VerifyPublicKey(aData, aData.Length) != 1)
return false;
hash = new Hash160(Utils.RIPEMD160SHA256(aData));
}
break;
case ParseState.OP_20:
if (aOpcode != (Opcode)20)
return false;
if (hash != null)
return false;
hash = new Hash160(aData);
parseState = ParseState.OP_EQUALVERIFY;
break;
case ParseState.OP_EQUALVERIFY:
if (aOpcode != Opcode.OP_EQUAL && aOpcode != Opcode.OP_EQUALVERIFY)
return false;
parseState = ParseState.OP_ANY;
break;
default:
return false;
}
return true;
});
if (parser.Parse())
{
return hash;
}
return null;
}