public InvocationTransaction GetMintTransaction() { string contractCommand = "mintTokens"; UInt160 script_hash = UInt160.Parse(this.contractScriptHashTextBox.Text); byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitPush(0); sb.EmitPush(contractCommand); sb.EmitAppCall(script_hash.ToArray()); script = sb.ToArray(); } AssetState asset = (AssetState)this.assetComboBox.SelectedItem; TransactionOutput[] outputs = new TransactionOutput[] { new TransactionOutput { AssetId = asset.AssetId, ScriptHash = UInt160.Parse(this.contractScriptHashTextBox.Text), Value = Fixed8.Parse(this.amountTextBox.Text) } }; return(Program.CurrentWallet.MakeTransaction(new InvocationTransaction { Outputs = outputs, Script = script })); }
public void Can_parse_exponent_notation() { Fixed8 expected = Fixed8.FromDecimal(1.23m); Fixed8 actual = Fixed8.Parse("1.23E-0"); actual.Should().Be(expected); }
private void TransactAction(Account[] accountPair) { Program.CurrentWallet = accountPair[0].Wallet; int curWalletAmount = int.Parse(Program.CurrentWallet.GetAvailable(Blockchain.GoverningToken.Hash).ToString()); TransactionOutput[] outputs = new TransactionOutput[2]; outputs[0] = new TransactionOutput { AssetId = Blockchain.GoverningToken.Hash, ScriptHash = Wallet.ToScriptHash(accountPair[0].Address), Value = Fixed8.Parse(amount.ToString()) }; outputs[1] = new TransactionOutput { AssetId = Blockchain.GoverningToken.Hash, ScriptHash = Wallet.ToScriptHash(accountPair[1].Address), Value = Fixed8.Parse(amount.ToString()) }; if (curWalletAmount > amount) { TransactProcess(outputs, Program.CurrentWallet); } else { Thread.Sleep(16000); } }
public InvocationTransaction GetTransaction() { AssetType asset_type = (AssetType)cmbAssetType.SelectedItem; string name = string.IsNullOrWhiteSpace(TxbAssetName.Text) ? string.Empty : $"[{{\"lang\":\"{CultureInfo.CurrentCulture.Name}\",\"name\":\"{TxbAssetName.Text}\"}}]"; Fixed8 amount = (bool)ChkNoLimit.IsChecked ? -Fixed8.Satoshi : Fixed8.Parse(TxbAssetAmount.Text); byte precision = (byte)int.Parse(TxbAssetPrecision.Text); ECPoint owner = (ECPoint)cmbAssetOwner.SelectedItem; UInt160 admin = Wallet.ToScriptHash(cmbAssetAdmin.Text); UInt160 issuer = Wallet.ToScriptHash(cmbAssetIssuer.Text); Fixed8 AFee = Fixed8.Parse(TxbAssetAFee.Text); Fixed8 TFee = Fixed8.Zero; Fixed8 TFeeMin = Fixed8.Parse(TxbAssetTFeeMin.Text); Fixed8 TFeeMax = Fixed8.Parse(TxbAssetTFeeMax.Text); UInt160 feeAddress = Wallet.ToScriptHash(TxbAssetFeeAddress.Text); using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitSysCall("Pure.Asset.Create", asset_type, name, amount, precision, owner, admin, issuer, AFee, TFee, TFeeMin, TFeeMax, feeAddress); return(new InvocationTransaction { Attributes = new[] { new TransactionAttribute { Usage = TransactionAttributeUsage.Script, Data = Contract.CreateSignatureRedeemScript(owner).ToScriptHash().ToArray() } }, Script = sb.ToArray() }); } }
public void Basic_equality() { var a = Fixed8.FromDecimal(1.23456789m); var b = Fixed8.Parse("1.23456789"); a.Should().Be(b); }
private void Init() { accountB.walletAccounts = new WalletAccount[accountAmount]; Account[] accountPair = new Account[2]; accountPair[0] = accountA; accountPair[1] = accountB; for (int i = 0; i < 2; i++) { Program.CurrentWallet = accountPair[i].Wallet; int curWalletAmount = int.Parse(Program.CurrentWallet.GetAvailable(Blockchain.GoverningToken.Hash).ToString()); TransactionOutput[] outputs = new TransactionOutput[100]; for (int j = 0; j < 100; j++) { outputs[j] = new TransactionOutput { AssetId = Blockchain.GoverningToken.Hash, ScriptHash = Wallet.ToScriptHash(accountPair[i].Address), Value = Fixed8.Parse((curWalletAmount / 100).ToString()) }; } if (curWalletAmount >= amount * 100) { TransactProcess(outputs, Program.CurrentWallet); } else { Thread.Sleep(16000); } } }
private void TransactBackAction(WalletAccount target, Account account, int value) { Program.CurrentWallet = account.Wallet; int curWalletAmount = int.Parse(Program.CurrentWallet.GetAvailable(Blockchain.GoverningToken.Hash).ToString()); TransactionOutput[] outputs = new TransactionOutput[value / amount]; for (int i = 0; i < outputs.Length; i++) { outputs[i] = new TransactionOutput { AssetId = Blockchain.GoverningToken.Hash, ScriptHash = Wallet.ToScriptHash(target.Address), Value = Fixed8.Parse(amount.ToString()) }; } if (curWalletAmount >= value) { TransactProcess(outputs, Program.CurrentWallet); } else { Thread.Sleep(16000); } }
private void ProcessInvoke(JObject result) { if (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 = Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); } else { tx = null; } } result["tx"] = tx?.ToArray().ToHexString(); } }
public InvocationTransaction GetTransaction() { AssetType asset_type = (AssetType)comboBox1.SelectedItem; string name = string.IsNullOrWhiteSpace(textBox1.Text) ? string.Empty : $"[{{\"lang\":\"{CultureInfo.CurrentCulture.Name}\",\"name\":\"{textBox1.Text}\"}}]"; Fixed8 amount = checkBox1.Checked ? Fixed8.Parse(textBox2.Text) : -Fixed8.Satoshi; byte precision = (byte)numericUpDown1.Value; ECPoint owner = (ECPoint)comboBox2.SelectedItem; UInt160 admin = comboBox3.Text.ToScriptHash(); UInt160 issuer = comboBox4.Text.ToScriptHash(); using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitSysCall("Neo.Asset.Create", asset_type, name, amount, precision, owner, admin, issuer); return(new InvocationTransaction { Attributes = new[] { new TransactionAttribute { Usage = TransactionAttributeUsage.Script, Data = Contract.CreateSignatureRedeemScript(owner).ToScriptHash().ToArray() } }, Script = sb.ToArray() }); } }
///// <summary> ///// 获取指定地址的交易列表 ///// </summary> ///// <param name="_params[0]">地址</param> ///// <param name="_params[1]">起始索引位置,默认1</param> ///// <param name="_params[2]">偏移量,默认20</param> ///// <returns>交易列表</returns> //private JObject GetTransaction(JArray _params, JObject json) //{ // string from = _params[0].AsString(); // string position = _params[1].AsString() != "" ? _params[1].AsString() : "1"; // string offset = _params[2].AsString() != "" ? _params[2].AsString() : "20"; // string jsonRes = RequestRpc("findTxVout", $"address={from}&position={position}&offset={offset}"); // Newtonsoft.Json.Linq.JArray jsons = Newtonsoft.Json.Linq.JArray.Parse(jsonRes); // json["transaction"] = new JArray(jsons.Select(p => // { // JObject peerJson = new JObject(); // peerJson["blockHeight"] = p["blockHeight"].ToString(); // peerJson["txid"] = p["txid"].ToString(); // peerJson["type"] = p["type"].ToString(); // Newtonsoft.Json.Linq.JToken[] jt = p["inAddress"].ToArray(); // JArray j_inaddress = new JArray(); // foreach (Newtonsoft.Json.Linq.JToken i in jt) // { // string s = i.ToString(); // j_inaddress.Add(s); // } // peerJson["inputaddress"] = j_inaddress; // peerJson["asset"] = p["asset"].ToString(); // peerJson["n"] = (int)p["n"]; // peerJson["value"] = (double)p["value"]; // peerJson["outputaddress"] = p["address"].ToString(); // peerJson["time"] = p["time"].ToString(); // peerJson["utctime"] = (int)p["utcTime"]; // peerJson["confirmations"] = p["confirmations"].ToString(); // return peerJson; // })); // return json; //} /// <summary> /// 获取交易的的十六进制字符串(不上链) /// </summary> /// <param name="_params[0]">资产 ID</param> /// <param name="_params[1]">收款地址</param> /// <param name="_params[2]">转账金额</param> /// <param name="_params[3]">手续费,可选参数,默认为 0</param> /// <param name="_params[4]">找零地址,可选参数,默认为钱包中第一个标准地址</param> /// <param name="_params[5]">bhp手续费地址,可选参数。(转账资产为BHP时,此参数无效)</param> /// <returns>交易的的十六进制字符串</returns> private JObject GetTransactionData(JArray _params) { if (wallet == null || walletTimeLock.IsLocked()) { 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; UInt160 fee_address = _params.Count >= 6 ? _params[5].AsString().ToScriptHash() : null; if (assetId.Equals(Blockchain.GoverningToken.Hash)) { fee_address = null; } Transaction tx = wallet.MakeTransaction(null, new[] { new TransferOutput { AssetId = assetId, Value = value, ScriptHash = scriptHash } }, fee_address: fee_address, 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(); if (tx.Size > Transaction.MaxTransactionSize) { throw new RpcException(-301, "The data is too long."); } return(Bhp.IO.Helper.ToArray(tx).ToHexString()); } else { return(context.ToJson()); } } }
public RPCSettings(IConfigurationSection section) { this.BindAddress = IPAddress.Parse(section.GetSection("BindAddress").Value); this.Port = ushort.Parse(section.GetSection("Port").Value); this.SslCert = section.GetSection("SslCert").Value; this.SslCertPassword = section.GetSection("SslCertPassword").Value; this.MaxGasInvoke = Fixed8.Parse(section.GetValue("MaxGasInvoke", "0")); }
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string s) { return(Fixed8.Parse(s)); } throw new NotSupportedException(); }
private void CreateChannel(string uri, string peerUri, string asset, string deposit) { // Send RegisterChannel Messages to peer RegisterChannelHandler registerChannelHndl = new RegisterChannelHandler( uri, peerUri, null, asset, null, Fixed8.Parse(deposit).GetData()); registerChannelHndl.MakeTransaction(); }
/// <summary> /// Preprocess is called prior to `/construction/payloads` to construct a request for any metadata that is needed for transaction construction given (i.e. account nonce). /// The request returned from this method will be used by the caller (in a different execution environment) to call the `/construction/metadata` endpoint. /// </summary> /// <param name="request"></param> /// <returns></returns> public JObject ConstructionPreprocess(ConstructionPreprocessRequest request) { // the metadata in request should include tx type and type specific info Metadata metadata = request.Metadata; if (metadata is null || metadata.Pairs is null || metadata.Pairs.Count == 0) { return(Error.TX_METADATA_INVALID.ToJson()); } if (!metadata.TryGetValue("tx_type", out JObject txType)) { return(Error.TX_METADATA_INVALID.ToJson()); } try { switch (txType.AsString()) { case nameof(ClaimTransaction): JArray coins = metadata["claims"] as JArray; CoinReference[] coinReferences = coins.Select(p => new CoinReference() { PrevHash = UInt256.Parse(p["txid"].AsString()), PrevIndex = ushort.Parse(p["vout"].AsString()) }).ToArray(); break; case nameof(ContractTransaction): break; case nameof(InvocationTransaction): byte[] script = metadata["script"].AsString().HexToBytes(); Fixed8 gas = Fixed8.Parse(metadata["gas"].AsString()); break; case nameof(StateTransaction): JArray descriptors = metadata["descriptors"] as JArray; StateDescriptor[] stateDescriptors = descriptors.Select(p => new StateDescriptor() { Type = p["type"].TryGetEnum <StateType>(), Key = p["key"].AsString().HexToBytes(), Field = p["field"].AsString(), Value = p["value"].AsString().HexToBytes() }).ToArray(); break; default: throw new NotSupportedException(); } } catch (Exception) { return(Error.TX_METADATA_INVALID.ToJson()); } ConstructionPreprocessResponse response = new ConstructionPreprocessResponse(request.Metadata); return(response.ToJson()); }
public TransactionOutput GetOutput() { return(new TransactionOutput { AssetId = (comboBox1.SelectedItem as RegisterTransaction).Hash, Value = Fixed8.Parse(textBox2.Text), ScriptHash = Wallet.ToScriptHash(textBox1.Text) }); }
/// <summary> /// 分发资产 /// </summary> /// <param name="_params[0]">资产 ID</param> /// <param name="_params[1]">数组{"address": \<收款地址>,"value": \<转账金额>}</param> /// <returns>交易</returns> private JObject SendIssueTransaction(JArray _params) { if (wallet == null || walletTimeLock.IsLocked()) { throw new RpcException(-400, "Access denied"); } else { UInt256 asset_id = UInt256.Parse(_params[0].AsString()); JArray to = (JArray)_params[1]; if (to.Count == 0) { throw new RpcException(-32602, "Invalid params"); } TransactionOutput[] outputs = new TransactionOutput[to.Count]; for (int i = 0; i < to.Count; i++) { outputs[i] = new TransactionOutput { AssetId = asset_id, Value = Fixed8.Parse(to[i]["value"].AsString()), ScriptHash = to[i]["address"].AsString().ToScriptHash() }; } IssueTransaction tx = wallet.MakeTransaction(new IssueTransaction { Version = 1, Outputs = outputs }, fee: Fixed8.One); if (tx == null) { throw new RpcException(-300, "Insufficient funds"); } ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); if (tx.Size > Transaction.MaxTransactionSize) { throw new RpcException(-301, "The size of the free transaction must be less than 102400 bytes"); } wallet.ApplyTransaction(tx); system.LocalNode.Tell(new LocalNode.Relay { Inventory = tx }); return(tx.ToJson()); } else { return(context.ToJson()); } } }
private JObject GetInvokeResult(UInt160 chain_hash, byte[] script) { Blockchain blockchain = Blockchain.GetBlockchain(chain_hash); if (blockchain == null) { throw new RpcException(-100, "Unknown blockchain"); } ApplicationEngine engine = ApplicationEngine.Run(script, blockchain.GetSnapshot()); JObject json = new JObject(); json["script"] = script.ToHexString(); json["state"] = engine.State; json["gas_consumed"] = engine.GasConsumed.ToString(); try { json["stack"] = new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson())); } catch (InvalidOperationException) { json["stack"] = "error: recursive reference"; } if (wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = json["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(json["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx, blockchain); wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); } else { tx = null; } } json["tx"] = tx?.ToArray().ToHexString(); } return(json); }
public void Parse_InvalidLongValueAsString_ParseReturnFormatException() { const string invalidString = "xxx"; Action parseAction = () => Fixed8.Parse(invalidString); parseAction .Should() .Throw <FormatException>(); }
public static TransactionOutput FromJson(JObject json) { TransactionOutput output = new TransactionOutput(); output.AssetId = UInt256.Parse(json["asset"].AsString()); output.Value = Fixed8.Parse(json["value"].AsString()); output.ScriptHash = Wallet.ToScriptHash(json["address"].AsString()); output.Fee = Fixed8.Parse(json["fee"].AsString()); return(output); }
public static TransactionOutput FromJsonString(JObject json) { TransactionOutput output = new TransactionOutput(); output.AssetId = UInt256.Parse("0x" + json["assetId"].AsString()); output.Value = Fixed8.Parse(json["value"].AsString()); output.ScriptHash = UInt160.Parse("0x" + json["scriptHash"].AsString()); output.Fee = Fixed8.Parse(json["fee"].AsString()); return(output); }
public void Parse_ValidLongValueAsString_ParseIsOk() { const long longValue = 1; const int expectedFixed8LongValue = 100000000; var actual = Fixed8.Parse(longValue.ToString()); Asserting .That(actual) .AsLongValue(expectedFixed8LongValue); }
private void ImportAssetsFromFile() { const string fileName = "assets.acc"; var importPath = Tools.GetImportDirectory(); if (!Directory.Exists(importPath)) { _logger?.Error($"Directory {importPath} does not exist."); return; } _logger?.Info($"Scan directory: {importPath}"); var filePath = $"{importPath}{fileName}"; var fileExist = File.Exists(filePath); if (!fileExist) { _logger?.Error($"No file {fileName} into directory {importPath}"); return; } _logger?.Info($"-Import assets from file: {DateTime.Now}"); var fileContent = File.ReadAllText(filePath); var jObject = JObject.Parse(fileContent); var assets = new List <AssetState>(); foreach (var jAsset in (JArray)jObject) { var assetTypeValue = jAsset["type"].AsString(); if (Enum.TryParse(assetTypeValue, true, out AssetType assetType)) { var asset = new AssetState { AssetId = UInt256.Parse(jAsset["id"].AsString()), AssetType = (AssetType)assetType, Name = jAsset["name"].AsString(), Amount = Fixed8.Parse(jAsset["amount"].AsString()), Available = Fixed8.Parse(jAsset["available"].AsString()), Issuer = UInt160.Parse(jAsset["issuer"].AsString()), Precision = byte.Parse(jAsset["precision"].AsString()), Fee = Fixed8.Parse(jAsset["fee"].AsString()), FeeAddress = UInt160.Parse(jAsset["feeaddress"].AsString()), Owner = ECPoint.Parse(jAsset["owner"].AsString(), ECCurve.Secp256r1), Admin = UInt160.Parse(jAsset["admin"].AsString()), Expiration = uint.Parse(jAsset["expiration"].AsString()), IsFrozen = bool.Parse(jAsset["isfrozen"].AsString()) }; assets.Add(asset); } } var newFileName = $"{importPath}{fileName}p"; File.Move(filePath, newFileName); ImportAssets(assets); _logger?.Info($"-Finish import assets from files: {DateTime.Now}"); }
public override Validator ReadJson(JsonReader reader, Type objectType, Validator existingValue, bool hasExistingValue, JsonSerializer serializer) { Debug.Assert(reader.TokenType == JsonToken.StartObject); // TODO: read w/o loading full JObject var result = JObject.ReadFrom(reader); var key = EncodedPublicKey.Parse(result.Value <string>("publickey")); var votes = Fixed8.Parse(result.Value <string>("votes")); var active = result.Value <bool>("active"); return(new Validator(key, active, votes)); }
public RegisterTransaction GetTransaction() { return(Program.CurrentWallet.MakeTransaction(new RegisterTransaction { AssetType = (AssetType)comboBox1.SelectedItem, Name = (AssetType)comboBox1.SelectedItem == AssetType.Share ? string.Empty : $"[{{'lang':'zh-CN','name':'{textBox1.Text}'}}]", Amount = checkBox1.Checked ? Fixed8.Parse(textBox2.Text) : -Fixed8.Satoshi, Issuer = (ECPoint)comboBox2.SelectedItem, Admin = Wallet.ToScriptHash(comboBox3.Text), Outputs = new TransactionOutput[0] }, Fixed8.Zero)); }
public TxOutListBoxItem GetOutput() { AssetDescriptor asset = (AssetDescriptor)comboBox1.SelectedItem; return(new TxOutListBoxItem { AssetName = asset.AssetName, AssetId = asset.AssetId, Value = new BigDecimal(Fixed8.Parse(textBox2.Text).GetData(), 8), ScriptHash = Wallet.ToScriptHash(textBox1.Text) }); }
public RegisterTransaction GetTransaction() { return(Program.CurrentWallet.MakeTransaction(new RegisterTransaction { AssetType = (AssetType)comboBox1.SelectedItem, Name = string.IsNullOrWhiteSpace(textBox1.Text) ? string.Empty : $"[{{\"lang\":\"{CultureInfo.CurrentCulture.Name}\",\"name\":\"{textBox1.Text}\"}}]", Amount = checkBox1.Checked ? Fixed8.Parse(textBox2.Text) : -Fixed8.Satoshi, Precision = (byte)numericUpDown1.Value, Owner = (ECPoint)comboBox2.SelectedItem, Admin = Wallet.ToScriptHash(comboBox3.Text), Outputs = new TransactionOutput[0] }, fee: Fixed8.Zero)); }
public RegisterTransaction GetTransaction() { return(Program.CurrentWallet.MakeTransaction(new RegisterTransaction { AssetType = (AssetType)comboBox1.SelectedItem, Name = (AssetType)comboBox1.SelectedItem == AssetType.Share ? string.Empty : $"[{{\"lang\":\"{CultureInfo.CurrentCulture.Name}\",\"name\":\"{textBox1.Text}\"}}]", Amount = checkBox1.Checked ? Fixed8.Parse(textBox2.Text) : -Fixed8.Satoshi, Precision = 8, Issuer = (ECPoint)comboBox2.SelectedItem, Admin = Wallet.ToScriptHash(comboBox3.Text), Outputs = new TransactionOutput[0] }, Fixed8.Zero)); }
public TransactionOutput[] GetOutputs() { return(textBox3.Lines.Where(p => !string.IsNullOrWhiteSpace(p)).Select(p => { UInt256 asset_id = (comboBox1.SelectedItem as AssetState).AssetId; string[] line = p.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); return new TransactionOutput { AssetId = asset_id, Value = Fixed8.Parse(line[1]), ScriptHash = Wallet.ToScriptHash(line[0]) }; }).ToArray()); }
public RegisterTransaction GetTransaction() { RegisterTransaction tx = Program.CurrentWallet.MakeTransaction <RegisterTransaction>(new TransactionOutput[0], Fixed8.Zero); if (tx == null) { return(null); } tx.AssetType = (AssetType)comboBox1.SelectedItem; tx.Name = tx.AssetType == AssetType.Share ? string.Empty : $"[{{'lang':'zh-CN','name':'{textBox1.Text}'}}]"; tx.Amount = checkBox1.Checked ? Fixed8.Parse(textBox2.Text) : -Fixed8.Satoshi; tx.Issuer = (ECPoint)comboBox2.SelectedItem; tx.Admin = Wallet.ToScriptHash(comboBox3.Text); return(tx); }
private JObject GetInvokeResult(byte[] script) { ApplicationEngine engine = ApplicationEngine.Run(script, extraGAS: maxGasInvoke); JObject json = new JObject(); json["script"] = script.ToHexString(); json["state"] = engine.State; json["gas_consumed"] = engine.GasConsumed.ToString(); try { json["stack"] = new JArray(engine.ResultStack.Select(p => p.ToParameter().ToJson())); } catch (InvalidOperationException) { json["stack"] = "error: recursive reference"; } if (Wallet != null) { InvocationTransaction tx = new InvocationTransaction { Version = 1, Script = json["script"].AsString().HexToBytes(), Gas = Fixed8.Parse(json["gas_consumed"].AsString()) }; tx.Gas -= Fixed8.FromDecimal(10); if (tx.Gas < Fixed8.Zero) { tx.Gas = Fixed8.Zero; } tx.Gas = tx.Gas.Ceiling(); tx = Wallet.MakeTransaction(tx); if (tx != null) { ContractParametersContext context = new ContractParametersContext(tx); Wallet.Sign(context); if (context.Completed) { tx.Witnesses = context.GetWitnesses(); } else { tx = null; } } json["tx"] = tx?.ToArray().ToHexString(); } return(json); }