Why aren't public-private keys sufficient to build a block chain? Why do we need proof of work/stake?
the code could have a way to order transactions and if an attacker decides to do the opposite intentionally and decides to spam the network

This is the crux of the issue: how do you achieve this? It isn't a trivial problem to solve in a decentralized network. The more generalized version of this non-trivial problem is called the Byzantine General's Problem, it describes the ability of participants to come to an agreement in an untrusted network. The invention of bitcoin provides an economically-incentivized game-theoretic framework that could be considered a probabilist solution to this problem.  As @PieterWuille mentioned in the comments, there is no absolute guarantee of eventual consistency: there is only a (continually increasing, thus far) economic incentive for participants to consider.
The solution that proof of work provides is to rate-limit spamming via the requirement for expenditure of a scarce resource: energy. It is hard to create a new block (it takes some amount of energy, on average), but it is easy to verify if a block is valid. And remember that the method for choosing the next valid block must be perfectly consistent across all nodes in the network, or else you risk a network split/fork, which is very undesirable.

but how does the attacker benefit from that?

There are many ways an attacker could benefit. As a simple example: the attacker takes a 'short' financial position, betting against the price of bitcoin. They then attack the network, assumedly causing the network's value to drop, and thus they would profit from their short position.