public JObject ValidateAddress(string address) { if (string.IsNullOrEmpty(address)) { throw new ArgumentNullException("address"); } var res = new JObject(); res["isvalid"] = false; // P2PKH if (BitcoinPubKeyAddress.IsValid(address, ref this.Network)) { res["isvalid"] = true; } // P2SH else if (BitcoinScriptAddress.IsValid(address, ref this.Network)) { res["isvalid"] = true; } // P2WPKH else if (BitcoinWitPubKeyAddress.IsValid(address, ref this.Network)) { res ["isvalid"] = true; } // P2WSH else if (BitcoinWitScriptAddress.IsValid(address, ref this.Network)) { res ["isvalid"] = true; } return(res); }
private string GetHash(BitcoinAddress address) { BitcoinPubKeyAddress pubkey = address as BitcoinPubKeyAddress; if (pubkey != null) { return(pubkey.Hash.ToString()); } BitcoinScriptAddress script = address as BitcoinScriptAddress; if (script != null) { return(script.Hash.ToString()); } BitcoinWitPubKeyAddress wit1 = address as BitcoinWitPubKeyAddress; if (wit1 != null) { return(wit1.Hash.ToString()); } BitcoinWitScriptAddress wit2 = address as BitcoinWitScriptAddress; if (wit2 != null) { return(wit2.Hash.ToString()); } return(null); }
public ValidatedAddress ValidateAddress(string address) { if (string.IsNullOrEmpty(address)) { throw new ArgumentNullException("address"); } var res = new ValidatedAddress(); res.IsValid = false; // P2WPKH if (BitcoinWitPubKeyAddress.IsValid(address, this.Network, out Exception _)) { res.IsValid = true; } // P2WSH else if (BitcoinWitScriptAddress.IsValid(address, this.Network, out Exception _)) { res.IsValid = true; } // P2PKH else if (BitcoinPubKeyAddress.IsValid(address, this.Network)) { res.IsValid = true; } // P2SH else if (BitcoinScriptAddress.IsValid(address, this.Network)) { res.IsValid = true; } return(res); }
public void CanGenerateScriptFromAddress() { var address = new BitcoinPubKeyAddress(new KeyId("47376c6f537d62177a2c41c4ca9b45829ab99083"), Network.Main); Assert.Equal("OP_DUP OP_HASH160 47376c6f537d62177a2c41c4ca9b45829ab99083 OP_EQUALVERIFY OP_CHECKSIG", address.ScriptPubKey.ToString()); var scriptAddress = new BitcoinScriptAddress(new ScriptId("8f55563b9a19f321c211e9b9f38cdf686ea07845"), Network.Main); Assert.Equal("OP_HASH160 8f55563b9a19f321c211e9b9f38cdf686ea07845 OP_EQUAL", scriptAddress.ScriptPubKey.ToString()); var pubKey = new PubKey("0359d3092e4a8d5f3b3948235b5dec7395259273ccf3c4e9d5e16695a3fc9588d6"); Assert.Equal("OP_DUP OP_HASH160 4d29186f76581c7375d70499afd1d585149d42cd OP_EQUALVERIFY OP_CHECKSIG", pubKey.Hash.ScriptPubKey.ToString()); Assert.Equal("0359d3092e4a8d5f3b3948235b5dec7395259273ccf3c4e9d5e16695a3fc9588d6 OP_CHECKSIG", pubKey.ScriptPubKey.ToString()); var script = new Script("0359d3092e4a8d5f3b3948235b5dec7395259273ccf3c4e9d5e16695a3fc9588d6 OP_CHECKSIG"); Assert.Equal("OP_HASH160 a216e3bce8c1b3adf376731b6cd0b6936c4e053f OP_EQUAL", script.PaymentScript.ToString()); }
private void FormDetails_Load(object sender, EventArgs e) { string address = ""; string bitcoinAddress = ""; string hash = ""; string script = ""; string base58Type = ""; Type type = Address.GetType(); using (new HourGlass()) { switch (type.ToString()) { case "NBitcoin.BitcoinScriptAddress": BitcoinScriptAddress bsa = Address as BitcoinScriptAddress; bitcoinAddress = bsa.ToString(); hash = bsa.Hash.ToString(); script = bsa.ScriptPubKey.ToString(); base58Type = bsa.Type.ToString(); break; case "NBitcoin.BitcoinAddress": BitcoinAddress ba = Address as BitcoinAddress; bitcoinAddress = ba.ToString(); hash = ba.Hash.ToString(); script = ba.ScriptPubKey.ToString(); base58Type = ba.Type.ToString(); break; case "NBitcoin.Stealth.BitcoinStealthAddress": BitcoinStealthAddress stealth = Address as BitcoinStealthAddress; bitcoinAddress = stealth.ToString(); hash = stealth.ScanPubKey.Hash.ToString(); script = stealth.ScanPubKey.ScriptPubKey.ToString(); base58Type = stealth.Type.ToString(); break; case "NBitcoin.BitcoinColoredAddress": BitcoinColoredAddress colored = Address as BitcoinColoredAddress; address = colored.ToString(); bitcoinAddress = colored.Address.ToString(); hash = colored.Address.Hash.ToString(); script = colored.ScriptPubKey.ToString(); base58Type = colored.Type.ToString(); break; default: textBoxType.Text = type.ToString(); break; } } textBoxAddress.Text = address; textBoxBitcoinAddress.Text = bitcoinAddress; textBoxPubHash.Text = hash; textBoxScriptPubKey.Text = script; textBoxType.Text = base58Type; textBoxBitcoinAddress.Focus(); }
public static bool IsValidBitcoinAddress(string address) { try { #pragma warning disable 219 // ReSharper disable once UnusedVariable BitcoinAddress singleAddress = new BitcoinPubKeyAddress(address, Network.Main); return(true); } // ReSharper disable once EmptyGeneralCatchClause catch (Exception) { // ignore for now; move on to next possible case } try { // ReSharper disable once UnusedVariable BitcoinScriptAddress multiSigAddress = new BitcoinScriptAddress(address, Network.Main); return(true); #pragma warning restore 219 } // ReSharper disable once EmptyGeneralCatchClause catch (Exception) { } return(false); // not a valid address, neither single nor multisig }
private void ValidateConversion <T>(TestVector vector, BitcoinAddress address) where T : BitcoinAddress { Assert.NotNull(address); var key = address as T; // Perform some validations Assert.NotNull(key); Assert.Equal(vector.Type, GetAddressType(key)); Assert.Equal(CashFormat.Legacy, GetAddressFormat(key)); Assert.Equal(vector.Legacy, key.ToString()); // Convert to CashAddr format var cashAddrKey = ConvertAddressToCashAddr(key); // And perform some validations Assert.NotNull(cashAddrKey); Assert.Equal(vector.Type, GetAddressType(cashAddrKey)); Assert.Equal(CashFormat.Cashaddr, GetAddressFormat(cashAddrKey)); Assert.Equal(vector.CashAddr, cashAddrKey.ToString()); // Convert back to legacy and validate it var legacyAddrKey = ConvertAddressToLegacy(cashAddrKey); Assert.NotNull(legacyAddrKey); Assert.Equal(vector.Type, GetAddressType(legacyAddrKey)); Assert.Equal(CashFormat.Legacy, GetAddressFormat(legacyAddrKey)); Assert.Equal(vector.Legacy, legacyAddrKey.ToString()); // Raw mode validation var legacyHashBytes = GetHashBytes(legacyAddrKey); var legacyHashString = Encoders.Hex.EncodeData(legacyHashBytes); Assert.Equal(vector.Hash, legacyHashString); var cashAddrHashBytes = GetHashBytes(cashAddrKey); var cashAddrHashString = Encoders.Hex.EncodeData(cashAddrHashBytes); Assert.Equal(vector.Hash, cashAddrHashString); // Try to recreate addresses with hashes switch (address) { case BitcoinPubKeyAddress pubKey: var pubKey2 = new BitcoinPubKeyAddress(pubKey.Hash, pubKey.Network); Assert.Equal(vector.CashAddr, pubKey2.ToString()); break; case BitcoinScriptAddress scriptKey: var scriptKey2 = new BitcoinScriptAddress(scriptKey.Hash, scriptKey.Network); Assert.Equal(vector.CashAddr, scriptKey2.ToString()); break; default: throw new InvalidOperationException(); } }
public IActionResult ValidateAddress([FromQuery] string address) { Guard.NotEmpty(address, nameof(address)); var result = new ValidatedAddress { IsValid = false, Address = address, }; try { // P2WPKH if (BitcoinWitPubKeyAddress.IsValid(address, this.network, out Exception _)) { result.IsValid = true; } // P2WSH else if (BitcoinWitScriptAddress.IsValid(address, this.network, out Exception _)) { result.IsValid = true; } // P2PKH else if (BitcoinPubKeyAddress.IsValid(address, this.network)) { result.IsValid = true; } // P2SH else if (BitcoinScriptAddress.IsValid(address, this.network)) { result.IsValid = true; result.IsScript = true; } } catch (Exception e) { this.logger.LogError("Exception occurred: {0}", e.ToString()); return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString())); } if (result.IsValid) { var scriptPubKey = BitcoinAddress.Create(address, this.network).ScriptPubKey; result.ScriptPubKey = scriptPubKey.ToHex(); result.IsWitness = scriptPubKey.IsWitness(this.network); } return(this.Json(result)); }
public static bool IsBitcoinScriptAddress(string base58, Network network) { try { var notUsed = new BitcoinScriptAddress(base58, network); return(true); } catch (Exception) { return(false); } }
public ValidatedAddress ValidateAddress([FromQuery] string address) { Guard.NotEmpty(address, nameof(address)); var result = new ValidatedAddress { IsValid = false, Address = address, }; try { // P2WPKH if (BitcoinWitPubKeyAddress.IsValid(address, this.network, out Exception _)) { result.IsValid = true; } // P2WSH else if (BitcoinWitScriptAddress.IsValid(address, this.network, out Exception _)) { result.IsValid = true; } // P2PKH else if (BitcoinPubKeyAddress.IsValid(address, this.network)) { result.IsValid = true; } // P2SH else if (BitcoinScriptAddress.IsValid(address, this.network)) { result.IsValid = true; result.IsScript = true; } } catch (Exception e) { this.logger.LogDebug("Exception occurred: {0}", e.ToString()); result.IsValid = false; return(result); } if (result.IsValid) { var scriptPubKey = BitcoinAddress.Create(address, this.network).ScriptPubKey; result.ScriptPubKey = scriptPubKey.ToHex(); result.IsWitness = scriptPubKey.IsWitness(this.network); } return(result); }
public bool IsCoherent() { BitcoinScriptAddress scriptAddress = Address as BitcoinScriptAddress; if (scriptAddress != null && RedeemScript != null) { return(scriptAddress.Hash == RedeemScript.Hash); } if (scriptAddress == null && RedeemScript != null) { return(false); } return(true); }
public ValidatedAddress ValidateAddress(string address) { Guard.NotEmpty(address, nameof(address)); var result = new ValidatedAddress { IsValid = false, Address = address, }; try { // P2WPKH if (BitcoinWitPubKeyAddress.IsValid(address, this.Network, out Exception _)) { result.IsValid = true; } // P2WSH else if (BitcoinWitScriptAddress.IsValid(address, this.Network, out Exception _)) { result.IsValid = true; } // P2PKH else if (BitcoinPubKeyAddress.IsValid(address, this.Network)) { result.IsValid = true; } // P2SH else if (BitcoinScriptAddress.IsValid(address, this.Network)) { result.IsValid = true; result.IsScript = true; } } catch (NotImplementedException) { result.IsValid = false; } if (result.IsValid) { var scriptPubKey = BitcoinAddress.Create(address, this.Network).ScriptPubKey; result.ScriptPubKey = scriptPubKey.ToHex(); result.IsWitness = scriptPubKey.IsWitness(this.Network); } return(result); }
public bool ImportAddress(string address, string label, bool rescan = true, bool p2Sh = false) { Guard.NotEmpty(nameof(address), address); var isP2Pkh = !p2Sh && BitcoinPubKeyAddress.IsValid(address, Network); var isP2Sh = p2Sh && BitcoinScriptAddress.IsValid(address, Network); Guard.Assert(isP2Pkh || isP2Sh); this.watchOnlyWalletManager.WatchAddress(address); if (rescan) { this.RescanBlockChain(null, null); } return(true); }
public async Task <IAddressMainInfo> GetMainInfoAsync(string id) { if (BitcoinAddressHelper.IsBitcoinColoredAddress(id, _appSettings.BcnExploler.UsedNetwork())) { var result = new BitcoinColoredAddress(id, _appSettings.BcnExploler.UsedNetwork()); return(new AddressMainInfo { AddressId = id, ColoredAddress = result.ToWif(), UncoloredAddress = result.Address.ToString(), IsColored = true }); } if (BitcoinAddressHelper.IsBitcoinPubKeyAddress(id, _appSettings.BcnExploler.UsedNetwork())) { var result = new BitcoinPubKeyAddress(id, _appSettings.BcnExploler.UsedNetwork()); return(new AddressMainInfo { AddressId = id, ColoredAddress = result.ToColoredAddress().ToWif(), UncoloredAddress = result.ToString(), IsColored = false }); } if (BitcoinAddressHelper.IsBitcoinScriptAddress(id, _appSettings.BcnExploler.UsedNetwork())) { var result = new BitcoinScriptAddress(id, _appSettings.BcnExploler.UsedNetwork()); return(new AddressMainInfo { AddressId = id, ColoredAddress = result.ToColoredAddress().ToWif(), UncoloredAddress = result.ToString(), IsColored = false }); } return(null); }
public IActionResult ValidateAddress([FromQuery] string address) { try { Guard.NotEmpty(address, nameof(address)); var res = new ValidatedAddress { IsValid = false }; // P2WPKH if (BitcoinWitPubKeyAddress.IsValid(address, this.network, out _)) { res.IsValid = true; } // P2WSH else if (BitcoinWitScriptAddress.IsValid(address, this.network, out _)) { res.IsValid = true; } // P2PKH else if (BitcoinPubKeyAddress.IsValid(address, this.network)) { res.IsValid = true; } // P2SH else if (BitcoinScriptAddress.IsValid(address, this.network)) { res.IsValid = true; } return(Json(res)); } catch (Exception e) { this.logger.LogError("Exception occurred: {0}", e.ToString()); return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString())); } }
public void ScriptKeyAddressConversion() { foreach (var vector in TestVectorArray.Where(x => x.Type == Base58Type.SCRIPT_ADDRESS)) { var addr = BitcoinAddress.Create(vector.Legacy, Network.Main); Assert.NotNull(addr); var legacyScriptKey = new BitcoinScriptAddress(vector.Legacy); Assert.Equal(vector.Legacy, legacyScriptKey.ToString()); Assert.Equal(Network.Main, legacyScriptKey.Network); Assert.Equal(vector.Hash, Encoders.Hex.EncodeData(legacyScriptKey.Hash.ToBytes())); var cashAddrScriptKey = new BitcoinScriptAddress(vector.CashAddr); Assert.Equal(vector.CashAddr, cashAddrScriptKey.ToString()); Assert.Equal(Network.Main, cashAddrScriptKey.Network); Assert.Equal(vector.Hash, Encoders.Hex.EncodeData(cashAddrScriptKey.Hash.ToBytes())); ValidateConversion <BitcoinScriptAddress>(vector, addr); } }
public void CanCreateAssetAddress() { //The issuer first generates a private key: 18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725. var key = new Key(TestUtils.ParseHex("18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725")); //He calculates the corresponding address: 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM. BitcoinPubKeyAddress address = key.PubKey.Decompress().GetAddress(this.networkMain); Assert.Equal("16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM", address.ToString()); //Next, he builds the Pay-to-PubKey-Hash script associated to that address: OP_DUP OP_HASH160 010966776006953D5567439E5E39F86A0D273BEE OP_EQUALVERIFY OP_CHECKSIG Script script = address.ScriptPubKey; Assert.Equal("OP_DUP OP_HASH160 010966776006953D5567439E5E39F86A0D273BEE OP_EQUALVERIFY OP_CHECKSIG", script.ToString().ToUpper()); BitcoinScriptAddress oo = script.GetScriptAddress(this.networkMain); //The script is hashed: 36e0ea8e93eaa0285d641305f4c81e563aa570a2. Assert.Equal("36e0ea8e93eaa0285d641305f4c81e563aa570a2", script.Hash.ToString()); Assert.Equal("36e0ea8e93eaa0285d641305f4c81e563aa570a2", key.PubKey.Decompress().Hash.ScriptPubKey.Hash.ToString()); //Finally, the hash is converted to a base 58 string with checksum using version byte 23: ALn3aK1fSuG27N96UGYB1kUYUpGKRhBuBC. Assert.Equal("ALn3aK1fSuG27N96UGYB1kUYUpGKRhBuBC", script.Hash.ToAssetId().GetWif(this.networkMain).ToString()); }
public Script GetRedeemScript(BitcoinScriptAddress address) { return GetRedeemScript(address.ScriptPubKey); }
public async Task AcceptToMemoryPool_WithP2SHValidTxns_IsSuccessfullAsync() { string dataDir = Path.Combine("TestData", nameof(MempoolValidatorTest), nameof(this.AcceptToMemoryPool_WithP2SHValidTxns_IsSuccessfullAsync)); Directory.CreateDirectory(dataDir); BitcoinSecret miner = new BitcoinSecret(new Key(), Network.PurpleRegTest); ITestChainContext context = await TestChainFactory.CreateAsync(Network.PurpleRegTest, miner.PubKey.Hash.ScriptPubKey, dataDir); IMempoolValidator validator = context.MempoolValidator; Assert.NotNull(validator); BitcoinSecret alice = new BitcoinSecret(new Key(), Network.PurpleRegTest); BitcoinSecret bob = new BitcoinSecret(new Key(), Network.PurpleRegTest); BitcoinSecret satoshi = new BitcoinSecret(new Key(), Network.PurpleRegTest); BitcoinSecret nico = new BitcoinSecret(new Key(), Network.PurpleRegTest); // corp needs two out of three of alice, bob, nico Script corpMultiSig = PayToMultiSigTemplate .Instance .GenerateScriptPubKey(2, new[] { alice.PubKey, bob.PubKey, nico.PubKey }); // P2SH address for corp multi-sig BitcoinScriptAddress corpRedeemAddress = corpMultiSig.GetScriptAddress(Network.PurpleRegTest); // Fund corp // 50 Coins come from first tx on chain - send corp 42 and change back to miner Coin coin = new Coin(context.SrcTxs[0].GetHash(), 0, context.SrcTxs[0].TotalOut, miner.ScriptPubKey); TransactionBuilder txBuilder = new TransactionBuilder(); Transaction fundP2shTx = txBuilder .AddCoins(new List <Coin> { coin }) .AddKeys(miner) .Send(corpRedeemAddress, "42.00") .SendFees("0.001") .SetChange(miner.GetAddress()) .BuildTransaction(true); Assert.True(txBuilder.Verify(fundP2shTx)); //check fully signed MempoolValidationState state = new MempoolValidationState(false); Assert.True(await validator.AcceptToMemoryPool(state, fundP2shTx), $"Transaction: {nameof(fundP2shTx)} failed mempool validation."); // AliceBobNico corp. send 20 to Satoshi Coin[] corpCoins = fundP2shTx.Outputs .Where(o => o.ScriptPubKey == corpRedeemAddress.ScriptPubKey) .Select(o => new ScriptCoin(new OutPoint(fundP2shTx.GetHash(), fundP2shTx.Outputs.IndexOf(o)), o, corpMultiSig)) .ToArray(); txBuilder = new TransactionBuilder(); Transaction p2shSpendTx = txBuilder .AddCoins(corpCoins) .AddKeys(alice, bob) .Send(satoshi.GetAddress(), "20") .SendFees("0.001") .SetChange(corpRedeemAddress) .BuildTransaction(true); Assert.True(txBuilder.Verify(p2shSpendTx)); Assert.True(await validator.AcceptToMemoryPool(state, p2shSpendTx), $"Transaction: {nameof(p2shSpendTx)} failed mempool validation."); Directory.Delete(dataDir, true); }
private CreationCommitmentResult CreateCommitmentTransaction(IWalletAddress wallet, PubKey lockedPubKey, PubKey unlockedPubKey, PubKey revokePubKey, PubKey multisigPairPubKey, IAsset asset, decimal lockedAmount, decimal unlockedAmount, string channelTr) { var multisig = new BitcoinScriptAddress(wallet.MultisigAddress, _connectionParams.Network); var channel = new Transaction(channelTr); var spendCoin = FindCoin(channel, multisig.ToString(), wallet.RedeemScript, lockedAmount + unlockedAmount, asset); if (spendCoin == null) { throw new BackendException($"Not found output in setup channel with amount {lockedAmount + unlockedAmount}", ErrorCode.NoCoinsFound); } TransactionBuilder builder = new TransactionBuilder(); builder.AddCoins(spendCoin); long additionalBtc = 0; var script = CreateOffchainScript(multisigPairPubKey, revokePubKey, lockedPubKey); var unlockedAddress = unlockedPubKey.GetAddress(_connectionParams.Network); var lockedAddress = script.GetScriptAddress(_connectionParams.Network); if (OpenAssetsHelper.IsBitcoin(asset.Id)) { if (unlockedAmount > 0) { builder.Send(unlockedAddress, new Money(unlockedAmount, MoneyUnit.BTC)); } if (lockedAmount > 0) { builder.Send(lockedAddress, new Money(lockedAmount, MoneyUnit.BTC)); } } else { var sendAmount = ((ColoredCoin)spendCoin).Bearer.Amount; var dustAmount = 0L; var assetId = new BitcoinAssetId(asset.BlockChainAssetId).AssetId; if (unlockedAmount > 0) { builder.SendAsset(unlockedAddress, new AssetMoney(assetId, unlockedAmount, asset.MultiplierPower)); dustAmount += new TxOut(Money.Zero, unlockedAddress.ScriptPubKey).GetDustThreshold(builder.StandardTransactionPolicy.MinRelayTxFee); } if (lockedAmount > 0) { builder.Send(lockedAddress, new AssetMoney(assetId, lockedAmount, asset.MultiplierPower)); dustAmount += new TxOut(Money.Zero, lockedAddress.ScriptPubKey).GetDustThreshold(builder.StandardTransactionPolicy.MinRelayTxFee); } additionalBtc = dustAmount - sendAmount; } var fakeFee = new Money(1, MoneyUnit.BTC); var fakeAmount = additionalBtc + fakeFee; builder.SendFees(fakeFee); _transactionBuildHelper.AddFakeInput(builder, fakeAmount); var tr = builder.BuildTransaction(true); _transactionBuildHelper.RemoveFakeInput(tr); return(new CreationCommitmentResult(tr, lockedAddress.ToString(), script.ToHex())); }
public void NewCreateBasicSwap(uint path, params string[] seed) { List <ExtKey> keys = new List <ExtKey>(); Segwit segwit = new Segwit(NBitcoin.Network.TestNet); for (int i = 0; i < seed.Length; i++) { var key = GetKey(path, seed[i]); //var address = segwit.GetP2SHAddress(key); keys.Add(key); //Console.WriteLine(address.ToString()); } NBitcoin.Network _Network = NBitcoin.Network.TestNet; MultiSig multi = new MultiSig(NBitcoin.Network.TestNet); List <PubKey> pubKeys = new List <PubKey>(); for (int i = 0; i < keys.Count; i++) { pubKeys.Add(keys[i].PrivateKey.PubKey); } Script pubKeyScript = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, pubKeys.ToArray()); BitcoinAddress address = pubKeyScript.WitHash.GetAddress(_Network); BitcoinScriptAddress p2sh = address.GetScriptAddress(); Console.WriteLine("Send money here: " + p2sh.ToString()); REST.BlockExplorer explorer = new REST.BlockExplorer("https://testnet.blockexplorer.com/"); var response = explorer.GetUnspent(p2sh.ToString()); List <ExplorerUnspent> unspent = response.Convert <List <ExplorerUnspent> >(); List <Transaction> transactions = new List <Transaction>(); foreach (var item in unspent) { ExplorerResponse txResponse = explorer.GetTransaction(item.txid); RawFormat format = RawFormat.Satoshi; var tx = Transaction.Parse(txResponse.data, format, Network.TestNet); transactions.Add(tx); } //Create send transaction. //get redeem script //var redeemScript = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, pubKeys.ToArray());// multi.GetRedeemScript(2, keys.ToArray()); Transaction received = transactions[0]; ScriptCoin coin = received.Outputs.AsCoins().First().ToScriptCoin(pubKeyScript.WitHash.ScriptPubKey.Hash.ScriptPubKey); //create transaction: BitcoinAddress destination = BitcoinAddress.Create("2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF"); //the faucet return address TransactionBuilder builder = new TransactionBuilder(); builder.AddCoins(coin); builder.Send(destination, Money.Coins(1.299m)); builder.SendFees(Money.Coins(0.001m)); builder.SetChange(destination); //builder. var unsigned = builder.BuildTransaction(sign: false); var signedA = builder.AddCoins(coin).AddKeys(keys[0].PrivateKey).SignTransaction(unsigned); Transaction signedB = builder.AddCoins(coin).AddKeys(keys[1].PrivateKey).SignTransaction(signedA); Transaction fullySigned = builder.AddCoins(coin).CombineSignatures(signedA, signedB); Console.WriteLine(fullySigned.ToHex()); Console.ReadLine(); }
public void CanGenerateScriptFromAddress() { var address = new BitcoinPubKeyAddress(new KeyId("47376c6f537d62177a2c41c4ca9b45829ab99083"), Network.Main); Assert.Equal("OP_DUP OP_HASH160 47376c6f537d62177a2c41c4ca9b45829ab99083 OP_EQUALVERIFY OP_CHECKSIG", address.ScriptPubKey.ToString()); var scriptAddress = new BitcoinScriptAddress(new ScriptId("8f55563b9a19f321c211e9b9f38cdf686ea07845"), Network.Main); Assert.Equal("OP_HASH160 8f55563b9a19f321c211e9b9f38cdf686ea07845 OP_EQUAL", scriptAddress.ScriptPubKey.ToString()); var pubKey = new PubKey("0359d3092e4a8d5f3b3948235b5dec7395259273ccf3c4e9d5e16695a3fc9588d6"); Assert.Equal("OP_DUP OP_HASH160 4d29186f76581c7375d70499afd1d585149d42cd OP_EQUALVERIFY OP_CHECKSIG", pubKey.Hash.ScriptPubKey.ToString()); Assert.Equal("0359d3092e4a8d5f3b3948235b5dec7395259273ccf3c4e9d5e16695a3fc9588d6 OP_CHECKSIG", pubKey.ScriptPubKey.ToString()); Script script = new Script("0359d3092e4a8d5f3b3948235b5dec7395259273ccf3c4e9d5e16695a3fc9588d6 OP_CHECKSIG"); Assert.Equal("OP_HASH160 a216e3bce8c1b3adf376731b6cd0b6936c4e053f OP_EQUAL", script.PaymentScript.ToString()); }
public Script GetRedeemScript(BitcoinScriptAddress address) { return(GetRedeemScript(address.ScriptPubKey)); }
public async Task <string> CreateUnsignedChannel(string clientPubKey, string hotWalletPubKey, decimal clientAmount, decimal hubAmount, IAsset asset) { var address = await _multisigService.GetMultisig(clientPubKey); if (address == null) { throw new BackendException($"Client {clientPubKey} is not registered", ErrorCode.BadInputParameter); } var multisig = new BitcoinScriptAddress(address.MultisigAddress, _connectionParams.Network); var clientAddress = new PubKey(clientPubKey).GetAddress(_connectionParams.Network); var hotWalletAddress = new PubKey(hotWalletPubKey).GetAddress(_connectionParams.Network); TransactionBuildContext context = new TransactionBuildContext(_connectionParams.Network, _pregeneratedOutputsQueueFactory); var currentChannel = await _offchainChannelRepository.GetChannel(address.MultisigAddress, asset.Id); if (currentChannel != null && !currentChannel.IsBroadcasted) { throw new BackendException("There is another pending channel setup", ErrorCode.AnotherChannelSetupExists); } return(await context.Build(async() => { var builder = new TransactionBuilder(); var multisigAmount = await SendToMultisig(multisig, multisig, asset, builder, context, -1); decimal clientChannelAmount, hubChannelAmount; if (currentChannel == null) { clientChannelAmount = Math.Max(0, clientAmount - multisigAmount); hubChannelAmount = hubAmount; await SendToMultisig(clientAddress, multisig, asset, builder, context, clientChannelAmount); await SendToMultisig(hotWalletAddress, multisig, asset, builder, context, hubAmount); clientChannelAmount += multisigAmount; } else { clientChannelAmount = Math.Max(0, clientAmount - currentChannel.ClientAmount); hubChannelAmount = Math.Max(0, hubAmount - currentChannel.HubAmount); await SendToMultisig(clientAddress, multisig, asset, builder, context, clientChannelAmount); await SendToMultisig(hotWalletAddress, multisig, asset, builder, context, hubChannelAmount); clientChannelAmount += currentChannel.ClientAmount; hubChannelAmount += currentChannel.HubAmount; } await _transactionBuildHelper.AddFee(builder, context); var tr = builder.BuildTransaction(true); _transactionBuildHelper.AggregateOutputs(tr); var hex = tr.ToHex(); var channel = await _offchainChannelRepository.CreateChannel(multisig.ToString(), asset.Id, hex, clientChannelAmount, hubChannelAmount); await _broadcastedOutputRepository.InsertOutputs(OpenAssetsHelper.OrderBasedColoringOutputs(tr, context) .Select(o => new BroadcastedOutput(o, channel.ChannelId, _connectionParams.Network))); return hex; })); }