public static void SignAndShowInformation(Transaction tx) { if (tx == null) { MessageBox.Show(Strings.InsufficientFunds); return; } SignatureContext context; try { context = new SignatureContext(tx); } catch (InvalidOperationException) { MessageBox.Show(Strings.UnsynchronizedBlock); return; } Program.CurrentWallet.Sign(context); if (context.Completed) { context.Verifiable.Scripts = context.GetScripts(); Program.CurrentWallet.SaveTransaction(tx); Program.LocalNode.Relay(tx); InformationBox.Show(tx.Hash.ToString(), Strings.SendTxSucceedMessage, Strings.SendTxSucceedTitle); } else { InformationBox.Show(context.ToString(), Strings.IncompletedSignatureMessage, Strings.IncompletedSignatureTitle); } }
public static void SignAndShowInformation(Transaction tx) { if (tx == null) { MessageBox.Show("余额不足以支付系统费用。"); return; } SignatureContext context; try { context = new SignatureContext(tx); } catch (InvalidOperationException) { MessageBox.Show("钱包余额不足,或区块链未同步完成,无法发送该交易。"); return; } Program.CurrentWallet.Sign(context); if (context.Completed) { context.Signable.Scripts = context.GetScripts(); Program.LocalNode.Relay(tx); InformationBox.Show(tx.Hash.ToString(), "交易已发送,这是交易编号(TXID):", "交易成功"); } else { InformationBox.Show(context.ToString(), "交易构造完成,但没有足够的签名:", "签名不完整"); } }
private void CheckSignatures() { if (context.Signatures.Count(p => p != null) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p))) { Contract contract = Contract.CreateMultiSigContract(context.Validators[context.MyIndex].EncodePoint(true).ToScriptHash(), context.M, context.Validators); Block block = context.MakeHeader(); SignatureContext sc = new SignatureContext(block); for (int i = 0, j = 0; i < context.Validators.Length && j < context.M; i++) { if (context.Signatures[i] != null) { sc.AddSignature(contract, context.Validators[i], context.Signatures[i]); j++; } } sc.Verifiable.Scripts = sc.GetScripts(); block.Transactions = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray(); Log($"relay block: {block.Hash}"); if (!localNode.Relay(block)) { Log($"reject block: {block.Hash}"); } context.State |= ConsensusState.BlockSent; } }
private void 资产分发IToolStripMenuItem_Click(object sender, EventArgs e) { using (IssueDialog dialog = new IssueDialog()) { if (dialog.ShowDialog() != DialogResult.OK) { return; } IssueTransaction tx = dialog.GetTransaction(); if (tx == null) { return; } //TODO: 检查是否符合规则,如是否超过总量、分发方式是否符合约定等; SignatureContext context = new SignatureContext(tx); Program.CurrentWallet.Sign(context); if (context.Completed) { context.Signable.Scripts = context.GetScripts(); InformationBox.Show(context.Signable.ToArray().ToHexString(), "分发交易构造完成,并已完整签名,可以广播。"); } else { InformationBox.Show(context.ToString(), "分发交易构造完成,但签名信息还不完整。"); } } }
private void button7_Click(object sender, EventArgs e) { SignatureContext context = SignatureContext.Parse(textBox8.Text); context.Signable.Scripts = context.GetScripts(); InformationBox.Show(context.Signable.ToArray().ToHexString(), "原始数据:"); }
private void button1_Click(object sender, EventArgs e) { if (textBox1.Text == "") { MessageBox.Show("必须输入一段含有待签名数据的JSON对象。"); return; } SignatureContext context = SignatureContext.Parse(textBox1.Text); if (!Program.CurrentWallet.Sign(context)) { MessageBox.Show("没有足够的私钥对数据进行签名。"); return; } if (context.Completed) { context.Signable.Scripts = context.GetScripts(); textBox2.Text = context.Signable.ToArray().ToHexString(); MessageBox.Show("签名完成,该对象的签名信息已经完整,可以广播。"); } else { textBox2.Text = context.ToString(); MessageBox.Show("签名完成,但该对象的签名信息还不完整。"); } }
private void CheckSignatures() { if (context.Signatures.Count(p => p != null) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p))) { Log($"{nameof(CheckSignatures)} {context.Signatures.Count(p => p != null)}/{context.M}"); Contract contract = Contract.CreateMultiSigContract(context.Miners[context.MinerIndex].EncodePoint(true).ToScriptHash(), context.M, context.Miners); Block block = context.MakeHeader(); SignatureContext sc = new SignatureContext(block); for (int i = 0; i < context.Miners.Length; i++) { if (context.Signatures[i] != null) { sc.Add(contract, context.Miners[i], context.Signatures[i]); } } sc.Signable.Scripts = sc.GetScripts(); block.Transactions = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray(); Log($"RelayBlock hash:{block.Hash}"); if (!LocalNode.Relay(block)) { Log($"failed hash:{block.Hash}"); } context.State |= ConsensusState.BlockSent; } }
private void button4_Click(object sender, EventArgs e) { context.Signable.Scripts = context.GetScripts(); IInventory inventory = (IInventory)context.Signable; Program.LocalNode.Relay(inventory); InformationBox.Show(inventory.Hash.ToString(), Strings.RelaySuccessText, Strings.RelaySuccessTitle); }
private void SignAndRelay(ConsensusPayload payload) { SignatureContext sc = new SignatureContext(payload); wallet.Sign(sc); sc.Signable.Scripts = sc.GetScripts(); LocalNode.Relay(payload); }
private async void button8_Click(object sender, EventArgs e) { SignatureContext context = SignatureContext.Parse(textBox8.Text); context.Signable.Scripts = context.GetScripts(); Inventory inventory = (Inventory)context.Signable; await Program.LocalNode.RelayAsync(inventory); InformationBox.Show(inventory.Hash.ToString(), "数据广播成功,这是广播数据的散列值:", "广播成功"); }
private void button4_Click(object sender, EventArgs e) { SignatureContext context = SignatureContext.Parse(textBox2.Text); context.Verifiable.Scripts = context.GetScripts(); IInventory inventory = (IInventory)context.Verifiable; Program.LocalNode.Relay(inventory); InformationBox.Show(inventory.Hash.ToString(), Strings.RelaySuccessText, Strings.RelaySuccessTitle); button4.Visible = false; }
public static void ShowInformation(SignatureContext context) { if (context.Completed) { context.Signable.Scripts = context.GetScripts(); Transaction tx = (Transaction)context.Signable; Program.LocalNode.Relay(tx); InformationBox.Show(tx.Hash.ToString(), "交易已发送,这是交易编号(TXID):", "交易成功"); } else { InformationBox.Show(context.ToString(), "交易构造完成,但没有足够的签名:", "签名不完整"); } }
private async Task ShowInformationAsync(SignatureContext context) { if (context.Completed) { context.Signable.Scripts = context.GetScripts(); Transaction tx = (Transaction)context.Signable; await Program.LocalNode.RelayAsync(tx); InformationBox.Show(tx.Hash.ToString(), "交易已发送,这是交易编号(TXID):", "交易成功"); } else { InformationBox.Show(context.ToString(), "交易构造完成,但没有足够的签名:", "签名不完整"); } }
private void SignAndRelay(ConsensusPayload payload) { SignatureContext sc; try { sc = new SignatureContext(payload); } catch (InvalidOperationException) { return; } wallet.Sign(sc); sc.Signable.Scripts = sc.GetScripts(); LocalNode.Relay(payload); }
private Transaction SignTransaction(Transaction tx) { if (tx == null) { Console.WriteLine($"no transaction specified"); return(null); } SignatureContext context; try { context = new SignatureContext(tx); } catch (InvalidOperationException) { Console.WriteLine($"unsynchronized block"); return(null); } current_wallet.Sign(context); if (context.Completed) { context.Verifiable.Scripts = context.GetScripts(); current_wallet.SaveTransaction(tx); bool relay_result = local_node.Relay(tx); if (relay_result) { return(tx); } else { Console.WriteLine($"Local Node could not relay transaction: {tx.Hash.ToString()}"); } } else { Console.WriteLine($"Incomplete Signature: {context.ToString()}"); } return(null); }
public static void SignAndShowInformation(Transaction tx) { if (tx == null) { MessageBox.Show(Strings.InsufficientFunds); return; } if (tx.Attributes.All(p => p.Usage != TransactionAttributeUsage.Vote) && tx.Outputs.Any(p => p.AssetId.Equals(Blockchain.AntShare.Hash)) && Settings.Default.Votes.Count > 0) { tx.Attributes = tx.Attributes.Concat(Settings.Default.Votes.OfType <string>().Select(p => new TransactionAttribute { Usage = TransactionAttributeUsage.Vote, Data = UInt256.Parse(p).ToArray() })).ToArray(); } SignatureContext context; try { context = new SignatureContext(tx); } catch (InvalidOperationException) { MessageBox.Show(Strings.UnsynchronizedBlock); return; } Program.CurrentWallet.Sign(context); if (context.Completed) { context.Signable.Scripts = context.GetScripts(); Program.CurrentWallet.SaveTransaction(tx); Program.LocalNode.Relay(tx); InformationBox.Show(tx.Hash.ToString(), Strings.SendTxSucceedMessage, Strings.SendTxSucceedTitle); } else { InformationBox.Show(context.ToString(), Strings.IncompletedSignatureMessage, Strings.IncompletedSignatureTitle); } }
protected override JObject Process(string method, JArray _params) { switch (method) { case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(assetId)); JObject json = new JObject(); json["balance"] = coins.Sum(p => p.Output.Value).ToString(); json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); return(json); } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); Fixed8 value = Fixed8.Parse(_params[2].AsString()); Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (value <= Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } } }, fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } default: return(base.Process(method, _params)); } }
protected override JObject Process(string method, JArray _params) { switch (method) { case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(assetId)); JObject json = new JObject(); json["balance"] = coins.Sum(p => p.Output.Value).ToString(); json["confirmed"] = coins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); return(json); } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); Fixed8 value = Fixed8.Parse(_params[2].AsString()); if (value <= Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (value < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendmany": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { JArray to = (JArray)_params[0]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransactionOutput[] outputs = new TransactionOutput[to.Count]; for (int i = 0; i < to.Count; i++) { outputs[i] = new TransactionOutput { AssetId = UInt256.Parse(to[i]["asset"].AsString()), Value = Fixed8.Parse(to[i]["value"].AsString()), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value <= Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } } Fixed8 fee = _params.Count >= 2 ? Fixed8.Parse(_params[1].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 3 ? Wallet.ToScriptHash(_params[2].AsString()) : null; ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = outputs }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "getnewaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { KeyPair key = Program.Wallet.CreateKey(); Contract contract = Program.Wallet.GetContracts(key.PublicKeyHash).First(p => p.IsStandard); return(contract.Address); } case "dumpprivkey": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = Wallet.ToScriptHash(_params[0].AsString()); KeyPair key = Program.Wallet.GetKeyByScriptHash(scriptHash); return(key.Export()); } default: return(base.Process(method, _params)); } }
private bool OnSendCommand(string[] args) { if (args.Length < 4 || args.Length > 5) { Console.WriteLine("error"); return(true); } if (Program.Wallet == null) { Console.WriteLine("You have to open the wallet first."); return(true); } using (SecureString password = ReadSecureString("password")) { if (password.Length == 0) { Console.WriteLine("cancelled"); return(true); } if (!Program.Wallet.VerifyPassword(password)) { Console.WriteLine("Incorrect password"); return(true); } } UInt256 assetId; switch (args[1].ToLower()) { case "neo": case "ans": assetId = Blockchain.SystemShare.Hash; break; case "gas": case "anc": assetId = Blockchain.SystemCoin.Hash; break; default: assetId = UInt256.Parse(args[1]); break; } UInt160 scriptHash = Wallet.ToScriptHash(args[2]); bool isSendAll = string.Equals(args[3], "all", StringComparison.OrdinalIgnoreCase); ContractTransaction tx; if (isSendAll) { Coin[] coins = Program.Wallet.FindUnspentCoins().Where(p => p.Output.AssetId.Equals(assetId)).ToArray(); tx = new ContractTransaction { Attributes = new TransactionAttribute[0], Inputs = coins.Select(p => p.Reference).ToArray(), Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = coins.Sum(p => p.Output.Value), ScriptHash = scriptHash } } }; } else { if (!Fixed8.TryParse(args[3], out Fixed8 amount)) { Console.WriteLine("Incorrect Amount Format"); return(true); } if (amount.GetData() % (long)Math.Pow(10, 8 - Blockchain.Default.GetAssetState(assetId).Precision) != 0) { Console.WriteLine("Incorrect Amount Precision"); return(true); } Fixed8 fee = args.Length >= 5 ? Fixed8.Parse(args[4]) : Fixed8.Zero; tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = amount, ScriptHash = scriptHash } } }, fee: fee); if (tx == null) { Console.WriteLine("Insufficient funds"); return(true); } } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); LocalNode.Relay(tx); Console.WriteLine($"TXID: {tx.Hash}"); } else { Console.WriteLine("SignatureContext:"); Console.WriteLine(context.ToString()); } return(true); }
private JObject InternalCall(string method, JArray _params) { switch (method) { case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); IEnumerable <Coin> coins = Program.Wallet.FindCoins().Where(p => p.AssetId.Equals(assetId)); JObject json = new JObject(); json["balance"] = coins.Where(p => p.State == CoinState.Unspent || p.State == CoinState.Unconfirmed).Sum(p => p.Value).ToString(); json["confirmed"] = coins.Where(p => p.State == CoinState.Unspent).Sum(p => p.Value).ToString(); return(json); } case "getbestblockhash": return(Blockchain.Default.CurrentBlockHash.ToString()); case "getblock": { Block block; if (_params[0] is JNumber) { uint index = (uint)_params[0].AsNumber(); block = Blockchain.Default.GetBlock(index); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); block = Blockchain.Default.GetBlock(hash); } if (block == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false); if (verbose) { JObject json = block.ToJson(); json["confirmations"] = Blockchain.Default.Height - block.Height + 1; UInt256 hash = Blockchain.Default.GetNextBlockHash(block.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } else { return(block.ToArray().ToHexString()); } } case "getblockcount": return(Blockchain.Default.Height + 1); case "getblockhash": { uint height = (uint)_params[0].AsNumber(); return(Blockchain.Default.GetBlockHash(height).ToString()); } case "getconnectioncount": return(localNode.RemoteNodeCount); case "getrawmempool": return(new JArray(LocalNode.GetMemoryPool().Select(p => (JObject)p.Hash.ToString()))); case "getrawtransaction": { UInt256 hash = UInt256.Parse(_params[0].AsString()); bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false); int height = -1; Transaction tx = LocalNode.GetTransaction(hash); if (tx == null) { tx = Blockchain.Default.GetTransaction(hash, out height); } if (tx == null) { throw new RpcException(-101, "Unknown transaction"); } if (verbose) { JObject json = tx.ToJson(); if (height >= 0) { Header header = Blockchain.Default.GetHeader((uint)height); json["blockhash"] = header.Hash.ToString(); json["confirmations"] = Blockchain.Default.Height - header.Height + 1; json["blocktime"] = header.Timestamp; } return(json); } else { return(tx.ToArray().ToHexString()); } } case "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString()); ushort index = (ushort)_params[1].AsNumber(); return(Blockchain.Default.GetUnspent(hash, index)?.ToJson(index)); } case "sendrawtransaction": { Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes()); return(localNode.Relay(tx)); } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt256 assetId = UInt256.Parse(_params[0].AsString()); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); Fixed8 value = Fixed8.Parse(_params[2].AsString()); Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (value <= Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } } }, fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); localNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "submitblock": { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); return(localNode.Relay(block)); } default: throw new RpcException(-32601, "Method not found"); } }
private bool OnSendCommand(string[] args) { if (Program.Wallet == null) { Console.WriteLine("You have to open the wallet first."); return(true); } if (args.Length < 4 || args.Length > 5) { Console.WriteLine("error"); return(true); } UInt256 assetId; switch (args[1].ToLower()) { case "ans": assetId = Blockchain.SystemShare.Hash; break; case "anc": assetId = Blockchain.SystemCoin.Hash; break; default: assetId = UInt256.Parse(args[1]); break; } UInt160 scriptHash = Wallet.ToScriptHash(args[2]); Fixed8 amount; if (!Fixed8.TryParse(args[3], out amount)) { Console.WriteLine("Incorrect Amount Format"); return(true); } if (amount.GetData() % (long)Math.Pow(10, 8 - Blockchain.Default.GetAssetState(assetId).Precision) != 0) { Console.WriteLine("Incorrect Amount Precision"); return(true); } Fixed8 fee = args.Length >= 5 ? Fixed8.Parse(args[4]) : Fixed8.Zero; ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] { new TransactionOutput { AssetId = assetId, Value = amount, ScriptHash = scriptHash } } }, fee: fee); if (tx == null) { Console.WriteLine("Insufficient funds"); return(true); } using (SecureString password = ReadSecureString("password")) { if (password.Length == 0) { Console.WriteLine("cancelled"); return(true); } if (!Program.Wallet.VerifyPassword(password)) { Console.WriteLine("Incorrect password"); return(true); } } SignatureContext context = new SignatureContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.SaveTransaction(tx); LocalNode.Relay(tx); Console.WriteLine($"TXID: {tx.Hash}"); } else { Console.WriteLine("SignatureContext:"); Console.WriteLine(context.ToString()); } return(true); }