Long ago, a script was made with a similar purpose as this one. I have since updated it and rewritten many pieces of it and added more features. It does however, lack the assassin unit which it once had.

If you think the script should have something else, feel free to let me know. I will consider any idea put towards this script.
Code:
#include "Stdafx.h"
#include "Setup.h"

class BountyHunter : public GossipScript
{
public:
        void GossipHello(Object* pObject, Player* Plr, bool AutoSend)
    {
        GossipMenu *Menu;
                if(Plr->CombatStatus.IsInCombat())// Checks for combat
                {
                        Plr->BroadcastMessage("You are in combat!");
                        return;
                }
                else
                {
                        objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), 95768, Plr);
                        Menu->AddItem(0, "I would like to place a bounty on someone for 400g", 0, 1);
                        Menu->AddItem(0, "I would like to see the posted bounties", 1);
                        if(Plr->GetSession()->HasPermissions()) //Checks for GM permissions
                        {
                                Menu->AddItem(0, "Clear all bounties", 2);
                        }
                }
                if(AutoSend)
            Menu->SendTo(Plr);
        }
        void GossipSelectOption(Object* pObject, Player* Plr, uint32 Id, uint32 IntId, const char * Code)
    {
                QueryResult * checkexisting = CharacterDatabase.Query("SELECT guid FROM characters WHERE name='%s';", Code); // Selects the column with the guid
       QueryResult * checkexistingg = CharacterDatabase.Query("SELECT * FROM huntedlist WHERE name='%s'", Code); // Select the row that validate the arguments
                QueryResult * checkcount = CharacterDatabase.Query("SELECT * FROM huntedlist WHERE listed='%u'", Plr->GetGUID());
                uint32 rows = checkcount->GetRowCount();
           GossipMenu * Menu;
                switch(IntId) // Switch cases :D
                {
                case 0:
                        {
                                if(checkexisting)// Checks to make sure the player exists
                                {
                                        uint32 playerid = checkexisting->Fetch()[0].GetUInt32();// if he/she does, fetches their guid stored in the db
                                        if(playerid == Plr->GetGUID())// Make sure the player isnt setting a bounty on themself
                                        {
                                                checkexisting->Delete();
                                                Plr->BroadcastMessage("You cannot set a bounty on yourself!");
                                                return;
                                        }
                                        else if(checkexistingg)// Checks for the player already having a listed bounty
                                        {
                                                Plr->BroadcastMessage("This player currently has a bounty placed on them!");
                                                checkexistingg->Delete(); // Deletes the result
                                                checkexisting->Delete();
                                                return;
                                        }
                                        else if(rows > 3)
                                        {
                                                checkexisting->Delete();
                                                checkexisting->Delete();
                                                checkcount->Delete();
                                                Plr->BroadcastMessage("You cannot have more than 3 bounties posted at a time!");
                                                return;
                                        }
                                        checkexistingg->Delete();
                                        uint32 currentg = Plr->GetUInt32Value(PLAYER_FIELD_COINAGE);// Finds the current gold of the player
                                        if(currentg >= 4000000) // Makes sure the players has more than 400g( This is done in copper)
                                        {
                                                Player * chr = objmgr.GetPlayer((const char*)Code, false); // Finds the player by the name that was typed in
                                                if(chr == NULL)// If the player cant be found, he is Offline or doesnt exist
                                                {
                                                        Plr->BroadcastMessage("The player is offline!");
                                                        return;
                                                }
                                                else
                                                {
                                                        chr->BroadcastMessage("A bounty has been placed on you! Prepare yourself!");// Sends a message to the person who has had a bounty placed on them
                                                        chr->CastSpell(chr, 46459, false); // puts the assassin's mark on the player
                                                        CharacterDatabase.Execute("INSERT INTO huntedlist VALUES('%u', '%s', '%u')", playerid, Code, Plr->GetGUID());// Adds the player to the db
                                                        uint32 newgold = currentg - 4000000; // Gets the amount for the bounty lister after paying
                                                        Plr->SetUInt32Value(PLAYER_FIELD_COINAGE, newgold); // Sets the players new gold amount
                                                        Plr->BroadcastMessage("Your bounty has been listed!");// Tells the lister that their list was successful
                                                        char msg[512];// An array of datatype char
                                                        sprintf(msg, "A bounty has been placed on %s. Good luck!", Code);// Fills the array earlier with data
                                                        sWorld.SendWorldWideScreenText(msg);// Prints out the array
                                                }
                                        }
                                        else
                                        {
                                                Plr->BroadcastMessage("You don't have enough gold!");
                                        }
                                }
                                Plr->Gossip_Complete();
                                break;
                        }
                case 1:
                        {
                                objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), 95769, Plr);
                                QueryResult * getlist = CharacterDatabase.Query("SELECT name FROM huntedlist");// Gets the name of the people in the db
                                if(getlist)//if there are any names posted, this will validate
                                {
                                        int count = getlist->GetRowCount();//Gets the amount of names
                                        if(count != 1)// If there is more than 1 name, it loops with a do/while statement
                                        {
                                                do
                                                {
                                                        const char * name = getlist->Fetch()[0].GetString();
                                                        Menu->AddItem(0, name, 1);// do this
                                                }
                                                while(getlist->NextRow());//while there is still another row
                                        }
                                        else// if there is 1 name, it only does the statements once, instead of looping
                                        {
                                                const char * name = getlist->Fetch()[0].GetString();
                                                Menu->AddItem(0, name, 1);
                                        }
                                        getlist->Delete();
                                }
                                else// If there are 0 people listed in the db, it will do this
                                {
                                        getlist->Delete();
                                        Plr->BroadcastMessage("There are no bounties!");
                                        Plr->Gossip_Complete();
                                }
                                Menu->SendTo(Plr);
                                break;

                        }
                case 2:
                        {
                                CharacterDatabase.Execute("TRUNCATE TABLE huntedlist");// Empties the entire bounty list
                                Plr->Gossip_Complete();
                                Plr->BroadcastMessage("Bounties cleared!");
                                break;
                        }


                }
        }

void Destroy()
{
        delete this;
}
};



void BountyKilled(Player * Plr, Player * pVictim) // This is what happens when any player is killed
{
        if(Plr->GetGUID() == pVictim->GetGUID())//Checks to make sure they didnt kill themself
                return;
        QueryResult * listerguid = CharacterDatabase.Query("SELECT listed FROM huntedlist WHERE guid='%u'", pVictim->GetGUID());//Gets the guid of the lister
        if(listerguid == NULL)// If none show up, then player has no bounty on them
        {
                listerguid->Delete();
                return;
        }
        QueryResult * checkforbounty = CharacterDatabase.Query("SELECT * FROM huntedlist WHERE guid='%u'", pVictim->GetGUID());
        if(checkforbounty != NULL)
        {
                uint32 listerguids = listerguid->Fetch()[0].GetUInt32();
                Player * chr = objmgr.GetPlayer(listerguids);// Gets the player by their guid
                chr->BroadcastMessage("Assassination of %s completed by %s.", pVictim->GetName(), Plr->GetName());// Tells the above player that their bounty was scucessful
                checkforbounty->Delete();
                CharacterDatabase.Execute("DELETE FROM huntedlist WHERE guid ='%u'", pVictim->GetGUID());//Removes the bounty
                Plr->BroadcastMessage("You have completed the bounty for %s! Enjoy the gold.", pVictim->GetName());
                uint32 cgold = Plr->GetUInt32Value(PLAYER_FIELD_COINAGE); //Gets the killer's gold amount
                uint32 ngold = cgold + 2000000;
                Plr->SetUInt32Value(PLAYER_FIELD_COINAGE, ngold);// Sets the killer's new gold amount
                listerguid->Delete();
        }
        else
        {
                checkforbounty->Delete();
                listerguid->Delete();
        }

}

void SetupBountyHunter(ScriptMgr * mgr)
{
        GossipScript * gs = (GossipScript*) new BountyHunter();
        mgr->register_gossip_script(120070, gs);
        mgr->register_hook(SERVER_HOOK_EVENT_ON_KILL_PLAYER, &BountyKilled);
}
I've also commented it so you can see what does what.

Here is the sql query that goes along with the script.



Code:
DROP TABLE IF EXISTS `huntedlist`;

CREATE TABLE `huntedlist` (
`guid` int(11) NOT NULL,
`name` varchar(30) COLLATE latin1_general_ci NOT NULL,
`listed` int(11) NOT NULL,
PRIMARY KEY (`guid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Enjoy