public void sighash_from_data() { var tests = TestCase.read_json("Data/sighash.json"); foreach(var test in tests) { var strTest = test.ToString(); if(test.Count < 1) // Allow for extra stuff (useful for comments) { Assert.True(false, "Bad test: " + strTest); continue; } if(test.Count == 1) continue; // comment string raw_tx, raw_script, sigHashHex; int nIn, nHashType; Transaction tx = new Transaction(); Script scriptCode = new Script(); // deserialize test data raw_tx = (string)test[0]; raw_script = (string)test[1]; nIn = (int)(long)test[2]; nHashType = (int)(long)test[3]; sigHashHex = (string)test[4]; tx.ReadWrite(ParseHex(raw_tx)); ValidationState state = Network.Main.CreateValidationState(); Assert.True(state.CheckTransaction(tx), strTest); Assert.True(state.IsValid); var raw = ParseHex(raw_script); scriptCode = new Script(raw); var sh = scriptCode.SignatureHash(tx, nIn, (SigHash)nHashType); Assert.True(sh.GetHex() == sigHashHex, strTest); } }
Script sign_multisig(Script scriptPubKey, Key[] keys, Transaction transaction) { uint256 hash = scriptPubKey.SignatureHash(transaction, 0, SigHash.All); List<Op> ops = new List<Op>(); //CScript result; // // NOTE: CHECKMULTISIG has an unfortunate bug; it requires // one extra item on the stack, before the signatures. // Putting OP_0 on the stack is the workaround; // fixing the bug would mean splitting the block chain (old // clients would not accept new CHECKMULTISIG transactions, // and vice-versa) // ops.Add(OpcodeType.OP_0); foreach(Key key in keys) { var vchSig = key.Sign(hash).ToDER().ToList(); vchSig.Add((byte)SigHash.All); ops.Add(Op.GetPushOp(vchSig.ToArray())); } return new Script(ops.ToArray()); }