This repository has been archived by the owner on Sep 14, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from Vesta-wallet/p2sh-multisig
P2SH Multisig Input Signing and Output Address Generation
- Loading branch information
Showing
13 changed files
with
290 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,33 @@ | ||
import 'dart:typed_data'; | ||
import '../utils/script.dart' as bscript; | ||
import '../utils/constants/op.dart'; | ||
import "../crypto.dart" show hash160; | ||
import './multisig.dart'; | ||
import '../models/networks.dart'; | ||
import 'package:bs58check/bs58check.dart' as bs58check; | ||
|
||
/// Takes the hash160 ([scriptHash]) of a P2SH redeemScript and returns the | ||
/// output script (scriptPubKey) | ||
Uint8List createP2shOutputScript(Uint8List scriptHash) { | ||
if (scriptHash.length != 20) { | ||
throw ArgumentError('Invalid script hash length'); | ||
class P2SH { | ||
Uint8List scriptHash; | ||
|
||
P2SH.fromScriptHash(Uint8List hash) : scriptHash = hash { | ||
if (scriptHash.length != 20) { | ||
throw ArgumentError('Invalid P2SH script hash length'); | ||
} | ||
} | ||
|
||
return bscript.compile([ops['OP_HASH160'], scriptHash, ops['OP_EQUAL']]); | ||
P2SH.fromScriptBytes(Uint8List bytes) : this.fromScriptHash(hash160(bytes)); | ||
P2SH.fromMultisig(MultisigScript script) | ||
: this.fromScriptBytes(script.scriptBytes); | ||
|
||
/// Returns the outputScript (scriptPubKey) | ||
Uint8List get outputScript => | ||
bscript.compile([ops["OP_HASH160"], scriptHash, ops["OP_EQUAL"]]); | ||
|
||
/// Returns the base58 address for a given network | ||
String address(NetworkType network) { | ||
final payload = Uint8List(21); | ||
payload.buffer.asByteData().setUint8(0, network.scriptHash); | ||
payload.setRange(1, payload.length, scriptHash); | ||
return bs58check.encode(payload); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import 'dart:typed_data'; | ||
import '../utils/script.dart' as bscript; | ||
import '../utils/constants/op.dart'; | ||
import 'package:coinslib/src/payments/multisig.dart'; | ||
|
||
// This is similar to the inputCheck for P2WSH and a candidate for abstraction. | ||
/// Only allows multisig P2SH at the moment | ||
bool inputCheck(List<dynamic> chunks) { | ||
if (chunks.length < 2) return false; | ||
|
||
// Check that the first item is 0 which is necessary for CHECKMULTISIG | ||
if (chunks[0] != 0) return false; | ||
|
||
// Last push needs to be the redeemScript | ||
if (chunks.last is! Uint8List) return false; | ||
|
||
// Check redeemScript is multisig | ||
try { | ||
final multisig = MultisigScript.fromScriptBytes(chunks.last); | ||
// Can only have upto threshold sigs plus OP_0 and redeemScript | ||
if (chunks.length > 2 + multisig.threshold) return false; | ||
} on ArgumentError { | ||
return false; | ||
} | ||
|
||
// Check signatures | ||
for (final sig in chunks.getRange(1, chunks.length - 1)) { | ||
if (!bscript.isCanonicalScriptSignature(sig)) return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool outputCheck(Uint8List script) { | ||
final buffer = bscript.compile(script); | ||
return buffer.length == 23 && | ||
buffer[0] == ops['OP_HASH160'] && | ||
buffer[1] == 0x14 && | ||
buffer[22] == ops['OP_EQUAL']; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.