Document SIGHASH_ALL requirement
This commit is contained in:
parent
37cc29bcc0
commit
55ff82bbec
2 changed files with 32 additions and 1 deletions
|
|
@ -248,6 +248,29 @@ at position `inputIndex`. Only inputs that require wallet signing need an entry
|
|||
pre-set unlocking bytecode can be omitted. This allows the wallet to sign each input without scanning
|
||||
or guessing which key was used.
|
||||
|
||||
#### SIGHASH requirement (security-critical)
|
||||
|
||||
Wallets **MUST** sign every input with `SIGHASH_ALL | SIGHASH_FORKID | SIGHASH_UTXOS` and **MUST**
|
||||
reject any request that would require different flags.
|
||||
|
||||
`SIGHASH_ALL` ensures the signature commits to the entire transaction (all inputs and all outputs).
|
||||
Without it, an attacker could collect a valid signature and graft it onto a different transaction —
|
||||
for example, using `SIGHASH_NONE` an attacker could replace every output to redirect funds.
|
||||
|
||||
Because `inputPaths` lets the dapp specify which key signs each input, the wallet no longer
|
||||
independently verifies that the key matches the UTXO's locking bytecode. This is safe **only** when
|
||||
`SIGHASH_ALL` is enforced: if the dapp provides a wrong path, the resulting signature is invalid
|
||||
(public key hash mismatch) and the transaction cannot broadcast. Without `SIGHASH_ALL`, a
|
||||
wrong-key signature could still be repurposed in a different transaction context.
|
||||
|
||||
Summary of the flags:
|
||||
|
||||
| Flag | Purpose |
|
||||
|------|---------|
|
||||
| `SIGHASH_ALL` | Commits to all inputs and outputs — prevents output substitution |
|
||||
| `SIGHASH_FORKID` | Prevents cross-fork replay (BCH ↔ BTC) |
|
||||
| `SIGHASH_UTXOS` | Commits to all input UTXOs — prevents input substitution after signing |
|
||||
|
||||
### sign_transaction_response
|
||||
|
||||
```typescript
|
||||
|
|
|
|||
|
|
@ -163,6 +163,13 @@ application is responsible for:
|
|||
|
||||
The wallet library does not auto-sign or auto-reject anything.
|
||||
|
||||
**SIGHASH enforcement:** The wallet **MUST** sign every input with
|
||||
`SIGHASH_ALL | SIGHASH_FORKID | SIGHASH_UTXOS`. See the
|
||||
[SIGHASH requirement](protocol.md#sighash-requirement-security-critical) section in the protocol
|
||||
docs for the security rationale. Because the dapp specifies `inputPaths`, the wallet trusts the
|
||||
dapp's key selection — `SIGHASH_ALL` is what makes this safe (a wrong-key signature is simply
|
||||
invalid and cannot be repurposed).
|
||||
|
||||
## Minimal example
|
||||
|
||||
```typescript
|
||||
|
|
@ -178,7 +185,8 @@ class MyAdapter implements WalletAdapter {
|
|||
getXpub(path: DerivationPath) { /* ... */ }
|
||||
|
||||
async signTransaction(request) {
|
||||
// show approval UI, sign, return hex
|
||||
// Show approval UI, sign with SIGHASH_ALL | SIGHASH_FORKID | SIGHASH_UTXOS, return hex.
|
||||
// See protocol.md "SIGHASH requirement" — other sighash flags MUST be rejected.
|
||||
return { signedTransactionHex: "..." };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue