private bool CallNoInvoke(InvocationTransaction tx, out byte[] txhash) { ApplicationEngine engine = ApplicationEngine.Run(tx.Script, tx); bool fault = engine.State.HasFlag(VMState.FAULT); Fixed8 gas = engine.GasConsumed - Fixed8.FromDecimal(10); if (gas < Fixed8.Zero) { gas = Fixed8.Zero; } var obj = new { VMState = engine.State.ToString(), GasConsumed = (decimal)engine.GasConsumed, EvaluationStack = engine.ResultStack.Select(p => p.ToParameter()).ToArray(), GasToSpend = (decimal)gas.Ceiling() }; string res = JsonConvert.SerializeObject(obj); txhash = Encoding.UTF8.GetBytes(res); return(!fault); }
public static InvocationTransaction MakeMultiSignatureTransaction(byte[] script, int m, KeyPair[] keypairs, Fixed8 gasLimit, Fixed8 gasPrice) { InvocationTransaction tx = new InvocationTransaction { Nonce = Transaction.GetNonce(), Script = script, GasPrice = gasPrice, GasLimit = gasLimit.Ceiling(), Account = GetMultiSigRedeemScriptHash(m, keypairs) }; int count = keypairs.Length; ECPoint[] pubkeys = keypairs.Select(p => p.PublicKey).ToArray(); tx.Attributes = new TransactionAttribute[0]; byte[] data = GetHashData(tx); byte[][] signatures = new byte[count][]; int i = 0; foreach (KeyPair keypair in keypairs.OrderBy(p => p.PublicKey)) { signatures[i++] = Sign(data, keypair.PrivateKey, keypair.PublicKey); } AddWitness(tx, signatures, m, pubkeys); return(tx); }
public static InvocationTransaction MakeTransaction(byte[] script, KeyPair keypair, Fixed8 gasLimit, Fixed8 gasPrice) { InvocationTransaction tx = new InvocationTransaction { Nonce = Transaction.GetNonce(), Script = script, GasPrice = gasPrice, GasLimit = gasLimit.Ceiling(), Account = GetPublicKeyHash(keypair.PublicKey) }; tx.Attributes = new TransactionAttribute[1]; TransactionAttribute transactionAttribute = new TransactionAttribute() { Usage = TransactionAttributeUsage.Remark1, Data = Encoding.UTF8.GetBytes("TestTestTest") }; tx.Attributes[0] = transactionAttribute; byte[] data = GetHashData(tx); byte[] signdata = Sign(data, keypair.PrivateKey, keypair.PublicKey); AddWitness(tx, signdata, keypair.PublicKey); return(tx); }
/// <summary> /// 获取GAS消耗 /// </summary> /// <param name="consumed">实际消耗的gas</param> /// <returns> /// GAS消息等于实际消耗的GAS减去免费的10GAS; /// 若gas消耗小于等于0,则返回0; /// 最后对gas消耗取上整数 /// </returns> public static Fixed8 GetGas(Fixed8 consumed) { Fixed8 gas = consumed - Fixed8.FromDecimal(10); if (gas <= Fixed8.Zero) { return(Fixed8.Zero); } return(gas.Ceiling()); }
public void Ceilling_Provide100000000Fixed8Object_NoCellingNeeded() { var actual = new Fixed8(100000000); var cellingValue = actual.Ceiling(); Asserting .That(cellingValue) .IsEqual(actual); }
public static Fixed8 GetGasLimit(Fixed8 consumed) { Fixed8 gas = consumed; if (gas <= Fixed8.Zero) { return(Fixed8.Zero); } return(gas.Ceiling()); }
public static Fixed8 GetGas(Fixed8 consumed, Fixed8 freeAmount) { Fixed8 gas = consumed - freeAmount; if (gas <= Fixed8.Zero) { return(Fixed8.Zero); } return(gas.Ceiling()); }
public static Fixed8 GetFuel(Fixed8 consumed) { Fixed8 fuel = consumed - Fixed8.FromDecimal(10); if (fuel <= Fixed8.Zero) { return(Fixed8.Zero); } return(fuel.Ceiling()); }
public void Ceilling_Provide100500000Fixed8Object_RemaiderLessThanZeroLogic() { var actual = new Fixed8(-100500000); var expectedCeillingFixed8 = new Fixed8(-100000000); var cellingValue = actual.Ceiling(); Asserting .That(cellingValue) .IsEqual(expectedCeillingFixed8); }
public static Fixed8 GetGas(Fixed8 consumed) { TR.Enter(); Fixed8 gas = consumed - Fixed8.FromDecimal(10); if (gas <= Fixed8.Zero) { return(TR.Exit(Fixed8.Zero)); } return(TR.Exit(gas.Ceiling())); }
private static Fixed8 GetGasConsumed(byte[] script) { RpcInvokeResult response = rpcClient.InvokeScript(script); if (Fixed8.TryParse(response.GasConsumed, out Fixed8 result)) { Fixed8 gas = result - Fixed8.FromDecimal(10); if (gas <= Fixed8.Zero) { return(Fixed8.Zero); } else { return(gas.Ceiling()); } } throw new Exception(); }
public static InvocationTransaction MakeTransaction(byte[] script, KeyPair keypair, Fixed8 gasLimit, Fixed8 gasPrice) { InvocationTransaction tx = new InvocationTransaction { Nonce = Transaction.GetNonce(), Script = script, GasPrice = gasPrice, GasLimit = gasLimit.Ceiling(), Account = GetPublicKeyHash(keypair.PublicKey) }; tx.Attributes = new TransactionAttribute[0]; byte[] data = GetHashData(tx); byte[] signdata = Sign(data, keypair.PrivateKey, keypair.PublicKey); AddWitness(tx, signdata, keypair.PublicKey); return(tx); }
public static bool Exec(Wallet wallet, LocalNode node, UInt160 scriptHash, UInt160 changeAddress, string operation, params object[] args) { byte[] script = MakeExecScript(scriptHash, operation, args); ApplicationEngine engine = ApplicationEngine.Run(script); Fixed8 gas = engine.GasConsumed - Fixed8.FromDecimal(10); if (gas < Fixed8.Zero) { gas = Fixed8.Zero; } gas = gas.Ceiling(); Fixed8 fee = gas.Equals(Fixed8.Zero) ? Fixed8.FromDecimal(0.001m) : Fixed8.Zero; InvocationTransaction it = wallet.MakeTransaction(new InvocationTransaction { Version = 1, Script = script, Gas = gas, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new TransactionOutput[0] }, change_address: changeAddress, fee: fee); return(SignAndShowInformation(wallet, node, it)); }
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 "signdata": if (Program.Wallet == null) { throw new RpcException(-400, "Access denied"); } else { byte[] data = System.Text.Encoding.UTF8.GetBytes(_params[0].AsString()); KeyPair keys = Program.Wallet.GetAccounts().First().GetKey(); using (keys.Decrypt()) { byte[] pubkey = keys.PublicKey.EncodePoint(false).Skip(1).ToArray(); return(Convert.ToBase64String(Crypto.Default.Sign(data, keys.PrivateKey, pubkey))); } } 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 "executescript": { if (Program.Wallet == null) { return(false); } byte[] script = _params[0].AsString().HexToBytes(); ApplicationEngine engine = ApplicationEngine.Run(script); Fixed8 gas = engine.GasConsumed - Fixed8.FromDecimal(10); if (gas < Fixed8.Zero) { gas = Fixed8.Zero; } gas = gas.Ceiling(); Fixed8 fee = gas.Equals(Fixed8.Zero) ? Fixed8.FromDecimal(0.001m) : Fixed8.Zero; InvocationTransaction tx = Program.Wallet.MakeTransaction(new InvocationTransaction { Version = 1, Script = script, Gas = gas, Attributes = new TransactionAttribute[0], Inputs = new CoinReference[0], Outputs = new TransactionOutput[0] }, fee: fee); if (tx == null) { return(false); } ContractParametersContext context; try { context = new ContractParametersContext(tx); } catch (Exception) { return(false); } Program.Wallet.Sign(context); if (!context.Completed) { return(false); } context.Verifiable.Scripts = context.GetScripts(); Program.Wallet.ApplyTransaction(tx); return(LocalNode.Relay(tx)); } default: return(base.Process(method, _params)); } }