private Transaction CreateDepositTransaction(BitcoinPubKeyAddress targetAddress, Block block, Money depositAmount, byte[] opReturnBytes) { // Create the deposit transaction. Transaction depositTransaction = this.transactionBuilder.BuildOpReturnTransaction(this.addressHelper.SourceChainMultisigAddress, opReturnBytes, depositAmount); // Add the deposit transaction to the block. block.AddTransaction(depositTransaction); this.opReturnDataReader.TryGetTargetAddress(depositTransaction, out string _).Returns(callInfo => { callInfo[1] = targetAddress.ToString(); return(true); }); return(depositTransaction); }
public void ExtractDepositsFromBlock_Should_Only_Find_Deposits_To_Multisig() { Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); BitcoinPubKeyAddress targetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress(); byte[] opReturnBytes = Encoding.UTF8.GetBytes(targetAddress.ToString()); long depositAmount = Money.COIN * 3; Transaction depositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, opReturnBytes, depositAmount); block.AddTransaction(depositTransaction); this.opReturnDataReader.TryGetTargetAddress(depositTransaction) .Returns(targetAddress.ToString()); Transaction nonDepositTransactionToMultisig = this.transactionBuilder.BuildTransaction( this.addressHelper.SourceChainMultisigAddress); block.AddTransaction(nonDepositTransactionToMultisig); BitcoinPubKeyAddress otherAddress = this.addressHelper.GetNewSourceChainPubKeyAddress(); otherAddress.ToString().Should().NotBe(this.addressHelper.SourceChainMultisigAddress.ToString(), "otherwise the next deposit should actually be extracted"); Transaction depositTransactionToOtherAddress = this.transactionBuilder.BuildOpReturnTransaction(otherAddress, opReturnBytes); block.AddTransaction(depositTransactionToOtherAddress); Transaction nonDepositTransactionToOtherAddress = this.transactionBuilder.BuildTransaction( otherAddress); block.AddTransaction(nonDepositTransactionToOtherAddress); int blockHeight = 230; IReadOnlyList <IDeposit> extractedDeposits = this.depositExtractor.ExtractDepositsFromBlock(block, blockHeight); extractedDeposits.Count.Should().Be(1); IDeposit extractedTransaction = extractedDeposits[0]; extractedTransaction.Amount.Satoshi.Should().Be(depositAmount); extractedTransaction.Id.Should().Be(depositTransaction.GetHash()); extractedTransaction.TargetAddress.Should().Be(targetAddress.ToString()); extractedTransaction.BlockNumber.Should().Be(blockHeight); extractedTransaction.BlockHash.Should().Be(block.GetHash()); }
/// <summary> /// Creates a number of additional addresses in the current account. /// </summary> /// <remarks> /// The name given to the account is of the form "account (i)" by default, where (i) is an incremental index starting at 0. /// According to BIP44, an account at index (i) can only be created when the account at index (i - 1) contains at least one transaction. /// </remarks> /// <param name="network">The network these addresses will be for.</param> /// <param name="addressesQuantity">The number of addresses to create.</param> /// <param name="isChange">Whether the addresses added are change (internal) addresses or receiving (external) addresses.</param> /// <returns>The created addresses.</returns> public IEnumerable <HdAddress> CreateAddresses(Network network, int addressesQuantity, bool isChange = false) { ICollection <HdAddress> addresses = isChange ? this.InternalAddresses : this.ExternalAddresses; // Get the index of the last address. int firstNewAddressIndex = 0; if (addresses.Any()) { firstNewAddressIndex = addresses.Max(add => add.Index) + 1; } var addressesCreated = new List <HdAddress>(); for (int i = firstNewAddressIndex; i < firstNewAddressIndex + addressesQuantity; i++) { // Generate a new address. PubKey pubkey = HdOperations.GeneratePublicKey(this.ExtendedPubKey, i, isChange); BitcoinPubKeyAddress address = pubkey.GetAddress(network); // Add the new address details to the list of addresses. var newAddress = new HdAddress { Index = i, HdPath = HdOperations.CreateHdPath((int)this.GetCoinType(), this.Index, isChange, i), ScriptPubKey = address.ScriptPubKey, Pubkey = pubkey.ScriptPubKey, Address = address.ToString(), Transactions = new List <TransactionData>() }; addresses.Add(newAddress); addressesCreated.Add(newAddress); } if (isChange) { this.InternalAddresses = addresses; } else { this.ExternalAddresses = addresses; } return(addressesCreated); }
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 void PublicKeyAddressConversion() { foreach (var vector in TestVectorArray.Where(x => x.Type == Base58Type.PUBKEY_ADDRESS)) { var addr = BitcoinAddress.Create(vector.Legacy, Network.Main); Assert.NotNull(addr); var legacyPubKey = new BitcoinPubKeyAddress(vector.Legacy); Assert.Equal(vector.Legacy, legacyPubKey.ToString()); Assert.Equal(Network.Main, legacyPubKey.Network); Assert.Equal(vector.Hash, Encoders.Hex.EncodeData(legacyPubKey.Hash.ToBytes())); var cashAddrPubKey = new BitcoinPubKeyAddress(vector.CashAddr); Assert.Equal(vector.CashAddr, cashAddrPubKey.ToString()); Assert.Equal(Network.Main, cashAddrPubKey.Network); Assert.Equal(vector.Hash, Encoders.Hex.EncodeData(cashAddrPubKey.Hash.ToBytes())); ValidateConversion <BitcoinPubKeyAddress>(vector, addr); } }
public void ExtractDepositsFromBlockShouldOnlyGetAmountsGreaterThanWithdrawalFee() { Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); BitcoinPubKeyAddress targetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress(); byte[] opReturnBytes = Encoding.UTF8.GetBytes(targetAddress.ToString()); // Set amount to be less than deposit minimum long depositAmount = FederatedPegSettings.CrossChainTransferMinimum - 1; Transaction depositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, opReturnBytes, depositAmount); block.AddTransaction(depositTransaction); this.opReturnDataReader.TryGetTargetAddress(depositTransaction, out string unused1).Returns(callInfo => { callInfo[1] = targetAddress.ToString(); return(true); }); // Set amount to be exactly deposit minimum long secondDepositAmount = FederatedPegSettings.CrossChainTransferMinimum; Transaction secondDepositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, opReturnBytes, secondDepositAmount); block.AddTransaction(secondDepositTransaction); this.opReturnDataReader.TryGetTargetAddress(secondDepositTransaction, out string unused2).Returns(callInfo => { callInfo[1] = targetAddress.ToString(); return(true); }); // Set amount to be greater than deposit minimum long thirdDepositAmount = FederatedPegSettings.CrossChainTransferMinimum + 1; Transaction thirdDepositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, opReturnBytes, thirdDepositAmount); block.AddTransaction(thirdDepositTransaction); this.opReturnDataReader.TryGetTargetAddress(thirdDepositTransaction, out string unused3).Returns(callInfo => { callInfo[1] = targetAddress.ToString(); return(true); });// Extract deposits int blockHeight = 12345; IReadOnlyList <IDeposit> extractedDeposits = this.depositExtractor.ExtractDepositsFromBlock(block, blockHeight); // Should only be two, with the value just over the withdrawal fee. extractedDeposits.Count.Should().Be(2); foreach (IDeposit extractedDeposit in extractedDeposits) { Assert.True(extractedDeposit.Amount >= FederatedPegSettings.CrossChainTransferMinimum); } }
public async Task ExtractLargeConversionDeposits_ReturnDeposits_AboveNormalThresholdAsync() { Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); // Create the target address. BitcoinPubKeyAddress targetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress(); byte[] opReturnBytes = Encoding.UTF8.GetBytes(targetAddress.ToString()); // Set amount to be less than deposit minimum CreateDepositTransaction(targetAddress, block, FederatedPegSettings.CrossChainTransferMinimum - 1, opReturnBytes); // Set amount to be less than the small threshold amount. CreateDepositTransaction(targetAddress, block, this.federationSettings.SmallDepositThresholdAmount - 1, opReturnBytes); // Set amount to be exactly the normal threshold amount. CreateDepositTransaction(targetAddress, block, this.federationSettings.NormalDepositThresholdAmount, opReturnBytes); byte[] ethOpReturnBytes = Encoding.UTF8.GetBytes(InterFluxOpReturnEncoder.Encode(DestinationChain.ETH, TargetETHAddress)); // Set amount to be equal to the normal threshold amount. CreateConversionTransaction(block, DepositValidationHelper.ConversionTransactionMinimum - 1, ethOpReturnBytes); // Set amount to be greater than the conversion deposit minimum amount. CreateConversionTransaction(block, DepositValidationHelper.ConversionTransactionMinimum + 1, ethOpReturnBytes); int blockHeight = 12345; IReadOnlyList <IDeposit> extractedDeposits = await this.depositExtractor.ExtractDepositsFromBlock(block, blockHeight, this.retrievalTypeConfirmations); // Should only be 1, with the value just over the withdrawal fee. IEnumerable <IDeposit> applicable = extractedDeposits.Where(d => d.RetrievalType == DepositRetrievalType.ConversionLarge); applicable.Count().Should().Be(1); foreach (IDeposit extractedDeposit in applicable) { Assert.True(extractedDeposit.Amount > DepositValidationHelper.ConversionTransactionMinimum); Assert.Equal(TargetETHAddress, extractedDeposit.TargetAddress); } }
static string[] ReadMsgTxn(string MsgData) { byte[] bts = MsgData.ToLower().HexToByteArray(); string TxnHex = WriteBts(bts, 0, 16).ToHex(); string LinkedTxn = WriteBts(bts, 16, 16).ToHex(); string FromAddress = WriteBts(bts, 32, 20).ToHex(); string Signature = WriteBts(bts, 52, 65).ToHex(); string Message = WriteBts(bts, 117, bts.Length - 117).ToHex(); if (!string.IsNullOrEmpty(LinkedTxn) && LinkedTxn.HexToByteArray().Length != 16) { return(null); } if (TxnHex.HexToByteArray().Length != 16) { return(null); } System.Security.Cryptography.MD5 sha1 = System.Security.Cryptography.MD5.Create(); if (TxnHex != sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(FromAddress + Signature + Message)).ToHex()) { return(null); } Network net = Network.Main; BitcoinPubKeyAddress bitcoinPubKeyAddress = new BitcoinPubKeyAddress(new KeyId(FromAddress.HexToByteArray()), net); Message = System.Text.Encoding.UTF8.GetString(Message.HexToByteArray()); Signature = Convert.ToBase64String(Signature.HexToByteArray()); FromAddress = bitcoinPubKeyAddress.ToString(); if (bitcoinPubKeyAddress.VerifyMessage(Message, Signature) == false) { return(null); } return(new string[] { TxnHex, FromAddress, Signature, Message, LinkedTxn }); }
public void BuildTransactionUsesGivenChangeAddress() { WalletTransactionHandlerTestContext testContext = SetupWallet(); TransactionBuildContext context = CreateContext(this.Network, testContext.WalletReference, "password", testContext.DestinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0); var key = new Key(); BitcoinPubKeyAddress address = key.PubKey.GetAddress(this.Network); HdAddress changeAddress = context.ChangeAddress = new HdAddress { Index = 0, HdPath = $"m/44'/0'/0'/0/0", Address = address.ToString(), Pubkey = key.PubKey.ScriptPubKey, ScriptPubKey = address.ScriptPubKey, //Transactions = new List<TransactionData>() }; Transaction transactionResult = testContext.WalletTransactionHandler.BuildTransaction(context); Transaction result = this.Network.CreateTransaction(transactionResult.ToHex()); Assert.Single(result.Inputs); Assert.Equal(testContext.AddressTransaction.Id, result.Inputs[0].PrevOut.Hash); Assert.Equal(2, result.Outputs.Count); TxOut output = result.Outputs[0]; Assert.Equal((testContext.AddressTransaction.Amount - context.TransactionFee - 7500), output.Value); Assert.Equal(changeAddress.ScriptPubKey, output.ScriptPubKey); output = result.Outputs[1]; Assert.Equal(7500, output.Value); Assert.Equal(testContext.DestinationKeys.PubKey.ScriptPubKey, output.ScriptPubKey); Assert.Equal(testContext.AddressTransaction.Amount - context.TransactionFee, result.TotalOut); Assert.NotNull(transactionResult.GetHash()); Assert.Equal(result.GetHash(), transactionResult.GetHash()); }
/// <summary> /// Interactive example that walks through creating, signing, and broadcasting a Dash transaction. /// Make sure you have Dash Core wallet running on TestNet for this example to work. /// </summary> public static void RunExample() { // Create a new HD extended private key ExtKey extKey = CreateExtKey(); // Derive a child address so we can send it some coins var extPubKey = extKey.Neuter().GetWif(_network); int customerId = 1234567; string keyDerivationPath = $"{customerId}/0"; BitcoinPubKeyAddress childAddress = DeriveChildAddress(extPubKey.ToString(), keyDerivationPath); // Watch this address in your core wallet so that you can monitor it for funds RPCClient rpc = GetRpcClient(); rpc.ImportAddress(childAddress, $"Customer {customerId}", false); // Send some coins manually to the address just created Console.WriteLine($"Now, go to another wallet and send some coins to address {childAddress}."); Console.WriteLine($"Wait a few minutes for it to confirm, then press ENTER to continue."); Console.ReadLine(); // Create and sign a transaction that spends the coins received by the address above. Console.WriteLine($"Enter an address of yours to which you want to receive coins:"); string toAddr = Console.ReadLine(); Console.WriteLine($"Enter the amount to spend:"); string spend = Console.ReadLine(); decimal minerFee = 0.00001m; decimal amountToSpend = Convert.ToDecimal(spend) - minerFee; Key privateKey = extKey.Derive(KeyPath.Parse(keyDerivationPath)).PrivateKey; var transaction = CreateAndSignTransaction(childAddress.ToString(), toAddr, amountToSpend, privateKey); // Finally, broadcast transaction to network rpc.SendRawTransaction(transaction); }
public void ExtractNormalDeposits_Should_Only_Find_Deposits_To_Multisig() { Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); BitcoinPubKeyAddress targetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress(); byte[] opReturnBytes = Encoding.UTF8.GetBytes(targetAddress.ToString()); // Create a deposit above the small deposit threshold. Transaction depositTransaction = CreateDepositTransaction(targetAddress, block, Money.Coins(11), opReturnBytes); Transaction nonDepositTransactionToMultisig = this.transactionBuilder.BuildTransaction(this.addressHelper.SourceChainMultisigAddress); block.AddTransaction(nonDepositTransactionToMultisig); BitcoinPubKeyAddress otherAddress = this.addressHelper.GetNewSourceChainPubKeyAddress(); otherAddress.ToString().Should().NotBe(this.addressHelper.SourceChainMultisigAddress.ToString(), "otherwise the next deposit should actually be extracted"); Transaction depositTransactionToOtherAddress = this.transactionBuilder.BuildOpReturnTransaction(otherAddress, opReturnBytes); block.AddTransaction(depositTransactionToOtherAddress); Transaction nonDepositTransactionToOtherAddress = this.transactionBuilder.BuildTransaction(otherAddress); block.AddTransaction(nonDepositTransactionToOtherAddress); int blockHeight = 230; IReadOnlyList <IDeposit> extractedDeposits = this.depositExtractor.ExtractDepositsFromBlock(block, blockHeight, new[] { DepositRetrievalType.Normal }); extractedDeposits.Count.Should().Be(1); IDeposit extractedTransaction = extractedDeposits[0]; extractedTransaction.Amount.Satoshi.Should().Be(Money.Coins(11)); extractedTransaction.Id.Should().Be(depositTransaction.GetHash()); extractedTransaction.TargetAddress.Should().Be(targetAddress.ToString()); extractedTransaction.BlockNumber.Should().Be(blockHeight); extractedTransaction.BlockHash.Should().Be(block.GetHash()); }
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 async Task ExtractSmallDeposits_ReturnDeposits_BelowSmallThreshold_AboveMinimumAsync() { Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); // Create the target address. BitcoinPubKeyAddress targetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress(); byte[] opReturnBytes = Encoding.UTF8.GetBytes(targetAddress.ToString()); // Set amount to be less than deposit minimum CreateDepositTransaction(targetAddress, block, FederatedPegSettings.CrossChainTransferMinimum - 1, opReturnBytes); // Set amount to be less than the small threshold amount. CreateDepositTransaction(targetAddress, block, this.federationSettings.SmallDepositThresholdAmount - 1, opReturnBytes); // Set amount to be exactly the small threshold amount. CreateDepositTransaction(targetAddress, block, this.federationSettings.SmallDepositThresholdAmount, opReturnBytes); // Set amount to be greater than the small threshold amount. CreateDepositTransaction(targetAddress, block, this.federationSettings.SmallDepositThresholdAmount + 1, opReturnBytes); // Set amount to be greater than the normal threshold amount. CreateDepositTransaction(targetAddress, block, this.federationSettings.NormalDepositThresholdAmount + 1, opReturnBytes); int blockHeight = 12345; IReadOnlyList <IDeposit> extractedDeposits = await this.depositExtractor.ExtractDepositsFromBlock(block, blockHeight, this.retrievalTypeConfirmations); IEnumerable <IDeposit> applicable = extractedDeposits.Where(d => d.RetrievalType == DepositRetrievalType.Small); // Should only be two, with the value just over the withdrawal fee. applicable.Count().Should().Be(2); foreach (IDeposit extractedDeposit in applicable) { Assert.True(extractedDeposit.Amount <= this.federationSettings.SmallDepositThresholdAmount); } }
public async Task <Transaction> GetTransaction(string id) { var tx = await _client.GetRawTransactionAsync(id); if (tx == null) { return(null); } var transaction = new Transaction { Blockhash = tx.Blockhash, TransactionId = tx.Txid, Size = tx.Size, TransactionIn = new List <In>(), TransactionsOut = new List <Out>(), }; // this fails b/c no input validation // Debug.Assert(id == transaction.TransactionId); int index = 0; foreach (var rpcIn in tx.Vin) { var inp = new In { Index = index }; if (rpcIn.Coinbase == null) { string hexScript = rpcIn.ScriptSig.Hex; byte[] decodedScript = Encoders.Hex.DecodeData(hexScript); Script script = new Script(decodedScript); PayToPubkeyHashTemplate template = new PayToPubkeyHashTemplate(); PayToPubkeyHashScriptSigParameters param = template.ExtractScriptSigParameters(script); if (param != null) { PubKey pubKey = param.PublicKey; BitcoinPubKeyAddress address = pubKey.GetAddress(NetworkSpec.ObsidianMain()); inp.Address = address.ToString(); } else { inp.Address = "none"; } inp.TransactionId = rpcIn.Txid; inp.VOut = (int)rpcIn.Vout; inp.Sequence = rpcIn.Sequence; inp.ScriptSigHex = rpcIn.ScriptSig.Hex; } else { inp.Coinbase = rpcIn.Coinbase; inp.Sequence = rpcIn.Sequence; } transaction.TransactionIn.Add(inp); } if (transaction.TransactionIn[0].Coinbase != null) { //Debug.Assert(transaction.TransactionIn.Count == 1); transaction.IsCoinBase = true; } index = 0; foreach (var output in tx.Vout) { var @out = new Out { TransactionId = transaction.TransactionId, Value = output.Value, Quantity = output.N, AssetId = null, Index = index++ }; if (output.ScriptPubKey.Addresses != null) // Satoshi 14.2 { @out.Address = output.ScriptPubKey.Addresses.FirstOrDefault(); } else { string hexScript = output.ScriptPubKey.Hex; if (!string.IsNullOrEmpty(hexScript)) { byte[] decodedScript = Encoders.Hex.DecodeData(hexScript); Script script = new Script(decodedScript); var pubKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(script); BitcoinPubKeyAddress address = pubKey.GetAddress(NetworkSpec.ObsidianMain()); @out.Address = address.ToString(); } else { @out.Address = "none"; } } transaction.TransactionsOut.Add(@out); } return(transaction); }
public BaseRsp <string> Publish(Models.ContractPublichModel model) { var resault = new BaseRsp <string>(); var net = model.Net == "test" ? NBitcoin.Wicc.Wicc.Instance.Testnet : NBitcoin.Wicc.Wicc.Instance.Mainnet; var apiUrl = "http://rpc.5.me/jsonrpc/" + model.Net; BitcoinPubKeyAddress address = null; try { var secret = new BitcoinSecret(model.PrivKey, net); address = secret.GetAddress(); } catch { resault.data = "提供的私钥有误, 请检查私钥或网络"; return(resault); } if (model.Contract.Length > 64 * 1024) { resault.data = "合约代码长度超过64KB"; return(resault); } var accountInfo = HttpGet(apiUrl + "/GetAccountInfo/" + address.ToString()); if (accountInfo == null) { resault.data = "RPC钱包服务暂时不可用"; return(resault); } var regId = accountInfo.data.regID?.ToString(); if (string.IsNullOrEmpty(regId)) { resault.data = "该地址未激活"; return(resault); } else if (long.Parse(accountInfo.data.balance.ToString()) < long.Parse(model.Fee)) { resault.data = "该地址当前余额不足以支付手续费"; return(resault); } WalletServiceApi.Wallet wt = new WalletServiceApi.Wallet() { Network = net, Prikey = model.PrivKey, UserId = new UserId(uint.Parse(regId.Split('-')[0]), uint.Parse(regId.Split('-')[1])) }; var height = HttpGet(apiUrl + "/GetBlockCount"); try { var sign = wt.GetRegisteAppRaw(string.Empty, model.Contract, ulong.Parse(model.Fee), uint.Parse(height.data.ToString())); var submittx = HttpPost <dynamic>(apiUrl + "/SubmitTx", "\"" + sign + "\""); if (!submittx.success) { resault.data = "上链失败: " + submittx.msg; return(resault); } else { resault.data = "交易哈希: " + submittx.data.hash; resault.success = true; return(resault); } } catch (Exception ex) { resault.data = "签名失败: " + ex.Message; return(resault); } resault.success = false; resault.data = "发布失败"; return(resault); }
public BaseRsp <string> DynLoad(Models.ContractDynLoadModel model) { var resault = new BaseRsp <string>(); var apiUrl = "http://rpc.5.me/jsonrpc/test"; BitcoinPubKeyAddress address = null; try { var secret = new BitcoinSecret(model.PrivKey, NBitcoin.Wicc.Wicc.Instance.Testnet); address = secret.GetAddress(); } catch { resault.data = "提供的私钥有误, 请检查私钥或网络"; return(resault); } var accountInfo = HttpGet(apiUrl + "/GetAccountInfo/" + address.ToString()); if (accountInfo == null) { resault.data = "RPC钱包服务暂时不可用"; return(resault); } var regId = accountInfo.data.regID?.ToString(); if (string.IsNullOrEmpty(regId)) { resault.data = "该地址未激活"; return(resault); } else if (long.Parse(accountInfo.data.balance.ToString()) < long.Parse(model.Fee)) { resault.data = "该地址当前余额不足以支付手续费"; return(resault); } WalletServiceApi.Wallet wt = new WalletServiceApi.Wallet() { Network = NBitcoin.Wicc.Wicc.Instance.Testnet, Prikey = model.PrivKey, UserId = new UserId(uint.Parse(regId.Split('-')[0]), uint.Parse(regId.Split('-')[1])) }; var height = HttpGet(apiUrl + "/GetBlockCount"); try { List <byte> codes = new List <byte>() { 0xdd, 0xdd }; codes.AddRange(Encoding.UTF8.GetBytes(model.Contract)); var sign = wt.CreateContractTxRaw("74505-1", codes.ToArray(), ulong.Parse(model.Fee), uint.Parse(height.data.ToString())); var submittx = HttpPost <dynamic>(apiUrl + "/SubmitTx", "\"" + sign + "\""); if (!submittx.success) { resault.data = submittx.msg; return(resault); } else { resault.data = "交易哈希: " + submittx.data.hash; resault.success = true; return(resault); } } catch (Exception ex) { resault.data = "签名失败: " + ex.Message; return(resault); } resault.success = false; resault.data = "发布失败"; return(resault); }
public async Task <Transaction> GetTransaction(string id) { try { GetRawTransactionRpcModel tx = await RpcClient.GetRawTransactionAsync(id); if (tx == null) { return(null); } TransactionType transactiontype = GetTransactionType(tx); var transaction = new Transaction { OriginalJson = tx.OriginalJson, TransactionType = transactiontype, Blockhash = tx.Blockhash, TransactionId = tx.Txid, Size = tx.Size, TransactionIn = new List <VIn>(), TransactionsOut = new List <Out>(), Time = tx.GetTime() }; int index = 0; foreach (var rpcIn in tx.Vin) { var vIn = new VIn { Index = index, Coinbase = rpcIn.Coinbase, Sequence = rpcIn.Sequence, ScriptSigHex = rpcIn.ScriptSig?.Hex, AssetId = null, // pointer to previous tx/vout: PrevTxIdPointer = rpcIn.Txid, PrevVOutPointer = (int)rpcIn.Vout, // we'll try to fetch this id possible PrevVOutFetchedAddress = null, PrevVOutFetchedValue = 0 }; if (rpcIn.Txid != null) { // Retrieve the origin address by retrieving the previous transaction and extracting the receive address and value var previousTx = await RpcClient.GetRawTransactionAsync(rpcIn.Txid); if (previousTx != null) { var n = rpcIn.Vout; Debug.Assert(n == previousTx.Vout[n].N); vIn.PrevVOutFetchedAddress = previousTx.Vout[n].ScriptPubKey.Addresses.First(); vIn.PrevVOutFetchedValue = previousTx.Vout[n].Value; } } transaction.TransactionIn.Add(vIn); } index = 0; foreach (var output in tx.Vout) { var @out = new Out { TransactionId = transaction.TransactionId, Value = output.Value, Quantity = output.N, AssetId = null, Index = index++, }; if (output.ScriptPubKey.Addresses != null) // Satoshi 14.2 { @out.Address = output.ScriptPubKey.Addresses.FirstOrDefault(); } else { string hexScript = output.ScriptPubKey.Hex; if (!string.IsNullOrEmpty(hexScript)) { byte[] decodedScript = Encoders.Hex.DecodeData(hexScript); Script script = new Script(decodedScript); var pubKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(script); if (pubKey != null) { BitcoinPubKeyAddress address = pubKey.GetAddress(NetworkSpec.ObsidianMain()); @out.Address = address.ToString(); } else { @out.Address = script.ToString(); } } else { Debug.Assert(output.ScriptPubKey.Type == NonStandardAddress); @out.Address = output.ScriptPubKey.Type; } } transaction.TransactionsOut.Add(@out); } return(transaction); } catch { } return(null); }
public string GenerateIdentity() { // Generate a fixed identity. string recoveryPhrase = "mystery problem faith negative member bottom concert bundle asthma female process twelve"; var mnemonic = new Mnemonic(recoveryPhrase); ExtKey masterNode = mnemonic.DeriveExtKey(); ExtPubKey walletRoot = masterNode.Derive(new KeyPath("m/44'")).Neuter(); ExtKey identityRoot = masterNode.Derive(new KeyPath("m/302'")); ExtKey identity0 = identityRoot.Derive(0, true); ExtKey identity1 = identityRoot.Derive(1, true); BitcoinPubKeyAddress identity0Address = identity0.PrivateKey.PubKey.GetAddress(profileNetwork); BitcoinPubKeyAddress identity1Address = identity1.PrivateKey.PubKey.GetAddress(profileNetwork); string identity0Id = identity0Address.ToString(); // PTe6MFNouKATrLF5YbjxR1bsei2zwzdyLU string identity1Id = identity1Address.ToString(); // PAcmQwEMW2oxzRBz7u6oFQMtYPSYqoXyiw // Create an identity profile that should be signed and pushed. IdentityModel identityModel = new IdentityModel { Id = identity0Id, Name = "This is a person", ShortName = "None of yoru concern", Alias = "JD", Title = "President of the World", Email = "*****@*****.**" }; byte[] entityBytes = MessagePackSerializer.Serialize(identityModel); // Testing to only sign the name. string signature = identity0.PrivateKey.SignMessage(entityBytes); IdentityDocument identityDocument = new IdentityDocument { Owner = identityModel.Id, Body = identityModel, Signature = signature }; string json = JsonConvert.SerializeObject(identityDocument); RestClient client = CreateClient(); // Get the identity, if it exists. var request = new RestRequest($"/identity/{identityModel.Id}"); IRestResponse <string> response = client.Get <string>(request); //if (response.StatusCode != System.Net.HttpStatusCode.OK) //{ // throw new ApplicationException(response.ErrorMessage); //} string data = response.Data; // Persist the identity. var request2 = new RestRequest($"/identity/{identityModel.Id}"); request2.AddJsonBody(identityDocument); IRestResponse <string> response2 = client.Put <string>(request2); if (response2.StatusCode != System.Net.HttpStatusCode.OK) { throw new ApplicationException(response2.ErrorMessage); } return(identity0Id); }
private async Task FinishOutputs(Guid transactionId, Transaction tr, BitcoinPubKeyAddress hotWallet) { await _broadcastedOutputRepository.InsertOutputs(tr.Outputs.AsCoins() .Where(o => o.ScriptPubKey.GetDestinationAddress(_connectionParams.Network).ToString() == hotWallet.ToString()) .Select(o => new BroadcastedOutput(o, transactionId, _connectionParams.Network))); await _broadcastedOutputRepository.SetTransactionHash(transactionId, tr.GetHash().ToString()); await _spentOutputService.SaveSpentOutputs(transactionId, tr); }
public void ExtractDepositsFromBlock_Should_Create_One_Deposit_Per_Transaction_To_Multisig() { Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); BitcoinPubKeyAddress targetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress(); byte[] opReturnBytes = Encoding.UTF8.GetBytes(targetAddress.ToString()); long depositAmount = Money.COIN * 3; Transaction depositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, opReturnBytes, depositAmount); block.AddTransaction(depositTransaction); this.opReturnDataReader.TryGetTargetAddress(depositTransaction) .Returns(targetAddress.ToString()); //add another deposit to the same address long secondDepositAmount = Money.COIN * 2; Transaction secondDepositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, opReturnBytes, secondDepositAmount); block.AddTransaction(secondDepositTransaction); this.opReturnDataReader.TryGetTargetAddress(secondDepositTransaction) .Returns(targetAddress.ToString()); //add another deposit to a different address string newTargetAddress = this.addressHelper.GetNewTargetChainPubKeyAddress().ToString(); byte[] newOpReturnBytes = Encoding.UTF8.GetBytes(newTargetAddress); long thirdDepositAmount = Money.COIN * 34; Transaction thirdDepositTransaction = this.transactionBuilder.BuildOpReturnTransaction( this.addressHelper.SourceChainMultisigAddress, newOpReturnBytes, thirdDepositAmount); block.AddTransaction(thirdDepositTransaction); this.opReturnDataReader.TryGetTargetAddress(thirdDepositTransaction) .Returns(newTargetAddress); int blockHeight = 12345; IReadOnlyList <IDeposit> extractedDeposits = this.depositExtractor.ExtractDepositsFromBlock(block, blockHeight); extractedDeposits.Count.Should().Be(3); extractedDeposits.Select(d => d.BlockNumber).Should().AllBeEquivalentTo(blockHeight); extractedDeposits.Select(d => d.BlockHash).Should().AllBeEquivalentTo(block.GetHash()); IDeposit extractedTransaction = extractedDeposits[0]; extractedTransaction.Amount.Satoshi.Should().Be(depositAmount); extractedTransaction.Id.Should().Be(depositTransaction.GetHash()); extractedTransaction.TargetAddress.Should() .Be(targetAddress.ToString()); extractedTransaction = extractedDeposits[1]; extractedTransaction.Amount.Satoshi.Should().Be(secondDepositAmount); extractedTransaction.Id.Should().Be(secondDepositTransaction.GetHash()); extractedTransaction.TargetAddress.Should() .Be(targetAddress.ToString()); extractedTransaction = extractedDeposits[2]; extractedTransaction.Amount.Satoshi.Should().Be(thirdDepositAmount); extractedTransaction.Id.Should().Be(thirdDepositTransaction.GetHash()); extractedTransaction.TargetAddress.Should().Be(newTargetAddress); }
public string GenerateRandomIdentity() { // Generate a random seed and new identity. var mnemonic = new Mnemonic(Wordlist.English, WordCount.Twelve); // string recoveryPhrase = ""; // var mnemonic = new Mnemonic(recoveryPhrase); ExtKey masterNode = mnemonic.DeriveExtKey(); ExtPubKey walletRoot = masterNode.Derive(new KeyPath("m/44'")).Neuter(); ExtKey identityRoot = masterNode.Derive(new KeyPath("m/302'")); ExtKey identity0 = identityRoot.Derive(0, true); ExtKey identity1 = identityRoot.Derive(1, true); BitcoinPubKeyAddress identity0Address = identity0.PrivateKey.PubKey.GetAddress(profileNetwork); BitcoinPubKeyAddress identity1Address = identity1.PrivateKey.PubKey.GetAddress(profileNetwork); string identity0Id = identity0Address.ToString(); // Create an identity profile that should be signed and pushed. //Identity identityModel = new Identity //{ // Identifier = identity0Id, // Name = "Blockcore Hub", // Email = "*****@*****.**", // Url = "https://city.hub.liberstad.com", // Image = "https://www.blockcore.net/assets/blockcore-256x256.png" //}; //Identity identityModel = new Identity //{ // Identifier = identity0Id, // Name = "Liberstad Hub", // Email = "*****@*****.**", // Url = "https://city.hub.liberstad.com", // Image = "https://file.city-chain.org/liberstad-square-logo.png" //}; string key = identity0Address.ToString(); string identifier = "did:is:" + key; var identity = new Identity { Identifier = identifier, Name = "John Doe", ShortName = "John", Alias = "JD", Title = "Gone missing", Type = "identity", Timpestamp = ToUnixEpochDate(new DateTime(2020, 2, 2)) }; //JsonWebKey key = new JsonWebKey(); //key.KeyId = identity0Id; var header = new Dictionary <string, object>(); header.Add("typ", "JWT"); header.Add("kid", key); string token = JWT.Encode(identity, identity0.PrivateKey, JwsAlgorithm.ES256K, header); // This should crash with exception: "Blockcore.Jose.JoseException: Payload is missing required signature". Message message = new Message() { Version = 4, Content = token }; RestClient client = CreateClient(); // Persist the identity. var request2 = new RestRequest($"/api/identity"); request2.AddJsonBody(message); IRestResponse <string> response2 = client.Put <string>(request2); if (response2.StatusCode != System.Net.HttpStatusCode.OK) { throw new ApplicationException(response2.ErrorMessage); } return(identity0Id); }
private async Task GenerateAssetOutputs() { await _logger.WriteInfoAsync("GenerateOutputsFunction", "GenerateAssetOutputs", null, "Start process"); var hotWallet = new BitcoinPubKeyAddress(_baseSettings.HotWalletForPregeneratedOutputs, _connectionParams.Network); var assets = (await _assetRepository.GetBitcoinAssets()).Where(o => !string.IsNullOrEmpty(o.AssetAddress) && !o.IsDisabled && o.IssueAllowed).ToList(); foreach (var asset in assets) { try { if (asset.DefinitionUrl == null) { await _logger.WriteWarningAsync("GenerateOutputsFunction", "GenerateAssetOutputs", $"Asset: {asset.Id} has no DefinitionUrl", ""); continue; } var queue = _pregeneratedOutputsQueueFactory.Create(asset.BlockChainAssetId); while (await queue.Count() < _baseSettings.MinPregeneratedAssetOutputsCount) { var coins = await _bitcoinOutputsService.GetUncoloredUnspentOutputs(hotWallet.ToString()); TransactionBuilder builder = new TransactionBuilder(); builder.AddCoins(coins); for (var i = 0; i < _baseSettings.GenerateAssetOutputsBatchSize; i++) { builder.Send(new BitcoinPubKeyAddress(asset.AssetAddress, _connectionParams.Network), _dustSize); } builder.SetChange(hotWallet); builder.SendFees(await _feeProvider.CalcFeeForTransaction(builder)); var signedHex = await _signatureApiProvider.SignTransaction(builder.BuildTransaction(true).ToHex()); var signedTr = new Transaction(signedHex); var transactionId = Guid.NewGuid(); await _bitcoinClient.BroadcastTransaction(signedTr, transactionId); await queue.EnqueueOutputs(signedTr.Outputs.AsCoins() .Where(o => o.ScriptPubKey.GetDestinationAddress(_connectionParams.Network).ToString() == asset.AssetAddress && o.TxOut.Value == _dustSize).ToArray()); await FinishOutputs(transactionId, signedTr, hotWallet); } } catch (Exception e) { await _logger.WriteWarningAsync("GenerateOutputsFunction", "GenerateAssetOutputs", $"Asset {asset.Id}", e); } } await _logger.WriteInfoAsync("GenerateOutputsFunction", "GenerateAssetOutputs", null, "End process"); }