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); }
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)); }
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)); }