Skip to content

Instantly share code, notes, and snippets.

@jl2012
Last active November 23, 2018 22:10
Show Gist options
  • Select an option

  • Save jl2012/9315ee59290fd48db7c8a416444aa6fb to your computer and use it in GitHub Desktop.

Select an option

Save jl2012/9315ee59290fd48db7c8a416444aa6fb to your computer and use it in GitHub Desktop.

Revisions

  1. jl2012 revised this gist Nov 23, 2018. 1 changed file with 76 additions and 0 deletions.
    76 changes: 76 additions & 0 deletions OP_MASK
    Original file line number Diff line number Diff line change
    @@ -30,4 +30,80 @@ int FindAndMask(CScript& script)
    }

    return masked;
    }

    BOOST_AUTO_TEST_CASE(script_op_mask)
    {
    // Exercise the FindAndMask functionality
    CScript s;
    CScript d;
    CScript e;

    s = CScript() << OP_1 << OP_2 << OP_3;
    e = s;
    BOOST_CHECK_EQUAL(FindAndMask(s), 0);
    BOOST_CHECK(s == e);

    s = ScriptFromHex("5101bd02febd");
    e = s;
    BOOST_CHECK_EQUAL(FindAndMask(s), 0);
    BOOST_CHECK(s == e);

    s = ScriptFromHex("5101bd02bd"); // invalid: incomplete push
    e = s;
    BOOST_CHECK_EQUAL(FindAndMask(s), 0);
    BOOST_CHECK(s == e);

    e = CScript() << OP_1 << OP_MASK << OP_VERIF;
    s = CScript() << OP_1 << OP_MASK << OP_DUP;
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);
    s = ScriptFromHex("51bd02feed");
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);
    s = ScriptFromHex("51bd02febd");
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);
    s = ScriptFromHex("51bd4e02000000feed");
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);
    s = CScript() << OP_1 << OP_MASK << OP_VERIF; // invalid: OP_VERIF
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);

    s = ScriptFromHex("51bd4e02000000feed02bdbd");
    e = ScriptFromHex("51bd6502bdbd");
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);

    s = ScriptFromHex("51bd4e02000000feed02bd"); // invalid: incomplete push
    e = ScriptFromHex("51bd6502bd");
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);

    s = CScript() << OP_1 << OP_IF << OP_MASK << OP_NOP8 << OP_ELSE << OP_MASK << OP_NOP9 << OP_ENDIF;
    e = CScript() << OP_1 << OP_IF << OP_MASK << OP_VERIF << OP_ELSE << OP_MASK << OP_VERIF << OP_ENDIF;
    BOOST_CHECK_EQUAL(FindAndMask(s), 2);
    BOOST_CHECK(s == e);

    s = CScript() << OP_1 << OP_MASK << OP_MASK << OP_3;
    e = CScript() << OP_1 << OP_MASK << OP_MASK << OP_VERIF;
    BOOST_CHECK_EQUAL(FindAndMask(s), 1);
    BOOST_CHECK(s == e);

    s = CScript() << OP_1 << OP_MASK << OP_MASK << OP_3 << OP_MASK;
    BOOST_CHECK_EQUAL(FindAndMask(s), -1);
    BOOST_CHECK(s == CScript());
    s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK << OP_MASK;
    BOOST_CHECK_EQUAL(FindAndMask(s), -1);
    BOOST_CHECK(s == CScript());
    s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK;
    BOOST_CHECK_EQUAL(FindAndMask(s), -1);
    BOOST_CHECK(s == CScript());
    s = CScript() << OP_1 << OP_2 << OP_NOTIF << OP_MASK; // invalid: inbalance condition
    BOOST_CHECK_EQUAL(FindAndMask(s), -1);
    BOOST_CHECK(s == CScript());
    s = ScriptFromHex("51bd02fe"); // invalid: incomplete push
    BOOST_CHECK_EQUAL(FindAndMask(s), -1);
    BOOST_CHECK(s == CScript());
    }
  2. jl2012 created this gist Nov 23, 2018.
    33 changes: 33 additions & 0 deletions OP_MASK
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    int FindAndMask(CScript& script)
    {
    int masked = 0;
    bool skip_next = false;
    CScript result;
    CScript::const_iterator pc = script.begin(), pc2 = script.begin();
    opcodetype opcode;

    while (script.GetOp(pc, opcode)) {
    if (opcode == OP_MASK) {
    result.insert(result.end(), pc2, pc);
    skip_next = true;
    pc2 = pc;
    }
    else if (skip_next == true) {
    result.insert(result.end(), (unsigned char)OP_VERIF);
    skip_next = false;
    pc2 = pc;
    ++masked;
    }
    }

    if (skip_next == true) {
    script = CScript();
    return -1;
    }
    if (masked > 0) {
    result.insert(result.end(), pc2, static_cast<CScript::const_iterator>(script.end()));
    script = std::move(result);
    }

    return masked;
    }