/// <summary> /// </summary> /// <param name="output"></param> public void Standard(TransferOutput output) { var transactionModel = new DebitModel((Debit)output.Transaction); var transferResponse = new TransferResponse(transactionModel, output.UpdatedBalance.ToDecimal()); this.ViewModel = new ObjectResult(transferResponse); }
public async Task Execute(TransferInput input) { IAccount originAccount = await _accountRepository.Get(input.OriginAccountId); if (originAccount == null) { _outputHandler.Error($"The account {input.OriginAccountId} does not exist or is already closed."); return; } IAccount destinationAccount = await _accountRepository.Get(input.DestinationAccountId); if (destinationAccount == null) { _outputHandler.Error($"The account {input.DestinationAccountId} does not exist or is already closed."); return; } IDebit debit = originAccount.Withdraw(_entityFactory, input.Amount); ICredit credit = destinationAccount.Deposit(_entityFactory, input.Amount); await _accountRepository.Update(originAccount, debit); await _accountRepository.Update(destinationAccount, credit); await _unitOfWork.Save(); TransferOutput output = new TransferOutput( debit, originAccount.GetCurrentBalance(), input.OriginAccountId, input.DestinationAccountId); _outputHandler.Default(output); }
public IActionResult SendMany(Assets assets) { CheckWallet(); UInt160 from = null; if (assets.From != null || assets.From.Length != 0) { from = assets.From.ToScriptHash(); } List <Asset> to = assets.Asset; if (to.Count == 0) { throw new RestException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UInt160 asset_id = UInt160.Parse(to[i].AssetId); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i].Value, descriptor.Decimals), ScriptHash = to[i].Address.ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { throw new RestException(-32602, "Invalid params"); } } Transaction tx = wallet.MakeTransaction(outputs, from); if (tx == null) { throw new RestException(-300, "Insufficient funds"); } ContractParametersContext transContext = new ContractParametersContext(tx); wallet.Sign(transContext); if (!transContext.Completed) { return(FormatJson(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 > RestSettings.Default.MaxFee) { throw new RestException(-301, "The necessary fee is more than the Max_fee, this transaction is failed. Please increase your Max_fee value."); } return(FormatJson(SignAndRelay(tx))); }
public SendTransferRequest(Ed25519Seed seed, TransferOutput output, int accountIndex = 0, AddressOptions addressOptions = null, string indexationKey = "", string data = "") : this(seed, new List <TransferOutput> { output }, accountIndex, addressOptions, indexationKey, data) { }
private JObject SendMany(UInt160 from, JArray to, Fixed8 fee, UInt160 change_address) { CheckWallet(); if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } } if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } Transaction tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext transContext = new ContractParametersContext(tx); Wallet.Sign(transContext); tx.Witnesses = transContext.GetWitnesses(); if (tx.Size > 1024) { Fixed8 calFee = Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m); if (fee < calFee) { fee = calFee; tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } } } if (fee > 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)); }
public void BuildOutput(IDebit debit, IAccount originAccount, IAccount destinationAccount) { var output = new TransferOutput( debit, originAccount.GetCurrentBalance(), originAccount.Id, destinationAccount.Id); _outputPort.Standard(output); }
public void Default(TransferOutput output) { ViewModel = new ObjectResult(new { Amount = output.Transaction.Amount, Description = output.Transaction.Description, TransactionDate = output.Transaction.TransactionDate, UpdatedBalance = output.UpdatedBalance, }); }
public void Standard(TransferOutput transferOutput) { var transferResponse = new { Amount = transferOutput.Transaction.Amount, Description = transferOutput.Transaction.Description, TransactionDate = transferOutput.Transaction.TransactionDate, UpdatedBalance = transferOutput.UpdatedBalance, }; ViewModel = new ObjectResult(transferResponse); }
public void Standard(TransferOutput transferOutput) { var transferResponse = new { transferOutput.Transaction.Amount, transferOutput.Transaction.Description, transferOutput.Transaction.TransactionDate, transferOutput.UpdatedBalance }; this.ViewModel = new ObjectResult(transferResponse); }
public async Task Execute(TransferInput input) { IAccount originAccount = await _accountRepository.Get(input.OriginAccountId); if (originAccount == null) { _outputHandler.Error($"The account {input.OriginAccountId} does not exist or is already closed."); return; } IAccount destinationAccount = await _accountRepository.Get(input.DestinationAccountId); if (destinationAccount == null) { _outputHandler.Error($"The account {input.DestinationAccountId} does not exist or is already closed."); return; } IDebit debit = originAccount.Withdraw(_entityFactory, input.Amount); ICredit credit = destinationAccount.Deposit(_entityFactory, input.Amount); await _accountRepository.Update(originAccount, debit); await _accountRepository.Update(destinationAccount, credit); // Publish the event to the enterprice service bus await _serviceBus.PublishEventAsync(new Shared.Events.TransferCompleted() { OriginalAccountId = originAccount.Id, DestinationAccountId = destinationAccount.Id, Amount = input.Amount.ToMoney().ToDecimal() }); await _unitOfWork.Save(); TransferOutput output = new TransferOutput( debit, originAccount.GetCurrentBalance(), input.OriginAccountId, input.DestinationAccountId); _outputHandler.Default(output); }
private JObject SendMany(UInt160 from, JArray to, Fixed8 fee, UInt160 change_address) { CheckWallet(); if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } } if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } Transaction tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee); if (tx.Size > 1024) { fee += Fixed8.FromDecimal(tx.Size * 0.00001m + 0.001m); tx = Wallet.MakeTransaction(null, outputs, from: from, change_address: change_address, fee: fee); } if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } return(SignAndRelay(tx)); }
public void Default(TransferOutput output) { Transfers.Add(output); }
private JObject SendMany(JArray _params) { CheckWallet(); int to_start = 0; UInt160 from = null; if (_params[0] is JString) { from = _params[0].AsString().ToScriptHash(); to_start = 1; } JArray to = (JArray)_params[to_start]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UInt160 asset_id = UInt160.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } } Transaction tx = wallet.MakeTransaction(outputs, from); 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.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)); }
public void Standard(TransferOutput output) { this.Transfers.Add(output); }
private JObject Process(string method, JArray _params) { switch (method) { case "unlock": if (wallet == null) { return("wallet is null."); } if (_params.Count < 2) { return("parameter is error."); } string password = _params[0].AsString(); int duration = (int)_params[1].AsNumber(); bool ok = walletTimeLock.UnLock(password, duration); string result = ok ? "successfully" : "failed"; return($"Wallet unlocked {result}."); case "dumpprivkey": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = _params[0].AsString().ToScriptHash(); WalletAccount account = wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "getaccountstate": { UInt160 script_hash = _params[0].AsString().ToScriptHash(); AccountState account = Blockchain.Singleton.Store.GetAccounts().TryGet(script_hash) ?? new AccountState(script_hash); return(account.ToJson()); } case "getassetstate": { UInt256 asset_id = UInt256.Parse(_params[0].AsString()); AssetState asset = Blockchain.Singleton.Store.GetAssets().TryGet(asset_id); return(asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset")); } case "getbalance": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //BRC5 balance json["balance"] = wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); 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(); break; } return(json); } case "getbestblockhash": return(Blockchain.Singleton.CurrentBlockHash.ToString()); case "getblock": { Block block; if (_params[0] is JNumber) { uint index = (uint)_params[0].AsNumber(); block = Blockchain.Singleton.Store.GetBlock(index); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); block = Blockchain.Singleton.Store.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.Singleton.Height - block.Index + 1; UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(block.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(block.ToArray().ToHexString()); } case "getblockcount": return(Blockchain.Singleton.Height + 1); case "getblockhash": { uint height = (uint)_params[0].AsNumber(); if (height <= Blockchain.Singleton.Height) { return(Blockchain.Singleton.GetBlockHash(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getblockheader": { Header header; if (_params[0] is JNumber) { uint height = (uint)_params[0].AsNumber(); header = Blockchain.Singleton.Store.GetHeader(height); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); header = Blockchain.Singleton.Store.GetHeader(hash); } if (header == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false); if (verbose) { JObject json = header.ToJson(); json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1; UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(header.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(header.ToArray().ToHexString()); } case "getblocksysfee": { uint height = (uint)_params[0].AsNumber(); if (height <= Blockchain.Singleton.Height) { return(Blockchain.Singleton.Store.GetSysFeeAmount(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getconnectioncount": return(LocalNode.Singleton.ConnectedCount); case "getcontractstate": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractState contract = Blockchain.Singleton.Store.GetContracts().TryGet(script_hash); return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract")); } case "getnewaddress": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { WalletAccount account = wallet.CreateAccount(); if (wallet is BRC6Wallet BRC6) { BRC6.Save(); } return(account.Address); } case "getpeers": { JObject json = new JObject(); json["unconnected"] = new JArray(LocalNode.Singleton.GetUnconnectedPeers().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Address.ToString(); peerJson["port"] = p.Port; return(peerJson); })); json["bad"] = new JArray(); //badpeers has been removed json["connected"] = new JArray(LocalNode.Singleton.GetRemoteNodes().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Remote.Address.ToString(); peerJson["port"] = p.ListenerPort; return(peerJson); })); return(json); } case "getrawmempool": return(new JArray(Blockchain.Singleton.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); Transaction tx = Blockchain.Singleton.GetTransaction(hash); if (tx == null) { throw new RpcException(-100, "Unknown transaction"); } if (verbose) { JObject json = tx.ToJson(); uint? height = Blockchain.Singleton.Store.GetTransactions().TryGet(hash)?.BlockIndex; if (height != null) { Header header = Blockchain.Singleton.Store.GetHeader((uint)height); json["blockhash"] = header.Hash.ToString(); json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1; json["blocktime"] = header.Timestamp; } return(json); } return(tx.ToArray().ToHexString()); } case "getstorage": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); byte[] key = _params[1].AsString().HexToBytes(); StorageItem item = Blockchain.Singleton.Store.GetStorages().TryGet(new StorageKey { ScriptHash = script_hash, Key = key }) ?? new StorageItem(); return(item.Value?.ToHexString()); } case "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString()); ushort index = (ushort)_params[1].AsNumber(); return(Blockchain.Singleton.Store.GetUnspent(hash, index)?.ToJson(index)); } case "createaddress": { byte[] privateKey = new byte[32]; using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) { rng.GetBytes(privateKey); KeyPair key = new KeyPair(privateKey); byte[] pubkey = Contract.CreateSignatureRedeemScript(key.PublicKey); JObject json = new JObject(); json["address"] = pubkey.ToScriptHash().ToAddress(); json["pubkey"] = key.PublicKey.EncodePoint(true).ToHexString(); json["prikey"] = key.PrivateKey.ToHexString(); json["wif"] = key.Export(); json["script"] = pubkey.ToHexString(); return(json); } } case "getutxos": { UInt160 script_hash = _params[0].AsString().ToScriptHash(); AccountState account = Blockchain.Singleton.Store.GetAccounts().TryGet(script_hash) ?? new AccountState(script_hash); return(account.ToJson()); } case "getvalidators": using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { var validators = snapshot.GetValidators(); return(snapshot.GetEnrollments().Select(p => { JObject validator = new JObject(); validator["publickey"] = p.PublicKey.ToString(); validator["votes"] = p.Votes.ToString(); validator["active"] = validators.Contains(p.PublicKey); return validator; }).ToArray()); } case "getversion": { JObject json = new JObject(); json["port"] = LocalNode.Singleton.ListenerPort; json["nonce"] = LocalNode.Nonce; json["useragent"] = LocalNode.UserAgent; return(json); } case "getwalletheight": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { return((wallet.WalletHeight > 0) ? wallet.WalletHeight - 1 : 0); } case "invoke": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractParameter[] parameters = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray(); byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, parameters).ToArray(); } return(GetInvokeResult(script)); } case "invokefunction": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); string operation = _params[1].AsString(); ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, operation, args).ToArray(); } return(GetInvokeResult(script)); } case "invokescript": { byte[] script = _params[0].AsString().HexToBytes(); return(GetInvokeResult(script)); } case "listaddress": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { return(wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = _params[1].AsString().ToScriptHash(); UInt160 to = _params[2].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null; string remark = _params.Count >= 7 ? _params[6].AsString() : null; Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } AddRemak(remark, tx); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "transfer": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = _params[1].AsString().ToScriptHash(); UInt160 to = _params[2].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : from; string remark = _params.Count >= 7 ? _params[6].AsString() : null; Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } AddRemak(remark, tx); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendmany": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { JArray to = (JArray)_params[0]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { 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 ? _params[2].AsString().ToScriptHash() : null; string remark = _params.Count >= 4 ? _params[3].AsString() : null; Transaction tx = wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } AddRemak(remark, tx); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendrawtransaction": { Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes()); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(tx).Result; return(GetRelayResult(reason)); } case "sendtoaddress": if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "wallet is null or locked."); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = _params[1].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? _params[4].AsString().ToScriptHash() : null; string remark = _params.Count >= 6 ? _params[5].AsString() : null; Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } AddRemak(remark, tx); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "submitblock": { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(block).Result; return(GetRelayResult(reason)); } case "validateaddress": { JObject json = new JObject(); UInt160 scriptHash; try { scriptHash = _params[0].AsString().ToScriptHash(); } catch { scriptHash = null; } json["address"] = _params[0]; json["isvalid"] = scriptHash != null; return(json); } /* * case "backupwallet": * if (wallet == null || walletTimeLock.IsLocked()) * throw new RpcException(-400, "wallet is null or locked."); * else * { * return BackupWallet(); * } * * case "backupwallettosqlite": * if (wallet == null) * throw new RpcException(-400, "Access denied"); * else * { * try * { * string path = ((Bhp.Wallets.BRC6.BRC6Wallet)wallet).Path; * string WalletName = _params.Count >= 1 ? _params[0].AsString().Trim() : path.Substring(path.LastIndexOf("\\") + 1).Trim(); * * int nIndex = WalletName.LastIndexOf('.'); * if (nIndex >= 0) * { * WalletName = WalletName.Substring(0, nIndex).Trim(); * } * else * { * WalletName = WalletName.Trim(); * } * return "Backup Wallet Success! Name:" + SQLiteOperateForBackupWallet.BackupWalletToSQLite(WifToList(), WalletName); * } * catch (Exception ex) * { * throw new Exception(ex.ToString()); * //throw new RpcException(-401, "SQLite Exception"); * } * } * * case "recoverwalletfromsqlite": * if (wallet == null) * throw new RpcException(-400, "Access denied"); * else * { * if (_params.Count == 0) * { * return "Please Input BackupWalletName"; * } * string BackWalletName = _params[0].AsString().Trim(); * //System.IO.Path.GetExtension(BackWalletName) * * string FileName = "";//不含后缀 * int nIndex = BackWalletName.LastIndexOf('.'); * if (nIndex >= 0) * { * FileName = BackWalletName.Substring(0, nIndex) + ".sqlite"; * } * else * { * FileName = BackWalletName + ".sqlite"; * } * List<string> wifs = SQLiteOperateForBackupWallet.RecoverWalletFromSQLite(FileName); * foreach (string wif in wifs) * { * WalletAccount account; * try * { * account = wallet.Import(wif); * } * catch (FormatException) * { * continue; * } * } * if (wallet is BRC6Wallet walletBrc6) * walletBrc6.Save(); * return "Recover Wallet Success"; * } * * case "closewallet": * if (wallet == null) * throw new RpcException(-400, "Access denied"); * else * { * if (wallet is IDisposable disposable) * { * disposable.Dispose(); * wallet = null; * } * return "Close Wallet Success"; * } */ default: throw new RpcException(-32601, "Method not found"); } }
protected override JObject Process(string method, JArray _params) { switch (method) { case "": case "getapplicationlog": { UInt256 hash = UInt256.Parse(_params[0].AsString()); string path = Path.Combine(Settings.Default.Paths.ApplicationLogs, $"{hash}.json"); return(File.Exists(path) ? JObject.Parse(File.ReadAllText(path)) : throw new RpcException(-100, "Unknown transaction")); } case "balance": // 使用address查询余额 AddCode if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); if (_params.Count() == 1) { // 查询NEO和GAS资产 string address = _params[0].AsString(); try { Wallet.ToScriptHash(address); } catch { json["code"] = -1; json["message"] = "NEO地址错误"; return(json); } IEnumerable <Coin> coins = Program.Wallet.GetCoins(address); // NEO var neoCoins = coins.Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(UInt256.Parse(Settings.Default.Asset.NEOAsset))); json["balance"] = neoCoins.Sum(p => p.Output.Value).ToString(); json["confirmed"] = neoCoins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); // GAS var gasCoins = coins.Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(UInt256.Parse(Settings.Default.Asset.GASAsset))); json["gasbalance"] = gasCoins.Sum(p => p.Output.Value).ToString(); json["gasconfirmed"] = gasCoins.Where(p => p.State.HasFlag(CoinState.Confirmed)).Sum(p => p.Output.Value).ToString(); return(json); } else // 查询指定资产余额 { string address = _params[1].AsString(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = Program.Wallet.GetAvailable(asset_id_160, address).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = Program.Wallet.GetCoins(address).Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); 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(); break; } return(json); } } case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = Program.Wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); 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(); break; } return(json); } case "listaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(Program.Wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = Wallet.ToScriptHash(_params[1].AsString()); UInt160 to = Wallet.ToScriptHash(_params[2].AsString()); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? Wallet.ToScriptHash(_params[5].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendfromto": // 从指定账号向指定账号转账 AddCode if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { // 参数顺序 资产类型 输出账号 输入账号 输出金额 输出账号私钥 手续费 找零地址 UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = Wallet.ToScriptHash(_params[1].AsString()); UInt160 to = Wallet.ToScriptHash(_params[2].AsString()); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); string privatekey = _params[4].AsString(); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 6 ? Fixed8.Parse(_params[5].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 7 && !string.IsNullOrEmpty(_params[6].AsString()) ? Wallet.ToScriptHash(_params[6].AsString()) : from;// 找零地址 Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); //File.AppendAllText("wallet.log", context.ScriptHashes.Count().ToString()); //Program.Wallet.Sign(context); Program.Wallet.Sign(context, privatekey); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(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"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value.Sign <= 0) { 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; Transaction tx = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "getnewaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = Program.Wallet.CreateAccount(); if (Program.Wallet is NEP6Wallet wallet) { wallet.Save(); } return(account.Address); } case "newaddress": // 创建一个账号 AddCode if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = Program.Wallet.CreateAccount(); if (Program.Wallet is NEP6Wallet wallet) { wallet.Save(); } return(account.OutputJson()); } case "dumpprivkey": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = Wallet.ToScriptHash(_params[0].AsString()); WalletAccount account = Program.Wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "invoke": // 使用给定的参数以散列值调用智能合约 case "invokefunction": case "invokescript": JObject result = base.Process(method, _params); if (Program.Wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = result["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(result["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = Program.Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); } else { tx = null; } } result["tx"] = tx?.ToArray().ToHexString(); } return(result); default: return(base.Process(method, _params)); } }
protected override JObject Process(string method, JArray _params) { switch (method) { //{"name":null,"version":"1.0","scrypt":{"n":16384,"r":8,"p":8},"accounts":[{"address":"AHGVqc2L3vbxG8N6t76oxg8ihdyxcqePB1","label":null,"isDefault":false,"lock":false,"key":"6PYMhaNsXjhGALn3XfEqwFLr3VsbCmgfr1WHMjaNgS5C9677L4KNoih46G","contract":{"script":"210331cef9faf71d85c4dd19911dd7d53815dc69056322f1db62a66df264e5f8ba8cac","parameters":[{"name":"signature","type":"Signature"}],"deployed":false},"extra":null},{"address":"ARBFVamaqvmyVjyN6P8V3tGeoZZJBZ7drP","label":null,"isDefault":false,"lock":false,"key":"6PYSMmydUaZCiYa6B8AgGJYDsXXfTmr1PdG27uWPkjtsdv4n3K2tbQ8WM1","contract":{"script":"2102ca41146dba006ef61e328e0735bdb46e76ee12f8feb94eec0f5cfb1bcf57ee17ac","parameters":[{"name":"signature","type":"Signature"}],"deployed":false},"extra":null},{"address":"AJ3uJEYBudv5ZFo2Eg6MFP1ZzimefzD8vZ","label":null,"isDefault":false,"lock":false,"key":"6PYWzN8pz45xxQu4wkQtn8GwvbfUhDS9iRBDgdLt5Vwd1RgkU6SAtuApuR","contract":{"script":"2103f4ca1a9ab97e8cdcd6349b72ff0914f5b70774a2c6927d4c0db1b2d733c696bcac","parameters":[{"name":"signature","type":"Signature"}],"deployed":false},"extra":null}],"extra":null} //将整个钱包的json作为一个串放进param // "{'jsonrpc': '2.0', 'method': 'openwallet', 'params': ["walllet-base64-json","password"], 'id': 1}" case "openwallet": { string oStr = Base64Decode(_params[0].AsString()); //System.Console.WriteLine(_params[0].AsString()); //System.Console.WriteLine(oStr); //JObject walletJson = _params[0]; string password = Base64Decode(_params[1].AsString()); string path = Directory.GetCurrentDirectory() + "\\" + "tmp.json"; FileStream F = new FileStream("tmp.json", FileMode.OpenOrCreate, FileAccess.ReadWrite); F.SetLength(0); StreamWriter sw = new StreamWriter(F); //sw.Write(walletJson.AsString()); sw.Write(oStr); sw.Flush(); sw.Close(); JObject json = new JObject(); NEP6Wallet nep6wallet = new NEP6Wallet(path); try { nep6wallet.Unlock(password); } catch (CryptographicException) { System.Console.WriteLine($"failed to open wallet \"{path}\""); File.Delete(path); throw new RpcException(-400, "Access denied"); } Program.Wallet = nep6wallet; File.Delete(path); //打开后删除钱包文件 return("0"); } case "closewallet": { //对当前打开的钱包做校验 // if(Program.Wallet != null) // { // Base64Encode // } Program.Wallet = null; return("0"); } case "getapplicationlog": { UInt256 hash = UInt256.Parse(_params[0].AsString()); string path = Path.Combine(Settings.Default.Paths.ApplicationLogs, $"{hash}.json"); return(File.Exists(path) ? JObject.Parse(File.ReadAllText(path)) : throw new RpcException(-100, "Unknown transaction")); } case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = Program.Wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); 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(); break; } return(json); } case "listaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(Program.Wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = Wallet.ToScriptHash(_params[1].AsString()); UInt160 to = Wallet.ToScriptHash(_params[2].AsString()); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? Wallet.ToScriptHash(_params[5].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(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"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value.Sign <= 0) { 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; Transaction tx = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "getnewaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = Program.Wallet.CreateAccount(); if (Program.Wallet is NEP6Wallet wallet) { wallet.Save(); } return(account.Address); } case "dumpprivkey": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = Wallet.ToScriptHash(_params[0].AsString()); WalletAccount account = Program.Wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "invoke": case "invokefunction": case "invokescript": JObject result = base.Process(method, _params); if (Program.Wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = result["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(result["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = Program.Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); } else { tx = null; } } result["tx"] = tx?.ToArray().ToHexString(); } return(result); 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 { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(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"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value.Sign <= 0) { 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; Transaction tx = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(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 = (KeyPair)Program.Wallet.CreateKey(); VerificationContract 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 = (KeyPair)Program.Wallet.GetKeyByScriptHash(scriptHash); return(key.Export()); } default: return(base.Process(method, _params)); } }
protected override JObject Process(string method, JArray _params) { switch (method) { case "getapplicationlog": { UInt256 hash = UInt256.Parse(_params[0].AsString()); string path = Path.Combine(Settings.Default.Paths.ApplicationLogs, $"{hash}.json"); return(File.Exists(path) ? JObject.Parse(File.ReadAllText(path)) : throw new RpcException(-100, "Unknown transaction")); } case "getbalance": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = Program.Wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = Program.Wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); 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(); break; } return(json); } case "listaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(Program.Wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = Wallet.ToScriptHash(_params[1].AsString()); UInt160 to = Wallet.ToScriptHash(_params[2].AsString()); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? Wallet.ToScriptHash(_params[5].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(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"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value.Sign <= 0) { 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; Transaction tx = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "getnewaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = Program.Wallet.CreateAccount(); if (Program.Wallet is NEP6Wallet wallet) { wallet.Save(); } return(account.Address); } case "dumpprivkey": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = Wallet.ToScriptHash(_params[0].AsString()); WalletAccount account = Program.Wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "invoke": case "invokefunction": case "invokescript": JObject result = base.Process(method, _params); if (Program.Wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = result["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(result["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = Program.Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); } else { tx = null; } } result["tx"] = tx?.ToArray().ToHexString(); } return(result); case "getunclaimedgas": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); uint height = Blockchain.Default.Height + 1; Fixed8 unavailable; try { unavailable = Blockchain.CalculateBonus(Program.Wallet.FindUnspentCoins().Where(p => p.Output.AssetId.Equals(Blockchain.GoverningToken.Hash)).Select(p => p.Reference), height); } catch (Exception) { unavailable = Fixed8.Zero; } json["unavailable"] = unavailable.ToString(); Fixed8 available = Blockchain.CalculateBonus(Program.Wallet.GetUnclaimedCoins().Select(p => p.Reference)); json["available"] = available.ToString(); return(json); } case "claimgas": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { Fixed8 availableBonus = Blockchain.CalculateBonus(Program.Wallet.GetUnclaimedCoins().Select(p => p.Reference)); if (availableBonus == Fixed8.Zero) { // no gas to claim return(null); } CoinReference[] claims = Program.Wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray(); if (claims.Length == 0) { return(null); } ClaimTransaction tx = new ClaimTransaction { Claims = claims, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new[] { new TransactionOutput { AssetId = Blockchain.UtilityToken.Hash, Value = Blockchain.CalculateBonus(claims), ScriptHash = Program.Wallet.GetChangeAddress() } } }; ContractParametersContext context; try { context = new ContractParametersContext(tx); } catch (InvalidOperationException) { // unsynchronized block return(null); } Program.Wallet.Sign(context); if (context.Completed) { context.Verifiable.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); bool relay_result = LocalNode.Relay(tx); if (relay_result) { return(tx.ToJson()); } else { throw new RpcException(-401, "Could not relay transaction"); } } else { return(context.ToJson()); } } default: return(base.Process(method, _params)); } }
protected override JObject Process(string method, JArray _params) { switch (method) { case "getapplicationlog": { UInt256 hash = UInt256.Parse(_params[0].AsString()); string path = Path.Combine(Settings.Default.Paths.ApplicationLogs, $"{hash}.json"); return(File.Exists(path) ? JObject.Parse(File.ReadAllText(path)) : throw new RpcException(-100, "Unknown transaction")); } 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 "listaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(Program.Wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = Wallet.ToScriptHash(_params[1].AsString()); UInt160 to = Wallet.ToScriptHash(_params[2].AsString()); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? Wallet.ToScriptHash(_params[5].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendtoaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; Transaction tx = Program.Wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(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"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) }; if (outputs[i].Value.Sign <= 0) { 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; Transaction tx = Program.Wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); LocalNode.Relay(tx); return(tx.ToJson()); } else { return(context.ToJson()); } } case "getnewaddress": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = Program.Wallet.CreateAccount(); if (Program.Wallet is NEP6Wallet wallet) { wallet.Save(); } return(account.Address); } case "dumpprivkey": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = Wallet.ToScriptHash(_params[0].AsString()); WalletAccount account = Program.Wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "invoke": case "invokefunction": case "invokescript": JObject result = base.Process(method, _params); if (Program.Wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = result["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(result["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = Program.Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Program.Wallet.Sign(context); if (context.Completed) { tx.Scripts = context.GetScripts(); } else { tx = null; } } result["tx"] = tx?.ToArray().ToHexString(); } return(result); default: return(base.Process(method, _params)); } }
/// <summary> /// Standard output. /// </summary> /// <param name="output">Output.</param> public void Standard(TransferOutput output) { this.ViewModel = new NoContentResult(); }
protected virtual JObject SendMany(JArray _params) { CheckWallet(); int to_start = 0; UInt160 from = null; if (_params[0] is JString) { from = AddressToScriptHash(_params[0].AsString(), system.Settings.AddressVersion); to_start = 1; } JArray to = (JArray)_params[to_start]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } Signer[] signers = _params.Count >= to_start + 2 ? ((JArray)_params[to_start + 1]).Select(p => new Signer() { Account = AddressToScriptHash(p.AsString(), system.Settings.AddressVersion), Scopes = WitnessScope.CalledByEntry }).ToArray() : null; TransferOutput[] outputs = new TransferOutput[to.Count]; using var snapshot = system.GetSnapshot(); for (int i = 0; i < to.Count; i++) { UInt160 asset_id = UInt160.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(snapshot, system.Settings, asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = new BigDecimal(BigInteger.Parse(to[i]["value"].AsString()), descriptor.Decimals), ScriptHash = AddressToScriptHash(to[i]["address"].AsString(), system.Settings.AddressVersion) }; if (outputs[i].Value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } } Transaction tx = wallet.MakeTransaction(snapshot, outputs, from, signers); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext transContext = new ContractParametersContext(snapshot, tx, settings.Network); 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.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(snapshot, tx)); }
private JObject Process(string method, JArray _params) { switch (method) { case "dumpprivkey": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { UInt160 scriptHash = _params[0].AsString().ToScriptHash(); WalletAccount account = wallet.GetAccount(scriptHash); return(account.GetKey().Export()); } case "getaccountstate": { UInt160 script_hash = _params[0].AsString().ToScriptHash(); AccountState account = Blockchain.Singleton.Store.GetAccounts().TryGet(script_hash) ?? new AccountState(script_hash); return(account.ToJson()); } case "getassetstate": { UInt256 asset_id = UInt256.Parse(_params[0].AsString()); AssetState asset = Blockchain.Singleton.Store.GetAssets().TryGet(asset_id); return(asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset")); } case "getbalance": if (wallet == null) { throw new RpcException(-400, "Access denied."); } else { JObject json = new JObject(); switch (UIntBase.Parse(_params[0].AsString())) { case UInt160 asset_id_160: //NEP-5 balance json["balance"] = wallet.GetAvailable(asset_id_160).ToString(); break; case UInt256 asset_id_256: //Global Assets balance IEnumerable <Coin> coins = wallet.GetCoins().Where(p => !p.State.HasFlag(CoinState.Spent) && p.Output.AssetId.Equals(asset_id_256)); 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(); break; } return(json); } case "getbestblockhash": return(Blockchain.Singleton.CurrentBlockHash.ToString()); case "getblock": { Block block; if (_params[0] is JNumber) { uint index = (uint)_params[0].AsNumber(); block = Blockchain.Singleton.Store.GetBlock(index); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); block = Blockchain.Singleton.Store.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.Singleton.Height - block.Index + 1; UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(block.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(block.ToArray().ToHexString()); } case "getblockcount": return(Blockchain.Singleton.Height + 1); case "getblockhash": { uint height = (uint)_params[0].AsNumber(); if (height <= Blockchain.Singleton.Height) { return(Blockchain.Singleton.GetBlockHash(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getblockheader": { Header header; if (_params[0] is JNumber) { uint height = (uint)_params[0].AsNumber(); header = Blockchain.Singleton.Store.GetHeader(height); } else { UInt256 hash = UInt256.Parse(_params[0].AsString()); header = Blockchain.Singleton.Store.GetHeader(hash); } if (header == null) { throw new RpcException(-100, "Unknown block"); } bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false); if (verbose) { JObject json = header.ToJson(); json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1; UInt256 hash = Blockchain.Singleton.Store.GetNextBlockHash(header.Hash); if (hash != null) { json["nextblockhash"] = hash.ToString(); } return(json); } return(header.ToArray().ToHexString()); } case "getblocksysfee": { uint height = (uint)_params[0].AsNumber(); if (height <= Blockchain.Singleton.Height) { return(Blockchain.Singleton.Store.GetSysFeeAmount(height).ToString()); } throw new RpcException(-100, "Invalid Height"); } case "getconnectioncount": return(LocalNode.Singleton.ConnectedCount); case "getcontractstate": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractState contract = Blockchain.Singleton.Store.GetContracts().TryGet(script_hash); return(contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract")); } case "getnewaddress": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { WalletAccount account = wallet.CreateAccount(); if (wallet is NEP6Wallet nep6) { nep6.Save(); } return(account.Address); } case "getpeers": { JObject json = new JObject(); json["unconnected"] = new JArray(LocalNode.Singleton.GetUnconnectedPeers().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Address.ToString(); peerJson["port"] = p.Port; return(peerJson); })); json["bad"] = new JArray(); //badpeers has been removed json["connected"] = new JArray(LocalNode.Singleton.GetRemoteNodes().Select(p => { JObject peerJson = new JObject(); peerJson["address"] = p.Remote.Address.ToString(); peerJson["port"] = p.ListenerPort; return(peerJson); })); return(json); } case "getrawmempool": return(new JArray(Blockchain.Singleton.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); Transaction tx = Blockchain.Singleton.GetTransaction(hash); if (tx == null) { throw new RpcException(-100, "Unknown transaction"); } if (verbose) { JObject json = tx.ToJson(); uint? height = Blockchain.Singleton.Store.GetTransactions().TryGet(hash)?.BlockIndex; if (height != null) { Header header = Blockchain.Singleton.Store.GetHeader((uint)height); json["blockhash"] = header.Hash.ToString(); json["confirmations"] = Blockchain.Singleton.Height - header.Index + 1; json["blocktime"] = header.Timestamp; } return(json); } return(tx.ToArray().ToHexString()); } case "getstorage": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); byte[] key = _params[1].AsString().HexToBytes(); StorageItem item = Blockchain.Singleton.Store.GetStorages().TryGet(new StorageKey { ScriptHash = script_hash, Key = key }) ?? new StorageItem(); return(item.Value?.ToHexString()); } case "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString()); ushort index = (ushort)_params[1].AsNumber(); return(Blockchain.Singleton.Store.GetUnspent(hash, index)?.ToJson(index)); } case "getvalidators": using (Snapshot snapshot = Blockchain.Singleton.GetSnapshot()) { var validators = snapshot.GetValidators(); return(snapshot.GetEnrollments().Select(p => { JObject validator = new JObject(); validator["publickey"] = p.PublicKey.ToString(); validator["votes"] = p.Votes.ToString(); validator["active"] = validators.Contains(p.PublicKey); return validator; }).ToArray()); } case "getversion": { JObject json = new JObject(); json["port"] = LocalNode.Singleton.ListenerPort; json["nonce"] = LocalNode.Nonce; json["useragent"] = LocalNode.UserAgent; return(json); } case "getwalletheight": if (wallet == null) { throw new RpcException(-400, "Access denied."); } else { return((wallet.WalletHeight > 0) ? wallet.WalletHeight - 1 : 0); } case "invoke": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); ContractParameter[] parameters = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray(); byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, parameters).ToArray(); } return(GetInvokeResult(script)); } case "invokefunction": { UInt160 script_hash = UInt160.Parse(_params[0].AsString()); string operation = _params[1].AsString(); ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, operation, args).ToArray(); } return(GetInvokeResult(script)); } case "invokescript": { byte[] script = _params[0].AsString().HexToBytes(); return(GetInvokeResult(script)); } case "listaddress": if (wallet == null) { throw new RpcException(-400, "Access denied."); } else { return(wallet.GetAccounts().Select(p => { JObject account = new JObject(); account["address"] = p.Address; account["haskey"] = p.HasKey; account["label"] = p.Label; account["watchonly"] = p.WatchOnly; return account; }).ToArray()); } case "sendfrom": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 from = _params[1].AsString().ToScriptHash(); UInt160 to = _params[2].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[3].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 5 ? Fixed8.Parse(_params[4].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null; Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = to } }, from: from, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendmany": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { JArray to = (JArray)_params[0]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransferOutput[] outputs = new TransferOutput[to.Count]; for (int i = 0; i < to.Count; i++) { UIntBase asset_id = UIntBase.Parse(to[i]["asset"].AsString()); AssetDescriptor descriptor = new AssetDescriptor(asset_id); outputs[i] = new TransferOutput { AssetId = asset_id, Value = BigDecimal.Parse(to[i]["value"].AsString(), descriptor.Decimals), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; if (outputs[i].Value.Sign <= 0) { 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 ? _params[2].AsString().ToScriptHash() : null; Transaction tx = wallet.MakeTransaction(null, outputs, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "sendrawtransaction": { Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes()); Neo.SmartContract.Debug.DumpInfo.RegNeedLog(tx.Hash); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(tx).Result; return(GetRelayResult(reason)); } case "sendtoaddress": if (wallet == null) { throw new RpcException(-400, "Access denied"); } else { UIntBase assetId = UIntBase.Parse(_params[0].AsString()); AssetDescriptor descriptor = new AssetDescriptor(assetId); UInt160 scriptHash = _params[1].AsString().ToScriptHash(); BigDecimal value = BigDecimal.Parse(_params[2].AsString(), descriptor.Decimals); if (value.Sign <= 0) { throw new RpcException(-32602, "Invalid params"); } Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; if (fee < Fixed8.Zero) { throw new RpcException(-32602, "Invalid params"); } UInt160 change_address = _params.Count >= 5 ? _params[4].AsString().ToScriptHash() : null; Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, change_address: change_address, fee: fee); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } case "submitblock": { Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>(); RelayResultReason reason = system.Blockchain.Ask <RelayResultReason>(block).Result; return(GetRelayResult(reason)); } case "validateaddress": { JObject json = new JObject(); UInt160 scriptHash; try { scriptHash = _params[0].AsString().ToScriptHash(); } catch { scriptHash = null; } json["address"] = _params[0]; json["isvalid"] = scriptHash != null; return(json); } default: throw new RpcException(-32601, "Method not found"); } }
public void Standard(TransferOutput output) => this.TransferOutput = output;