If I run a full node I am supposedly contributing to network security by keeping a copy of the blockchain
That's right, but by running a node, you're most importantly securing yourself. I will get back to this statement further down.
The network doesn't really need infinite nodes for security, but just enough so that TX-data can propagate fast enough to all corners of the network. A small number of strategic nodes with big bandwidth could achieve this. There must be some redundancy to prevent a scenario where adversary could take down some % of them and cause trouble for part of the network. These nodes will belong to big services, exchanges, pools and enthusiasts.
Smaller nodes surely help by reducing the load on existing nodes. Anyway, it's not an easy task to map nodes and determine the topology, and you don't really know the capacity of random nodes you connect to.
If I mine (via pool or solo) I contribute to the network through verification of blocks
You verify blocks by running a node, not by mining. Mining is the process of producing a valid block. Nodes do the final verification. By solo mining, you're also running a node and thus contributing to network verification of blocks. By pool mining, the pool is running a node so you're not really contributing directly. You might be contributing indirectly, since the pool will have a cash-flow from users which will enable it to upgrade internet speed and run a stronger node (or a whole network of them).
The security is really achieved by nodes and miners together.
- Nodes check validity of TX-es, i.e., that they come with a valid signature otherwise anyone could spend your funds. They "define" the rules and that the double-spend problem will be solved by delegating POW to miners.
- Miners provide the POW, and give resilience to the network. Thanks to them, nodes can tell what came first and it's very hard to cancel a TX once it made its way into a block. Miners help achieve both security and immutability.
Note that Bitcoin has another kind of nodes which don't check blocks for validity. Those are "dumb nodes" which only relay data. They don't really secure anything, and rely on other nodes giving them good data. I'd just title these "network relays" instead of nodes to prevent confusion.
To understand better all of this, we must understand how the whole system works.
So, how does a decentralized cryptocurrency work?
A blockchain is a shared database to which records can only be added. When you run a node, you're saying "I will accept only entries to my copy of the blockchain which followed these rules". That's all. With a node, you define what will be the currency you accept and what those rules mean. By having lots of others following the same rules, an economic ecosystem where participants can freely transact with each other is created. If someone changes the rules in a way that's not compatible with the rest, then he can no longer transact with the same people, but if there are others using the new rules he can transact with them instead - another currency is created. Depending on context, the split can be called a hard fork (when 2 different coins have a shared history). If you don't run a node, but use a light wallet, then you delegate the choice of rules to the node operator. If you don't agree, you should change the service.
The main thing which enabled the first decentralized cryptocurrency was the way it used POW (proof-of-work) to solve the double-spend problem without having to rely on some trusted authority. The POW is what enables your node to tell the order of transactions and ensures that history can't be changed or re-written. I.e., I can't take back my Bitcoins once I sent them to you and I can't spend them again at another place since the whole network sees them as spent.
So, what are the rules? Something like:
A blockchain is a collection of blocks
Every block is a collection of transactions + the block header. Every block must reference the previous one, making a "chain".
A transaction is nothing but a statement like "I hereby prove I have rights to spend X,Y,Z outputs, and create A,B,C outputs of the same total amount. For this I offer a fee of M"
A block can have any number of transactions
Once transactions are aggregated into a block, it must be "hashed". A hash is a way of getting an one-way result from some data. Like, if you hash "abc" you get "ba7816..." and if you hash "abd" you get "a52d15..", try it out here. The result looks random, and if it's a good hash function it will always look random. Point is, you can't know what the hash of "abc" will be, without actually performing the hash computation and seeing what you get. To hash a block, instead of using "abc" as in the example, you feed the entire data of the block and see what you get. If what you get matches a pre-determined pattern, it will be a valid hash. Thing is, what if it's not? Then, you need to change just a little bit of data (there's a "slot" for this, called a nonce) in the block, and try again. The process is repeated until a matching hash is found and only then the block will be valid. The pattern can be more or less restrictive. An "easy" pattern would be to get the first letters of a hash to be "aa...", this would take only a few attempts to match. When we increase difficulty it means that the pattern is harder and harder to guess. Like increasing the number of numbers from your lottery ticket you need to get right to win.
Every block will have a special, "coinbase" transaction which creates new coins according to pre-determined schedule agreed by the rules. The one who makes the block, gets to choose where these new coins (and fees) will go to. (Collecting TX-es in a block is done by either solo miners or pool operators)
A block will only be accepted by nodes if it it's following all the rules and comes with a valid POW (this part is done by miners). Miners take the block template (basically, entire block which is only missing the valid hash), and change just that one small bit (nonce) to keep "rolling" the hashes until a match is found. If anything else changes (transaction, reference to previous block, coinbase address) the hash will also change. This is what makes it secure, because changing anything in the block would make it invalid because hash would change in an unpredictable way.
In case there are 2 different blocks arriving at the same time the one with a bigger difficulty will "win" and kick out the other one, and everyone will build upon the accepted one. If a part of the network builds on one, and other part on the other then the competing chains could be 2 blocks deep. The biggest cumulative "work" wins and kicks the alternative chain. This happens occasionally due to network propagation times and is called a re-org. Note that both chains must be following the same rules otherwise nodes would reject it straight-away. The POW is there just to make sure nobody can cheat on the ordering of valid transactions. For example to replace 10 blocks and re-arrange order of transactions or simply cancel some, you'd need to re-do all the hashes for all 10 of them before someone else adds the 11-th one. Thing is, you'd need 10x more computing power than the entire network to do it and that makes it an impossible task. Even if you manage it, you can only reorder or cancel transactions. You can't ever cheat the rules agreed by the nodes. A miner is always working within those rules.