As you mentioned yourself, the problem with software development is that there are a lot of unknowns. These introduce variability in what will be built (which people assume will be fixed). What's worse, is that in the beginning, both parties have trouble knowing what is needed and what will change after the project is started (and things will definitely change as both parties get a better understanding of what's needed).
The problem with writing contracts is that they usually try to fix all aspects of the agreement about what to build, how much to pay for it, and when it will be ready. So because of the unknowns inherent to software development, the contracts end up not as writing down the rules of collaboration to reach the same goal or target, but as an attempt for each party to get the best deal out of it: the client to pay cheap, the provider not to pay penalties. It's basically a matter of writing the contract so that the other side takes on the risks. And you can get this with fixed-price and time and materials also.
As to whose responsibility it is to define the contract, it is a joined effort between business people, sales persons, executives, project managers, and legal staff. A contract defines things related to resources, personnel, roles and responsibilities, payments, warranties, insurance, limitations of liabilities, obligations of both parties, data security, data protection, change management, dispute resolutions, delivery plans, acceptance criteria, various other linked documents like requirements, specifications, etc. You can search online for some templates just to get an idea of what's involved.
So when drafting the contract, yes, it's best to involve some lawyers familiar with the IT field, or someone with legal experience that has done this before, to lay down the agreement in writing. Otherwise, if you are new to this, you are exposing yourself to a bunch of risks.