What is preventing negative balance? This is probably a stupid question that has an answer somewhere, but I was unable to find anything, so please feel free to redirect me !

I have a basic understanding of how the bitcoin blockchain works, namely, you sign and broadcast your transaction, it gets picked up by the nodes and is eventally included in a block that is mined.

I understand that as long as there isn't someone controlling more than 50% of the mining power, it is unlikely to be able to perform a double spend attempt.

However, what prevents someone from spending more bitcoins that they have ? For example, if I have 1 BTC on my adress, suppose I run a mining node, what prevents me from trying to mine a block in which I spend 1.2 BTC ? At what point in the process is the balance of my adress checked to make sure I do have the bitcoin that I want to spend ?

At first I thought that it was the nodes that verified that the transaction on the mempool are valid before starting to mine them but this can't be it, since you could have a malicious node that does whatever (although it would be difficult to pull off without enough mining power).

This check must be somehow "hard-coded" somewhere, in the sense that it is actually impossible to create a transaction of inexistent bitcoin. Could someone point me to a resource or elaborate how does this work ?
if I have 1 BTC on my address, suppose I run a mining node, what prevents me from trying to mine a block in which I spend 1.2 BTC ?


This is the specific set of code in Bitcoin Core that rejects anyone's transaction who's is putting less money into the transaction (inputs) than the recipients are receiving (outputs), e.g. spending more money than they have added to the transaction:

const CAmount value_out = tx.GetValueOut();
if (nValueIn &lt; value_out) {
    return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false,
        strprintf("value in (%s) &lt; value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
}


Technically, this isn't checking the "balance" of an address, since in Bitcoin system itself, addresses don't have balances.  When you receive bitcoins, you receive them to an individually-identifiable output (payment).  When you spend bitcoins, you identify exactly which output (or outputs) you want to spend and spend all of that value at once.

If you want to pay someone less than the full value of one of your outputs, you add an extra output on to your payment that returns the remainder to yourself.  This is like paying for a $2 snack with a $5 bill and receiving $3 change back to yourself (and it Bitcoin, we call that extra output paying yourself the "change output" by analogy).

So in the code above, by checking every single spend in the system to prevent anyone from receivng more bitcoins than were initially spent (except for newly-minted bitcoins), we prevent negative balances.


  At what point in the process is the balance of my adress checked to make sure I do have the bitcoin that I want to spend ?


As explained above, inputs and outputs (rather than address balances) are what's checked.  They're ultimately checked when a block is received; however, the software may check them for unconfirmed transactions and cache the result so that it can process newly-received blocks faster.



Somewhat related, you also can't pay someone a negative output:

    if (txout.nValue &lt; 0)
        return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative");