示例#1
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(balance, _) = await this.GetBalanceAsync(accountHash, "GAS");

            var tx = wallet.MakeTransaction(neoSystem.StoreView, script, accountHash, new[] { signer }, maxGas: (long)balance.Amount);

            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();
            var blockHash = await SubmitTransactionAsync(tx).ConfigureAwait(false);

            return(tx.Hash);
        }
示例#2
0
        public Task <UInt256> ExecuteAsync(ExpressWalletAccount account, Neo.VM.Script script, decimal additionalGas = 0)
        {
            if (disposedValue)
            {
                throw new ObjectDisposedException(nameof(OfflineNode));
            }

            var devAccount = DevWalletAccount.FromExpressWalletAccount(account);
            var devWallet  = new DevWallet(string.Empty, devAccount);
            var signer     = new Signer()
            {
                Account = devAccount.ScriptHash, Scopes = WitnessScope.CalledByEntry
            };
            var tx = devWallet.MakeTransaction(script, devAccount.ScriptHash, new[] { signer });

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

            if (devAccount.IsMultiSigContract())
            {
                var wallets = chain.GetMultiSigWallets(account);

                foreach (var wallet in wallets)
                {
                    if (context.Completed)
                    {
                        break;
                    }

                    wallet.Sign(context);
                }
            }
            else
            {
                devWallet.Sign(context);
            }

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

            tx.Witnesses = context.GetWitnesses();

            return(SubmitTransactionAsync(tx));
        }
示例#3
0
        public async Task <UInt256> ExecuteAsync(Wallet wallet, UInt160 accountHash, WitnessScope witnessScope, Script script, decimal additionalGas = 0)
        {
            var signers = new[] { new Signer {
                                      Account = accountHash, Scopes = witnessScope
                                  } };
            var factory = new TransactionManagerFactory(rpcClient);
            var tm      = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false);

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

            var account = wallet.GetAccount(accountHash) ?? throw new Exception();

            if (account.Contract.Script.IsMultiSigContract())
            {
                var signatureCount  = account.Contract.ParameterList.Length;
                var multiSigWallets = chain.GetMultiSigWallets(ProtocolSettings, accountHash);
                if (multiSigWallets.Count < signatureCount)
                {
                    throw new InvalidOperationException();
                }

                var publicKeys = multiSigWallets
                                 .Select(w => (w.GetAccount(accountHash)?.GetKey() ?? throw new Exception()).PublicKey)
                                 .ToArray();

                for (var i = 0; i < signatureCount; i++)
                {
                    var key = multiSigWallets[i].GetAccount(accountHash)?.GetKey() ?? throw new Exception();
                    tm.AddMultiSig(key, signatureCount, publicKeys);
                }
            }
            else
            {
                tm.AddSignature(account.GetKey() ?? throw new Exception());
            }

            var tx = await tm.SignAsync().ConfigureAwait(false);

            return(await rpcClient.SendRawTransactionAsync(tx).ConfigureAwait(false));
        }