示例#1
0
        private void SignAndRelay(ConsensusPayload payload)
        {
            ContractParametersContext sc;

            try
            {
                sc = new ContractParametersContext(payload);
                wallet.Sign(sc);
            }
            catch (InvalidOperationException)
            {
                return;
            }
            sc.Verifiable.Scripts = sc.GetScripts();
            localNode.RelayDirectly(payload);
        }
        private JObject SignAndRelay(Transaction tx)
        {
            ContractParametersContext context = new ContractParametersContext(tx);

            wallet.Sign(context);
            if (context.Completed)
            {
                tx.Witnesses = context.GetWitnesses();
                system.Blockchain.Tell(tx);
                return(Utility.TransactionToJson(tx));
            }
            else
            {
                return(context.ToJson());
            }
        }
示例#3
0
        private static Transaction SignWithWallet(Transaction tx)
        {
            if (tx == null)
            {
                throw new ArgumentNullException("tx");
            }
            try
            {
                tx.ToJson();
            }
            catch (Exception)
            {
                throw new FormatException("交易格式错误");
            }


            var wallet = new NEP6Wallet(new WalletIndexer("D:\\PrivateNet2\\node1\\Index_0001E240"), "1.json");

            try
            {
                wallet.Unlock("11111111");
            }
            catch (Exception)
            {
                Console.WriteLine("password error");
            }

            //Signature
            var context = new ContractParametersContext(tx);

            wallet.Sign(context);
            if (context.Completed)
            {
                Console.WriteLine("签名成功");
                tx.Witnesses = context.GetWitnesses();
            }
            else
            {
                Console.WriteLine("签名失败");
            }
            //Console.WriteLine(tx.ToArray().ToHexString());
            Console.WriteLine("交易验证:" + tx.Verify(Blockchain.Singleton.GetSnapshot(), new List <Transaction> {
                tx
            }));
            Console.WriteLine(tx.ToArray().ToHexString());
            return(tx);
        }
示例#4
0
        private JObject SendToAddress(UInt160 assetId, UInt160 scriptHash, string value)
        {
            CheckWallet();
            AssetDescriptor descriptor = new AssetDescriptor(assetId);
            BigDecimal      amount     = BigDecimal.Parse(value, descriptor.Decimals);

            if (amount.Sign <= 0)
            {
                throw new RpcException(-32602, "Invalid params");
            }
            Transaction tx = Wallet.MakeTransaction(new[]
            {
                new TransferOutput
                {
                    AssetId    = assetId,
                    Value      = amount,
                    ScriptHash = scriptHash
                }
            });

            if (tx == null)
            {
                throw new RpcException(-300, "Insufficient funds");
            }

            ContractParametersContext transContext = new ContractParametersContext(tx);

            Wallet.Sign(transContext);
            if (!transContext.Completed)
            {
                return(transContext.ToJson());
            }
            tx.Witnesses = transContext.GetWitnesses();
            if (tx.Size > 1024)
            {
                long calFee = tx.Size * 1000 + 100000;
                if (tx.NetworkFee < calFee)
                {
                    tx.NetworkFee = calFee;
                }
            }
            if (tx.NetworkFee > Settings.Default.MaxFee)
            {
                throw new RpcException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value.");
            }
            return(SignAndRelay(tx));
        }
示例#5
0
        /// <summary>
        /// Create an unsigned Transaction object with given parameters.
        /// </summary>
        /// <param name="script">Transaction Script</param>
        /// <param name="attributes">Transaction Attributes</param>
        /// <param name="cosigners">Transaction Cosigners</param>
        /// <param name="networkFee">Transaction NetworkFee, will set to estimate value(with only basic signatures) when networkFee is 0</param>
        /// <returns></returns>
        public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] attributes = null, Cosigner[] cosigners = null, long networkFee = 0)
        {
            var  random = new Random();
            uint height = rpcClient.GetBlockCount() - 1;

            Tx = new Transaction
            {
                Version         = 0,
                Nonce           = (uint)random.Next(),
                Script          = script,
                Sender          = sender,
                ValidUntilBlock = height + Transaction.MaxValidUntilBlockIncrement,
                Attributes      = attributes ?? new TransactionAttribute[0],
                Cosigners       = cosigners ?? new Cosigner[0],
                Witnesses       = new Witness[0]
            };

            RpcInvokeResult result = rpcClient.InvokeScript(script);

            Tx.SystemFee = Math.Max(long.Parse(result.GasConsumed) - ApplicationEngine.GasFree, 0);
            if (Tx.SystemFee > 0)
            {
                long d         = (long)NativeContract.GAS.Factor;
                long remainder = Tx.SystemFee % d;
                if (remainder > 0)
                {
                    Tx.SystemFee += d - remainder;
                }
                else if (remainder < 0)
                {
                    Tx.SystemFee -= remainder;
                }
            }

            context = new ContractParametersContext(Tx);

            // set networkfee to estimate value when networkFee is 0
            Tx.NetworkFee = networkFee == 0 ? EstimateNetworkFee() : networkFee;

            var gasBalance = new Nep5API(rpcClient).BalanceOf(NativeContract.GAS.Hash, sender);

            if (gasBalance >= Tx.SystemFee + Tx.NetworkFee)
            {
                return(this);
            }
            throw new InvalidOperationException($"Insufficient GAS in address: {sender.ToAddress()}");
        }
        private UInt256 SendTransaction(InvocationTransaction tx, Fixed8 fee)
        {
            Console.WriteLine("----------");
            tx = wallet.MakeTransaction(new InvocationTransaction
            {
                Version    = tx.Version,
                Script     = tx.Script,
                Gas        = tx.Gas,
                Attributes = tx.Attributes,
                Inputs     = tx.Inputs,
                Outputs    = tx.Outputs
            }, fee: fee);
            if (tx == null)
            {
                Console.WriteLine("Insufficient Funds");
                return(null);
            }
            ContractParametersContext context;

            try
            {
                context = new ContractParametersContext(tx);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine("Unsynchronized Block");
                return(null);
            }

            wallet.Sign(context);

            if (context.Completed)
            {
                context.Verifiable.Witnesses = context.GetWitnesses();
                wallet.ApplyTransaction(tx);
                System.LocalNode.Tell(new LocalNode.Relay {
                    Inventory = tx
                });
                Console.WriteLine($"Relayed Transaction: {tx.ToJson()}");
                return(tx.Hash);
            }
            else
            {
                Console.WriteLine(context.ToJson());
                return(null);
            }
        }
示例#7
0
        public bool Sign(ContractParametersContext context)
        {
            bool fSuccess = false;

            foreach (UInt160 scriptHash in context.ScriptHashes)
            {
                WalletAccount account = GetAccount(scriptHash);
                if (account?.HasKey != true)
                {
                    continue;
                }
                KeyPair key       = account.GetKey();
                byte[]  signature = context.Verifiable.Sign(key);
                fSuccess |= context.AddSignature(account.Contract, key.PublicKey, signature);
            }
            return(fSuccess);
        }
示例#8
0
        private Witness PrepareDummyWitness(int maxAccounts)
        {
            var address        = new WalletAccount[maxAccounts];
            var wallets        = new NEP6Wallet[maxAccounts];
            var walletsUnlocks = new IDisposable[maxAccounts];

            for (int x = 0; x < maxAccounts; x++)
            {
                wallets[x]        = TestUtils.GenerateTestWallet();
                walletsUnlocks[x] = wallets[x].Unlock("123");
                address[x]        = wallets[x].CreateAccount();
            }

            // Generate multisignature

            var multiSignContract = Contract.CreateMultiSigContract(maxAccounts, address.Select(a => a.GetKey().PublicKey).ToArray());

            for (int x = 0; x < maxAccounts; x++)
            {
                wallets[x].CreateAccount(multiSignContract, address[x].GetKey());
            }

            // Sign

            var data = new ContractParametersContext(new Transaction()
            {
                Cosigners       = new Cosigner[0],
                Sender          = multiSignContract.ScriptHash,
                Attributes      = new TransactionAttribute[0],
                NetworkFee      = 0,
                Nonce           = 0,
                Script          = new byte[0],
                SystemFee       = 0,
                ValidUntilBlock = 0,
                Version         = 0,
                Witnesses       = new Witness[0]
            });

            for (int x = 0; x < maxAccounts; x++)
            {
                Assert.IsTrue(wallets[x].Sign(data));
            }

            Assert.IsTrue(data.Completed);
            return(data.GetWitnesses()[0]);
        }
示例#9
0
        public async Task <UInt256> ExecuteAsync(Wallet wallet, UInt160 accountHash, WitnessScope witnessScope, Neo.VM.Script script, decimal additionalGas = 0)
        {
            if (disposedValue)
            {
                throw new ObjectDisposedException(nameof(OfflineNode));
            }

            var signer = new Signer()
            {
                Account = accountHash, Scopes = witnessScope
            };
            var tx = wallet.MakeTransaction(neoSystem.StoreView, script, accountHash, new[] { signer });

            if (additionalGas > 0.0m)
            {
                tx.SystemFee += (long)additionalGas.ToBigInteger(NativeContract.GAS.Decimals);
            }

            var context = new ContractParametersContext(neoSystem.StoreView, tx, ProtocolSettings.Network);
            var account = wallet.GetAccount(accountHash) ?? throw new Exception();

            if (account.IsMultiSigContract())
            {
                var multiSigWallets = chain.GetMultiSigWallets(neoSystem.Settings, accountHash);
                for (int i = 0; i < multiSigWallets.Count; i++)
                {
                    multiSigWallets[i].Sign(context);
                    if (context.Completed)
                    {
                        break;
                    }
                }
            }
            else
            {
                wallet.Sign(context);
            }

            if (!context.Completed)
            {
                throw new Exception();
            }

            tx.Witnesses = context.GetWitnesses();
            return(await SubmitTransactionAsync(tx).ConfigureAwait(false));
        }
示例#10
0
        private Transaction SignTransaction(Transaction tx)
        {
            TR.Enter();
            if (tx == null)
            {
                Console.WriteLine($"no transaction specified");
                return(TR.Exit((Transaction)null));
            }
            ContractParametersContext context;

            try
            {
                context = new ContractParametersContext(tx);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine($"unsynchronized block");

                return(TR.Exit((Transaction)null));
            }

            current_wallet.Sign(context);

            if (context.Completed)
            {
                context.Verifiable.Scripts = context.GetScripts();
                current_wallet.ApplyTransaction(tx);

                bool relay_result = local_node.Relay(tx);

                if (relay_result)
                {
                    return(TR.Exit(tx));
                }
                else
                {
                    Console.WriteLine($"Local Node could not relay transaction: {tx.Hash.ToString()}");
                }
            }
            else
            {
                Console.WriteLine($"Incomplete Signature: {context.ToString()}");
            }

            return(TR.Exit((Transaction)null));
        }
示例#11
0
        private Transaction SignTransaction(Transaction tx)
        {
            if (tx == null)
            {
                Console.WriteLine($"no transaction specified");
                return(null);
            }
            ContractParametersContext context;

            try
            {
                context = new ContractParametersContext(tx);
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine($"unsynchronized block");

                return(null);
            }

            current_wallet.Sign(context);

            if (context.Completed)
            {
                tx.Witnesses = context.GetWitnesses();
                current_wallet.ApplyTransaction(tx);

                bool relay_result = system.Blockchain.Ask <RelayResultReason>(tx).Result == RelayResultReason.Succeed;

                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);
        }
示例#12
0
文件: Wallet.cs 项目: xhnice/neo
        /// <summary>
        /// 交易签名
        /// AddCode
        /// </summary>
        /// <param name="context">交易上下文</param>
        /// <param name="privatekey">私钥</param>
        /// <returns>结果</returns>
        public bool Sign(ContractParametersContext context, string privatekey)
        {
            bool fSuccess = false;

            foreach (UInt160 scriptHash in context.ScriptHashes)
            {
                WalletAccount account = GetAccount(scriptHash);
                //if (account?.HasKey != true) continue; // 判断账号是否有nep2key 只读私有属性 只能通过构造函数赋值 所以不伪造
                // 使用私钥生成钥匙
                KeyPair key       = new KeyPair(privatekey.HexToBytes());
                byte[]  signature = context.Verifiable.Sign(key);
                //key.PrivateKey.ToHexString();
                //key.PublicKey.EncodePoint(true).ToHexString();
                //File.AppendAllText("wallet.log", $"privatekey: {key.PrivateKey.ToHexString()} \n publickey: {key.PublicKey.EncodePoint(true).ToHexString()}\n");
                fSuccess |= context.AddSignature(account.Contract, key.PublicKey, signature);
            }
            return(fSuccess);
        }
示例#13
0
        private void SignAndRelay(ConsensusPayload payload)
        {
            ContractParametersContext sc;

            try
            {
                sc = new ContractParametersContext(payload);
                wallet.Sign(sc);
            }
            catch (InvalidOperationException)
            {
                return;
            }
            sc.Verifiable.Witnesses = sc.GetWitnesses();
            system.LocalNode.Tell(new LocalNode.SendDirectly {
                Inventory = payload
            });
        }
示例#14
0
        public Block CreateBlock()
        {
            Contract contract            = Contract.CreateMultiSigContract(M, Validators);
            ContractParametersContext sc = new ContractParametersContext(Block);

            for (int i = 0, j = 0; i < Validators.Length && j < M; i++)
            {
                if (CommitPayloads[i]?.ConsensusMessage.ViewNumber != ViewNumber)
                {
                    continue;
                }
                sc.AddSignature(contract, Validators[i], CommitPayloads[i].GetDeserializedMessage <Commit>().Signature);
                j++;
            }
            Block.Witness      = sc.GetWitnesses()[0];
            Block.Transactions = TransactionHashes.Select(p => Transactions[p]).ToArray();
            return(Block);
        }
示例#15
0
 private void ProcessInvoke(JObject result)
 {
     if (Wallet != null)
     {
         Transaction tx = Wallet.MakeTransaction(result["script"].AsString().HexToBytes());
         ContractParametersContext context = new ContractParametersContext(tx);
         Wallet.Sign(context);
         if (context.Completed)
         {
             tx.Witnesses = context.GetWitnesses();
         }
         else
         {
             tx = null;
         }
         result["tx"] = tx?.ToArray().ToHexString();
     }
 }
示例#16
0
        private JObject SignAndRelay(Transaction tx)
        {
            ContractParametersContext context = new ContractParametersContext(tx);

            Wallet.Sign(context);
            if (context.Completed)
            {
                tx.Witnesses = context.GetWitnesses();
                System.LocalNode.Tell(new LocalNode.Relay {
                    Inventory = tx
                });
                return(tx.ToJson());
            }
            else
            {
                return(context.ToJson());
            }
        }
 private void button9_Click_1(object sender, EventArgs e)
 {
     byte[] script;
     try
     {
         script = textBox6.Text.Trim().HexToBytes();
     }
     catch (FormatException ex)
     {
         MessageBox.Show(ex.Message);
         return;
     }
     if (tx == null)
     {
         tx = new InvocationTransaction();
     }
     tx.Version    = 1;
     tx.Script     = script;
     tx.Attributes = temp_signatures.Select(p => p.Unwrap()).ToArray();
     if (tx.Inputs == null)
     {
         tx.Inputs = new CoinReference[0];
     }
     if (tx.Outputs == null)
     {
         tx.Outputs = new TransactionOutput[0];
     }
     if (tx.Witnesses == null)
     {
         tx.Witnesses = new Witness[0];
     }
     try
     {
         ContractParametersContext context;
         context = new ContractParametersContext(tx);
         Clipboard.SetDataObject(context.ToString());
         MessageBox.Show("Copied to clipboard");
     }
     catch (InvalidOperationException)
     {
         MessageBox.Show(Strings.UnsynchronizedBlock);
         return;
     }
 }
示例#18
0
        public static Block CreateSignedBlock(Header prevHeader, IReadOnlyList <KeyPair> keyPairs, uint network, Transaction[]?transactions = null, ulong timestamp = 0)
        {
            transactions ??= Array.Empty <Transaction>();

            var blockHeight = prevHeader.Index + 1;
            var block       = new Block
            {
                Header = new Header
                {
                    Version    = 0,
                    PrevHash   = prevHeader.Hash,
                    MerkleRoot = MerkleTree.ComputeRoot(transactions.Select(t => t.Hash).ToArray()),
                    Timestamp  = timestamp > prevHeader.Timestamp
                        ? timestamp
                        : Math.Max(Neo.Helper.ToTimestampMS(DateTime.UtcNow), prevHeader.Timestamp + 1),
                    Index         = blockHeight,
                    PrimaryIndex  = 0,
                    NextConsensus = prevHeader.NextConsensus
                },
                Transactions = transactions
            };

            // generate the block header witness. Logic lifted from ConsensusContext.CreateBlock
            var m              = keyPairs.Count - (keyPairs.Count - 1) / 3;
            var contract       = Contract.CreateMultiSigContract(m, keyPairs.Select(k => k.PublicKey).ToList());
            var signingContext = new ContractParametersContext(null, new BlockScriptHashes(prevHeader.NextConsensus), network);

            for (int i = 0; i < keyPairs.Count; i++)
            {
                var signature = block.Header.Sign(keyPairs[i], network);
                signingContext.AddSignature(contract, keyPairs[i].PublicKey, signature);
                if (signingContext.Completed)
                {
                    break;
                }
            }
            if (!signingContext.Completed)
            {
                throw new Exception("block signing incomplete");
            }
            block.Header.Witness = signingContext.GetWitnesses()[0];

            return(block);
        }
示例#19
0
        public static void SignAndShowInformation(Transaction tx)
        {
            if (tx == null)
            {
                MessageBox.Show(Strings.InsufficientFunds);
                return;
            }
            ContractParametersContext context;

            try
            {
                context = new ContractParametersContext(tx);
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show(Strings.UnsynchronizedBlock);
                return;
            }
            Program.CurrentWallet.Sign(context);
            if (context.Completed)
            {
                context.Verifiable.Scripts = context.GetScripts();
                using (var ms = new System.IO.MemoryStream())
                {
                    using (var br = new System.IO.BinaryWriter(ms))
                    {
                        //tx.SerializeUnsigned(br);
                        IO.ISerializable s = tx;
                        s.Serialize(br);
                    }
                    var hex = ms.ToArray().ToHexString();
                    System.IO.File.WriteAllText("d:\\0x00.transhex.txt", hex);
                }

                Program.CurrentWallet.ApplyTransaction(tx);

                Program.LocalNode.Relay(tx);
                InformationBox.Show(tx.Hash.ToString(), Strings.SendTxSucceedMessage, Strings.SendTxSucceedTitle);
            }
            else
            {
                InformationBox.Show(context.ToString(), Strings.IncompletedSignatureMessage, Strings.IncompletedSignatureTitle);
            }
        }
示例#20
0
        public static void SignAndShowInformation(Transaction tx)
        {
            if (tx == null)
            {
                //MessageBox.Show(Strings.InsufficientFunds);
                using (WarningDlg dialog = new WarningDlg("Error", Resources.InsufficientFunds))
                {
                    if (dialog.ShowDialog() != DialogResult.OK)
                    {
                    }
                }
                return;
            }
            ContractParametersContext context;

            try
            {
                context = new ContractParametersContext(tx);
            }
            catch (InvalidOperationException)
            {
                //MessageBox.Show(Strings.UnsynchronizedBlock);
                using (WarningDlg dialog = new WarningDlg("Error", Resources.UnsynchronizedBlock))
                {
                    if (dialog.ShowDialog() != DialogResult.OK)
                    {
                    }
                }
                return;
            }
            Constant.CurrentWallet.Sign(context);
            if (context.Completed)
            {
                context.Verifiable.Scripts = context.GetScripts();
                Constant.CurrentWallet.SaveTransaction(tx);
                Constant.LocalNode.Relay(tx);
                //InformationBox.Show(tx.Hash.ToString(), Strings.SendTxSucceedMessage, Strings.SendTxSucceedTitle);
            }
            else
            {
                //InformationBox.Show(context.ToString(), Strings.IncompletedSignatureMessage, Strings.IncompletedSignatureTitle);
            }
        }
示例#21
0
        public Block CreateBlock()
        {
            EnsureHeader();
            Contract contract            = Contract.CreateMultiSigContract(M, Validators);
            ContractParametersContext sc = new ContractParametersContext(DBFTPlugin.System.StoreView, Block.Header);

            for (int i = 0, j = 0; i < Validators.Length && j < M; i++)
            {
                if (GetMessage(CommitPayloads[i])?.ViewNumber != ViewNumber)
                {
                    continue;
                }
                sc.AddSignature(contract, Validators[i], GetMessage <Commit>(CommitPayloads[i]).Signature);
                j++;
            }
            Block.Header.Witness = sc.GetWitnesses()[0];
            Block.Transactions   = TransactionHashes.Select(p => Transactions[p]).ToArray();
            return(Block);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                MessageBox.Show(Strings.SigningFailedNoDataMessage);
                return;
            }
            ContractParametersContext context = ContractParametersContext.Parse(textBox1.Text);

            if (!Program.CurrentWallet.Sign(context))
            {
                MessageBox.Show(Strings.SigningFailedKeyNotFoundMessage);
                return;
            }
            textBox2.Text = context.ToString();
            if (context.Completed)
            {
                button4.Visible = true;
            }
        }
示例#23
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                MessageBox.Show(LanHelper.LocalLanguage("You must input JSON object pending signature data."));
                return;
            }
            ContractParametersContext context = ContractParametersContext.Parse(textBox1.Text);

            if (!Program.CurrentWallet.Sign(context))
            {
                MessageBox.Show(LanHelper.LocalLanguage("The private key that can sign the data is not found."));
                return;
            }
            textBox2.Text = context.ToString();
            if (context.Completed)
            {
                button4.Visible = true;
            }
        }
示例#24
0
        private void SignAndRelay(ConsensusPayload payload)
        {
            ReportNeoBlockchain reportObj = new ReportNeoBlockchain("[NeoConsensusService-SignAndRelay]");

            ContractParametersContext sc;

            try
            {
                sc = new ContractParametersContext(payload);
                wallet.Sign(sc);
            }
            catch (InvalidOperationException)
            {
                return;
            }
            sc.Verifiable.Scripts = sc.GetScripts();
            localNode.RelayDirectly(payload);

            reportObj.appendElapsedTime();
        }
示例#25
0
        /// <summary>
        /// Create an unsigned Transaction object with given parameters.
        /// </summary>
        /// <param name="script">Transaction Script</param>
        /// <param name="attributes">Transaction Attributes</param>
        /// <param name="cosigners">Transaction Cosigners</param>
        /// <returns></returns>
        public TransactionManager MakeTransaction(byte[] script, TransactionAttribute[] attributes = null, Cosigner[] cosigners = null)
        {
            var  random = new Random();
            uint height = rpcClient.GetBlockCount() - 1;

            Tx = new Transaction
            {
                Version         = 0,
                Nonce           = (uint)random.Next(),
                Script          = script,
                Sender          = sender,
                ValidUntilBlock = height + Transaction.MaxValidUntilBlockIncrement,
                Attributes      = attributes ?? Array.Empty <TransactionAttribute>(),
                Cosigners       = cosigners ?? Array.Empty <Cosigner>(),
                Witnesses       = Array.Empty <Witness>()
            };

            // Add witness hashes parameter to pass CheckWitness
            UInt160[]       hashes = Tx.GetScriptHashesForVerifying(null);
            RpcInvokeResult result = rpcClient.InvokeScript(script, hashes);

            Tx.SystemFee = Math.Max(long.Parse(result.GasConsumed) - ApplicationEngine.GasFree, 0);
            if (Tx.SystemFee > 0)
            {
                long d         = (long)NativeContract.GAS.Factor;
                long remainder = Tx.SystemFee % d;
                if (remainder > 0)
                {
                    Tx.SystemFee += d - remainder;
                }
                else if (remainder < 0)
                {
                    Tx.SystemFee -= remainder;
                }
            }

            context   = new ContractParametersContext(Tx);
            signStore = new List <SignItem>();

            return(this);
        }
示例#26
0
        private RelayResultReason SubmitInvocationTransaction(UInt160 chainHash, KeyPair keyPair, byte[] script)
        {
            ZoroSystem system = ZoroChainSystem.Singleton.GetZoroSystem(chainHash);

            Blockchain blockchain = ZoroChainSystem.Singleton.GetBlockchain(chainHash);

            InvocationTransaction tx = new InvocationTransaction
            {
                Nonce    = Transaction.GetNonce(),
                Account  = Contract.CreateSignatureRedeemScript(keyPair.PublicKey).ToScriptHash(),
                Script   = script,
                GasLimit = InvocationTransaction.GetGasLimit(Fixed8.Zero),
            };

            tx.Attributes          = new TransactionAttribute[1];
            tx.Attributes[0]       = new TransactionAttribute();
            tx.Attributes[0].Usage = TransactionAttributeUsage.Script;
            tx.Attributes[0].Data  = tx.Account.ToArray();

            ContractParametersContext context = new ContractParametersContext(tx, blockchain);

            Program.Wallet.Sign(context);
            if (context.Completed)
            {
                tx.Witnesses = context.GetWitnesses();

                RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(tx).Result;

                if (reason != RelayResultReason.Succeed)
                {
                    Console.WriteLine($"Local Node could not relay transaction: {GetRelayResult(reason)}");
                }
                else
                {
                    Console.WriteLine($"Transaction has been accepted.");
                }
                return(reason);
            }

            return(RelayResultReason.UnableToVerify);
        }
示例#27
0
        public void TestCreateAccount()
        {
            var uut = new NEP6Wallet(wPath, "123", ProtocolSettings.Default);
            var acc = uut.CreateAccount("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632549".HexToBytes());
            var tx  = new Transaction()
            {
                Attributes = Array.Empty <TransactionAttribute>(),
                Script     = new byte[1],
                Signers    = new Signer[] { new Signer()
                                            {
                                                Account = acc.ScriptHash
                                            } },
            };
            var ctx = new ContractParametersContext(TestBlockchain.GetTestSnapshot(), tx, ProtocolSettings.Default.Network);
            var sig = uut.Sign(ctx);

            tx.Witnesses = ctx.GetWitnesses();
            Assert.IsTrue(tx.VerifyWitnesses(ProtocolSettings.Default, TestBlockchain.GetTestSnapshot(), long.MaxValue));
            Assert.ThrowsException <ArgumentNullException>(() => uut.CreateAccount((byte[])null));
            Assert.ThrowsException <ArgumentException>(() => uut.CreateAccount("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551".HexToBytes()));
        }
示例#28
0
文件: Wallet.cs 项目: PlumpMath/Pure
        public bool Sign(ContractParametersContext context)
        {
            bool fSuccess = false;

            foreach (UInt160 scriptHash in context.ScriptHashes)
            {
                VerificationContract contract = GetContract(scriptHash);
                if (contract == null)
                {
                    continue;
                }
                KeyPair key = GetKeyByScriptHash(scriptHash);
                if (key == null)
                {
                    continue;
                }
                byte[] signature = context.Verifiable.Sign(key);
                fSuccess |= context.AddSignature(contract, key.PublicKey, signature);
            }
            return(fSuccess);
        }
示例#29
0
        private void ProcessInvokeWithWallet(JObject result, UInt160 sender = null, Signers signers = null)
        {
            Transaction tx = null;

            if (wallet != null && signers != null)
            {
                Signer[]  witnessSigners  = signers.GetSigners().ToArray();
                UInt160[] signersAccounts = signers.GetScriptHashesForVerifying(null);
                if (sender != null)
                {
                    if (!signersAccounts.Contains(sender))
                    {
                        witnessSigners = witnessSigners.Prepend(new Signer()
                        {
                            Account = sender, Scopes = WitnessScope.CalledByEntry
                        }).ToArray();
                    }
                    else if (signersAccounts[0] != sender)
                    {
                        throw new RpcException(-32602, "The sender must be the first element of signers.");
                    }
                }

                if (witnessSigners.Count() > 0)
                {
                    tx = wallet.MakeTransaction(Convert.FromBase64String(result["script"].AsString()), sender, witnessSigners);
                    ContractParametersContext context = new ContractParametersContext(tx);
                    wallet.Sign(context);
                    if (context.Completed)
                    {
                        tx.Witnesses = context.GetWitnesses();
                    }
                    else
                    {
                        tx = null;
                    }
                }
            }
            result["tx"] = tx?.ToArray().ToHexString();
        }
        private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signers signers = null)
        {
            using var snapshot = system.GetSnapshot();
            var contract = NativeContract.ContractManagement.GetContract(snapshot, scriptHash);

            if (contract is null)
            {
                throw new RpcException(-100, "Unknown contract");
            }
            var methodName = "verify";

            Transaction tx = signers == null ? null : new Transaction
            {
                Signers    = signers.GetSigners(),
                Attributes = Array.Empty <TransactionAttribute>()
            };
            ContractParametersContext context = new ContractParametersContext(snapshot, tx);

            wallet.Sign(context);
            tx.Witnesses = context.Completed ? context.GetWitnesses() : null;

            using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.CreateSnapshot(), settings: system.Settings);
            engine.LoadScript(new ScriptBuilder().EmitDynamicCall(scriptHash, methodName, args).ToArray(), rvcount: 1);

            JObject json = new JObject();

            json["script"]      = Convert.ToBase64String(contract.Script);
            json["state"]       = engine.Execute();
            json["gasconsumed"] = engine.GasConsumed.ToString();
            json["exception"]   = GetExceptionMessage(engine.FaultException);
            try
            {
                json["stack"] = new JArray(engine.ResultStack.Select(p => p.ToJson()));
            }
            catch (InvalidOperationException)
            {
                json["stack"] = "error: recursive reference";
            }
            return(json);
        }