How contract signing works
What you sign
When you click "Sign contract," MPBxChange records four things atomically:
- The contract content hash (SHA-256 of the canonical JSON snapshot).
- Your signing intent (which role · buyer or supplier · and which contract revision).
- Your authentication state (Supabase session + Signing PIN verification).
- An audit-trail row with your IP, user-agent, timestamp, and the hash of the previous audit row (the chain).
You sign the hash, not the prose. If anyone changes the spec, milestone schedule, or counterparty after signing, the hash changes and the signature no longer matches. That mismatch is provable breach.
Why it's admissible
Section 9 of the Electronic Transactions Act B.E. 2544 (2001) recognises an electronic signature as legally binding when there is "a reliable means of identifying the person and indicating their intent to be bound." Our authentication chain — KYC + login + Signing PIN at the moment of each signature — meets that bar.
What gets recorded
| Field | Source | Persisted in |
|---|---|---|
| Content hash | computed from contract JSON | trade_contracts.signed_payload_hash |
| Your IP | request headers | audit_log |
| Your user-agent | request headers | audit_log |
| Timestamp | server clock | audit_log + trade_contracts |
| PIN attestation | bcrypt(profile.signing_pin_hash) | profiles + audit_log |
| Hash of previous audit row | escrow_events chain | escrow_events |
What you cannot un-sign
Once both parties have signed and escrow is funded, the spec, milestone schedule, and counterparty are frozen. Any change requires a written change-order accepted by both parties as a new signing event — there is no edit-in-place. This is by design.