Understanding Bitcoin smart contracts as an Ethereum developer
EVM (Ethereum), and to a large extent EOS, approach smart contract development with the premise that you pay to have your code deployed to the blockchain and it becomes a part of the network consensus rules. This means that every transaction must be processed by every node in the network in order be added to the chain. This approach offers high guarantees that the code has been executed correctly, but does so at extremely high processing cost and slow performance. Additionally, if the rules in the code require reading in data from previous transactions, that data must be stored within the blockchain state itself. This means that not only does every node need process your logic, but they also need to store all the data required for that computation.
Things are much simpler in Bitcoin. The base Bitcoin protocol records whatever data a user wants to pay to write, and cryptographically ties that transaction to the keys which wrote it and sequences the transaction in time. That is all. It couldn't care less about the rules of you contract.
This may sound limiting, until you realize what flexibility it gives. Rather than requiring that thousands (or more) nodes store all data and process your logic, this work can be entirely offloaded to wallets. Just like the consensus rules of Ethereum have to be followed by all Ethereum nodes, the same is true for the wallets interacting with your application. The difference is that the wallet only needs to care about a specific set of rules, not the rules of every application in existence. If a user makes a transaction which is not valid within the specified protocol, the wallets will refuse to recognize that transaction as a valid action. If desired, the application protocol within the wallet can even define how wallets should handle invalid transactions.
As state is not directly stored within the bitcoin blockchain as it is with Ethereum, it does mean that application providers and wallets do need to index the transaction data which is associated with their application. This sounds like extra complexity, but the fact is that is already the standard process for Ethereum contracts. Most every Ethereum contract logs events which need to be indexed in order to share usable information with a user. For example, if you want to have a wallet which shows the ERC20 tokens owned by an address, there is no concise way to read that data from an Ethereum node.
The only ways to get those balances are to call every ERC20 contract and ask for the user's balance in each one, or to parse all the transfer logs to determine how many tokens have been transferred to the user and subtract the tokens they have transferred away. Both of these approaches require heavy amounts of network bandwidth and processing effort by an Ethereum node. The solution to this problem is to watch Ethereum and index the Transfer events which cross the wire.
This is the exact process required in Bitcoin. You gain little from the Ethereum approach, but at a great cost.