public static KeyPath FromBytes(byte[] data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (data.Length % 4 != 0) { throw new ArgumentOutOfRangeException("data length is not suited for KeyPath"); } var depth = data.Length / 4; uint[] result = new uint[depth]; for (int i = 0; i < depth; i++) { result[i] = Utils.ToUInt32(data, i * 4, true); } return(new KeyPath(result)); }
public uint256(byte[] vch, bool lendian = true) { if (vch.Length != WIDTH_BYTE) { throw new FormatException("the byte array should be 256 byte long"); } if (!lendian) { vch = vch.Reverse().ToArray(); } pn0 = Utils.ToUInt32(vch, 4 * 0, true); pn1 = Utils.ToUInt32(vch, 4 * 1, true); pn2 = Utils.ToUInt32(vch, 4 * 2, true); pn3 = Utils.ToUInt32(vch, 4 * 3, true); pn4 = Utils.ToUInt32(vch, 4 * 4, true); pn5 = Utils.ToUInt32(vch, 4 * 5, true); pn6 = Utils.ToUInt32(vch, 4 * 6, true); pn7 = Utils.ToUInt32(vch, 4 * 7, true); }
private ExtKey(byte[] bytes, bool isSeed) { if (isSeed) { key = CalculateKey(bytes, out var cc); this.vchChainCode = cc; } else { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } if (bytes.Length != Length) { throw new FormatException($"An extpubkey should be {Length} bytes"); } int i = 0; nDepth = bytes[i]; i++; parentFingerprint = new HDFingerprint(bytes, i); i += 4; nChild = Utils.ToUInt32(bytes, i, false); i += 4; vchChainCode = new byte[32]; Array.Copy(bytes, i, vchChainCode, 0, 32); i += 32; if (bytes[i++] != 0) { throw new FormatException($"Invalid ExtKey"); } var pk = new byte[32]; Array.Copy(bytes, i, pk, 0, 32); key = new Key(pk); } }
internal PSBTInput(BitcoinStream stream, PSBT parent, uint index, TxIn input) : base(parent) { TxIn = input; Index = index; originalScriptSig = TxIn.ScriptSig ?? Script.Empty; originalWitScript = TxIn.WitScript ?? WitScript.Empty; byte[] k = new byte[0]; byte[] v = new byte[0]; try { stream.ReadWriteAsVarString(ref k); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTInput. Failed to Parse key.", e); } while (k.Length != 0) { try { stream.ReadWriteAsVarString(ref v); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTInput. Failed to parse key.", e); } switch (k.First()) { case PSBTConstants.PSBT_IN_NON_WITNESS_UTXO: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for NonWitnessUTXO"); } if (non_witness_utxo != null) { throw new FormatException("Invalid PSBTInput. Duplicate non_witness_utxo"); } non_witness_utxo = this.GetConsensusFactory().CreateTransaction(); non_witness_utxo.FromBytes(v); break; case PSBTConstants.PSBT_IN_WITNESS_UTXO: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for WitnessUTXO"); } if (witness_utxo != null) { throw new FormatException("Invalid PSBTInput. Duplicate witness_utxo"); } if (this.GetConsensusFactory().TryCreateNew <TxOut>(out var txout)) { witness_utxo = txout; } else { witness_utxo = new TxOut(); } witness_utxo.FromBytes(v); break; case PSBTConstants.PSBT_IN_PARTIAL_SIG: var pubkey = new PubKey(k.Skip(1).ToArray()); if (partial_sigs.ContainsKey(pubkey)) { throw new FormatException("Invalid PSBTInput. Duplicate key for partial_sigs"); } partial_sigs.Add(pubkey, new TransactionSignature(v)); break; case PSBTConstants.PSBT_IN_SIGHASH: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for SigHash type"); } if (!(sighash_type is null)) { throw new FormatException("Invalid PSBTInput. Duplicate key for sighash_type"); } if (v.Length != 4) { throw new FormatException("Invalid PSBTInput. SigHash Type is not 4 byte"); } var value = Utils.ToUInt32(v, 0, true); if (!Enum.IsDefined(typeof(SigHash), value)) { throw new FormatException($"Invalid PSBTInput Unknown SigHash Type {value}"); } sighash_type = (SigHash)value; break; case PSBTConstants.PSBT_IN_REDEEMSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for redeem script"); } if (redeem_script != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for redeem_script"); } redeem_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_IN_WITNESSSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for witness script"); } if (witness_script != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for redeem_script"); } witness_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_IN_BIP32_DERIVATION: var pubkey2 = new PubKey(k.Skip(1).ToArray()); if (hd_keypaths.ContainsKey(pubkey2)) { throw new FormatException("Invalid PSBTInput. Duplicate key for hd_keypaths"); } var masterFingerPrint = new HDFingerprint(v.Take(4).ToArray()); KeyPath path = KeyPath.FromBytes(v.Skip(4).ToArray()); hd_keypaths.Add(pubkey2, new RootedKeyPath(masterFingerPrint, path)); break; case PSBTConstants.PSBT_IN_SCRIPTSIG: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for final scriptsig"); } if (final_script_sig != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for final_script_sig"); } final_script_sig = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_IN_SCRIPTWITNESS: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for final script witness"); } if (final_script_witness != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for final_script_witness"); } final_script_witness = new WitScript(v); break; default: if (unknown.ContainsKey(k)) { throw new FormatException("Invalid PSBTInput. Duplicate key for unknown value"); } unknown.Add(k, v); break; } stream.ReadWriteAsVarString(ref k); } }
public DerivationStrategyBase Parse(string str) { if (str == null) { throw new ArgumentNullException(nameof(str)); } str = str.Trim(); HashSet <string> hintedLabels = new HashSet <string>(); var hintDestination = HintScriptPubKey?.GetDestination(); if (hintDestination != null) { if (hintDestination is KeyId) { hintedLabels.Add("legacy"); } if (hintDestination is ScriptId) { hintedLabels.Add("p2sh"); } } else { if (Network.Consensus.SupportSegwit) { hintedLabels.Add("p2sh"); } else { hintedLabels.Add("legacy"); } } try { var result = new DerivationStrategyFactory(Network).Parse(str); return(FindMatch(hintedLabels, result)); } catch { } Dictionary <uint, string[]> electrumMapping = new Dictionary <uint, string[]>(); //Source https://github.com/spesmilo/electrum/blob/9edffd17542de5773e7284a8c8a2673c766bb3c3/lib/bitcoin.py var standard = 0x0488b21eU; electrumMapping.Add(standard, new[] { "legacy" }); var p2wpkh_p2sh = 0x049d7cb2U; electrumMapping.Add(p2wpkh_p2sh, new string[] { "p2sh" }); var p2wpkh = 0x4b24746U; electrumMapping.Add(p2wpkh, Array.Empty <string>()); var parts = str.Split('-'); for (int i = 0; i < parts.Length; i++) { if (IsLabel(parts[i])) { hintedLabels.Add(parts[i].Substring(1, parts[i].Length - 2).ToLowerInvariant()); continue; } try { var data = Network.GetBase58CheckEncoder().DecodeData(parts[i]); if (data.Length < 4) { continue; } var prefix = NU.ToUInt32(data, false); var standardPrefix = NU.ToBytes(Network.NetworkType == NetworkType.Mainnet ? 0x0488b21eU : 0x043587cf, false); for (int ii = 0; ii < 4; ii++) { data[ii] = standardPrefix[ii]; } var derivationScheme = new BitcoinExtPubKey(Network.GetBase58CheckEncoder().EncodeData(data), Network).ToString(); electrumMapping.TryGetValue(prefix, out string[] labels); if (labels != null) { foreach (var label in labels) { hintedLabels.Add(label.ToLowerInvariant()); } } parts[i] = derivationScheme; } catch { continue; } } if (hintDestination != null) { if (hintDestination is WitKeyId) { hintedLabels.Remove("legacy"); hintedLabels.Remove("p2sh"); } } str = string.Join('-', parts.Where(p => !IsLabel(p))); foreach (var label in hintedLabels) { str = $"{str}-[{label}]"; } return(FindMatch(hintedLabels, new DerivationStrategyFactory(Network).Parse(str))); }