public static LuaVMCall Decode(string str) { try { var luaVMCall = new LuaVMCall(); string[] arrayName = str.Split('('); luaVMCall.fnName = arrayName[0]; arrayName[1] = arrayName[1].Replace(" ", "").Replace(")", ""); string[] arrayParam = arrayName[1].Split(','); var list = new List <FieldParam>(); for (int i = 0; i < arrayParam.Length; i++) { string[] arraytype = arrayParam[i].Split(':'); if (arraytype.Length == 2) { var fieldParam = new FieldParam(); fieldParam.type = arraytype[0]; fieldParam.value = arraytype[1]; list.Add(fieldParam); } } luaVMCall.args = list.ToArray(); return(luaVMCall); } catch (Exception) { return(null); } }
public Dictionary <string, RuleInfo> GetRules(string address, long height, bool bCommit = false) { Dictionary <string, RuleInfo> rules = new Dictionary <string, RuleInfo>(); try { LuaEnv luaenv = GetLuaEnv(address); LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; using (DbSnapshot dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot()) { s_dbSnapshot = dbSnapshot; LuaVMContext Storages = dbSnapshot?.Storages.Get(address); // rapidjson待优化,改为直接在C#层调用 luaenv.DoString(initScript); luaVMScript = dbSnapshot.Contracts.Get(address); LuaVMContext = dbSnapshot.Storages.Get(address); luaenv.DoString(luaVMScript.script); luaenv.DoString($"Storages = rapidjson.decode('{LuaVMContext.jsonData.ToStr()}')\n"); luaVMCall.fnName = "Update"; luaVMCall.args = new FieldParam[0]; object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.DoString($"curHeight = {height}\n"); luaFun.Call(args); // 待优化,改为直接在C#层调用 luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); if (bCommit) { dbSnapshot.Storages.Add(address, LuaVMContext); dbSnapshot.Commit(); } JToken jdStorages = JToken.Parse(LuaVMContext.jsonData.ToStr()); JToken[] jdRule = jdStorages["Rules"].ToArray(); for (int ii = 0; ii < jdRule.Length; ii++) { RuleInfo rule = new RuleInfo(); rule.Address = jdRule[ii]["Address"].ToString(); rule.Start = long.Parse(jdRule[ii]["Start"].ToString()); rule.End = long.Parse(jdRule[ii]["End"].ToString()); rules.Remove(rule.Address); rules.Add(rule.Address, rule); } } } catch (Exception e) { Log.Debug(e.ToString()); Log.Info("GetRules Error!"); } return(rules); }
public bool LuaCreate(LuaVMDB dbSnapshot, string sender, string data, long timestamp, string depend, long height, out string consAddress) { LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; LuaEnv luaenv = GetLuaEnv(depend, "LuaCreate"); consAddress = GetContractAddress(sender, data, timestamp, depend); try { LuaVMStack.Enqueue(consAddress, sender); luaenv.DoString(initScript); luaVMScript = new LuaVMScript() { script = FileHelper.GetFileData($"./Data/Contract/{depend}.lua").ToByteArray(), tablName = depend }; LuaVMContext = new LuaVMContext() { jsonData = "{}".ToByteArray() }; luaVMCall = LuaVMCall.Decode(data); dbSnapshot.Contracts.Add(consAddress, luaVMScript); luaenv.DoString(luaVMScript.script); object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.Global.Set("curHeight", height); luaenv.Global.Set("sender", sender); luaenv.Global.Set("addressThis", consAddress); if (luaFun != null) { luaFun.Call(args); // rapidjson luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); dbSnapshot.Storages.Add(consAddress, LuaVMContext); return(true); } } catch (Exception e) { throw e; } finally { LuaVMStack.Dequeue(); } return(false); }
public void OnBeRuler(HttpMessage httpMessage) { var consensus = Entity.Root.GetComponent <Consensus>(); var blockMgr = Entity.Root.GetComponent <BlockMgr>(); // 判断当前块高度是否接近主线 if (blockMgr.newBlockHeight - consensus.transferHeight > 1000) { httpMessage.result = $"{consensus.transferHeight}:{blockMgr.newBlockHeight} The current block height is too low. command BeRuler have been ignore."; return; } WalletKey key = Wallet.GetWallet().GetCurWallet(); var address = key.ToAddress(); long notice = 1; using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0)) { var account = dbSnapshot.Accounts.Get(address); if (account != null) { notice = account.nonce + 1; } } BlockSub transfer = new BlockSub(); transfer.addressIn = address; transfer.addressOut = consensus.consAddress; transfer.amount = "0"; transfer.nonce = notice; transfer.type = "contract"; LuaVMCall luaVMCall = new LuaVMCall(); luaVMCall.fnName = "add"; luaVMCall.args = new FieldParam[0]; transfer.data = luaVMCall.Encode(); transfer.timestamp = TimeHelper.Now(); transfer.hash = transfer.ToHash(); transfer.sign = transfer.ToSign(key); var rel = Entity.Root.GetComponent <Rule>().AddTransfer(transfer); if (rel == -1) { OnTransferAsync(transfer); } httpMessage.result = $"accepted transfer:{transfer.hash}"; }
public bool LuaCall(LuaVMDB dbSnapshot, string consAddress, string sender, string data, long height, out object[] result) { LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; LuaEnv luaenv = GetLuaEnv(consAddress, "LuaCall"); result = null; try { LuaVMStack.Enqueue(consAddress, sender); luaenv.DoString(initScript); luaVMScript = LuaVMScript.Get(dbSnapshot, consAddress); LuaVMContext = dbSnapshot.Storages.Get(consAddress); luaVMCall = LuaVMCall.Decode(data); luaenv.DoString(luaVMScript.script, consAddress); luaenv.DoString($"Storages = rapidjson.decode('{LuaVMContext.jsonData.ToStr()}')\n"); object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.Global.Set("curHeight", height); luaenv.Global.Set("sender", sender); luaenv.Global.Set("addressThis", consAddress); if (luaFun != null) { result = luaFun.Call(args); // rapidjson luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); dbSnapshot.Storages.Add(consAddress, LuaVMContext); return(true); } } catch (Exception e) { throw e; } finally { LuaVMStack.Dequeue(); } return(false); }
public void OnBeRuler(HttpMessage httpMessage) { Consensus consensus = Entity.Root.GetComponent <Consensus>(); WalletKey key = Wallet.GetWallet().GetCurWallet(); var address = key.ToAddress(); long notice = 1; using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0)) { var account = dbSnapshot.Accounts.Get(address); if (account != null) { notice = account.notice + 1; } } Transfer transfer = new Transfer(); transfer.addressIn = address; transfer.addressOut = consensus.consAddress; transfer.amount = "0"; transfer.notice = notice; transfer.type = "contract"; LuaVMCall luaVMCall = new LuaVMCall(); luaVMCall.fnName = "Add"; luaVMCall.args = new FieldParam[0]; //luaVMCall.args[0] = new FieldParam(); //luaVMCall.args[0].type = "Int64"; //luaVMCall.args[0].value = "999"; //long aaa = (long)luaVMCall.args[0].GetValue(); transfer.data = luaVMCall.Encode(); transfer.hash = transfer.ToHash(); transfer.sign = transfer.ToSign(key); var rel = Entity.Root.GetComponent <Rule>().AddTransfer(transfer); if (rel == -1) { OnTransferAsync(transfer); } httpMessage.result = $"accepted transfer:{transfer.hash}"; }
public static LuaVMCall Decode(string str) { var luaVMCall = new LuaVMCall(); try { string[] arrayName = str.Split('('); luaVMCall.fnName = arrayName[0]; arrayName[1] = arrayName[1].Replace(" ", "").Replace(")", ""); var list = new List <FieldParam>(); if (arrayName[1] != "") { string[] arrayParam = arrayName[1].Split(','); for (int i = 0; i < arrayParam.Length; i++) { int indexOf = arrayParam[i].IndexOf("\""); if (indexOf != -1) { var fieldParam = new FieldParam(); fieldParam.type = "String"; fieldParam.value = arrayParam[i].Replace("\"", ""); list.Add(fieldParam); } else { var fieldParam = new FieldParam(); fieldParam.type = "UInt64"; fieldParam.value = arrayParam[i]; list.Add(fieldParam); } } } luaVMCall.args = list.ToArray(); if (luaVMCall.fnName[0] == '_') { throw new Exception($"{luaVMCall.fnName} is private function"); } return(luaVMCall); } catch (Exception e) { throw e; } }
public bool Execute(DbSnapshot dbSnapshot, BlockSub transfer, long height, out object[] result) { LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; result = null; try { string address = GetContractAddress(transfer); LuaEnv luaenv = GetLuaEnv(address); //LuaEnv Global s_consAddress = address; s_transfer = transfer; s_dbSnapshot = dbSnapshot; luaenv.DoString(initScript); if (string.IsNullOrEmpty(transfer.addressOut)) { // 已存在 if (dbSnapshot.Contracts.Get(address) != null) { return(false); } luaVMScript = new LuaVMScript() { script = FileHelper.GetFileData($"./Data/Contract/{transfer.depend}.lua").ToByteArray() }; LuaVMContext = new LuaVMContext() { jsonData = "{}".ToByteArray() }; luaVMCall = LuaVMCall.Decode(transfer.data); dbSnapshot.Contracts.Add(address, luaVMScript); luaenv.DoString(luaVMScript.script); } else { luaVMScript = dbSnapshot.Contracts.Get(address); LuaVMContext = dbSnapshot.Storages.Get(address); luaVMCall = LuaVMCall.Decode(transfer.data); luaenv.DoString(luaVMScript.script, transfer.addressOut); luaenv.DoString($"Storages = rapidjson.decode('{LuaVMContext.jsonData.ToStr()}')\n"); } object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.Global.Set("curHeight", height); luaenv.Global.Set("sender", transfer.addressIn); result = luaFun?.Call(args); // rapidjson luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); dbSnapshot.Storages.Add(address, LuaVMContext); luaenv.GC(); s_consAddress = ""; s_dbSnapshot = null; return(true); } catch (Exception e) { Log.Error(e); Log.Info($"LuaVMEnv.Execute Error, transfer.hash: {transfer.hash} , contract: {transfer.addressOut} func:{luaVMCall.fnName}"); } s_consAddress = ""; s_dbSnapshot = null; return(false); }
public void Execute(DbSnapshot dbSnapshot, Transfer transfer, long height) { LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; try { s_dbSnapshot = dbSnapshot; string address = (transfer.addressOut == null || transfer.addressOut == "") ? Wallet.ToAddress(CryptoHelper.Sha256(Encoding.UTF8.GetBytes(transfer.data))) : transfer.addressOut; LuaEnv luaenv = GetLuaEnv(address); // rapidjson待优化,改为直接在C#层调用 luaenv.Global.Set("contractAddress", address); luaenv.Global.Set("dbSnapshot", dbSnapshot); luaenv.DoString(initScript); if (transfer.addressOut == null || transfer.addressOut == "") { // 当前版本只能由superAddress发布智能合约 if (consensus.superAddress != transfer.addressIn) { return; } luaVMScript = new LuaVMScript() { script = Base58.Decode(transfer.data) }; LuaVMContext = new LuaVMContext() { jsonData = "{}".ToByteArray() }; luaVMCall.fnName = "Create"; luaVMCall.args = new FieldParam[0]; if (dbSnapshot.Contracts.Get(address) == null) { dbSnapshot.Contracts.Add(address, luaVMScript); } luaenv.DoString(luaVMScript.script); } else { luaVMScript = dbSnapshot.Contracts.Get(address); LuaVMContext = dbSnapshot.Storages.Get(address); luaVMCall = LuaVMCall.Decode(transfer.data); luaenv.DoString(luaVMScript.script, transfer.addressOut); luaenv.DoString($"Storages = rapidjson.decode('{LuaVMContext.jsonData.ToStr()}')\n"); } object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.DoString($"curHeight = {height}\n"); luaenv.DoString($"curAddress = '{transfer.addressIn}'\n"); luaFun.Call(args); // 待优化,改为直接在C#层调用 luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); dbSnapshot.Storages.Add(address, LuaVMContext); } catch (Exception) { Log.Info($"LuaVMEnv.Execute Error, transfer.hash: {transfer.hash} , contract: {transfer.addressOut} func:{luaVMCall.fnName}"); } }
public void OnContract(HttpMessage httpMessage) { httpMessage.result = "command error! \nexample: contract consAddress callFun"; GetParam(httpMessage, "1", "consAddress", out string consAddress); GetParam(httpMessage, "1", "depend", out string depend); if (!GetParam(httpMessage, "2", "callFun", out string callFun)) { return; } WalletKey key = Wallet.GetWallet().GetCurWallet(); var sender = key.ToAddress(); if (callFun.IndexOf("create(") != -1) { var consensus = Entity.Root.GetComponent <Consensus>(); var blockMgr = Entity.Root.GetComponent <BlockMgr>(); long notice = 1; using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0)) { var account = dbSnapshot.Accounts.Get(sender); if (account != null) { notice = account.nonce + 1; } } BlockSub transfer = new BlockSub(); transfer.addressIn = sender; transfer.addressOut = null; transfer.amount = "0"; transfer.nonce = notice; transfer.type = "contract"; transfer.depend = depend; transfer.data = callFun; var luaVMCall = LuaVMCall.Decode(transfer.data); Log.Info(JsonHelper.ToJson(luaVMCall)); //transfer.timestamp = TimeHelper.Now(); //transfer.hash = transfer.ToHash(); //transfer.sign = transfer.ToSign(key); //var rel = Entity.Root.GetComponent<Rule>().AddTransfer(transfer); //if (rel == -1) //{ // OnTransferAsync(transfer); //} //httpMessage.result = $"accepted transfer:{transfer.hash}"; } else { using (DbSnapshot dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot()) { var consensus = Entity.Root.GetComponent <Consensus>(); var luaVMEnv = Entity.Root.GetComponent <LuaVMEnv>(); var blockSub = new BlockSub(); blockSub.addressIn = sender; blockSub.addressOut = consAddress; blockSub.data = callFun; bool rel = luaVMEnv.Execute(dbSnapshot, blockSub, consensus.transferHeight, out object[] result); httpMessage.result = JsonHelper.ToJson(result); } } }
public Dictionary <string, RuleInfo> GetRules(string address, long height, DbSnapshot dbSnapshot) { lock (this) { Dictionary <string, RuleInfo> rules = new Dictionary <string, RuleInfo>(); try { LuaEnv luaenv = GetLuaEnv(address, "GetRules"); LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; var luaVMDB = new LuaVMDB(dbSnapshot); LuaVMStack.Reset(null, luaVMDB, null, null); LuaVMContext Storages = dbSnapshot?.Storages.Get(address); // rapidjson luaenv.DoString(initScript); luaVMScript = LuaVMScript.Get(dbSnapshot, address); LuaVMContext = dbSnapshot.Storages.Get(address); luaenv.DoString(luaVMScript.script, address); luaenv.DoString($"Storages = rapidjson.decode('{LuaVMContext.jsonData.ToStr()}')\n"); luaVMCall.fnName = "update"; luaVMCall.args = new FieldParam[0]; object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.Global.Set("curHeight", height); luaenv.Global.Set("sender", ""); luaenv.Global.Set("addressThis", address); luaFun.Call(args); // rapidjson luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); dbSnapshot.Storages.Add(address, LuaVMContext); JToken jdStorages = JToken.Parse(LuaVMContext.jsonData.ToStr()); JToken[] jdRule = jdStorages["Rules"].ToArray(); for (int ii = 0; ii < jdRule.Length; ii++) { RuleInfo rule = new RuleInfo(); rule.Address = jdRule[ii]["Address"].ToString(); rule.Contract = jdRule[ii]["Contract"]?.ToString(); rule.Amount = jdRule[ii]["Amount"]?.ToString(); rule.Start = long.Parse(jdRule[ii]["Start"].ToString()); rule.End = long.Parse(jdRule[ii]["End"].ToString()); rule.LBH = long.Parse(jdRule[ii]["LBH"].ToString()); rules.Remove(rule.Address); rules.Add(rule.Address, rule); } luaenv.GC(); } catch (Exception e) { Log.Debug(e.ToString()); Log.Info("GetRules Error!"); } finally { LuaVMStack.Reset(null, null, null, null); } return(rules); } }
public bool Execute(DbSnapshot dbSnapshot, BlockSub transfer, long height, out object[] result) { lock (this) { using (LuaVMDB luaVMDB = new LuaVMDB(dbSnapshot)) { result = null; LuaVMCall luaVMCall = new LuaVMCall(); LuaVMScript luaVMScript = null; LuaVMContext LuaVMContext = null; try { string consAddress = GetContractAddress(transfer); LuaEnv luaenv = GetLuaEnv(consAddress, "Execute"); //LuaEnv Global LuaVMStack.Reset(transfer, luaVMDB, consAddress, transfer.addressIn); luaenv.DoString(initScript); if (string.IsNullOrEmpty(transfer.addressOut)) { // 已存在 if (luaVMDB.Contracts.Get(consAddress) != null) { return(false); } luaVMScript = new LuaVMScript() { script = FileHelper.GetFileData($"./Data/Contract/{transfer.depend}.lua").ToByteArray(), tablName = transfer.depend }; LuaVMContext = new LuaVMContext() { jsonData = "{}".ToByteArray() }; luaVMCall = LuaVMCall.Decode(transfer.data); luaVMDB.Contracts.Add(consAddress, luaVMScript); luaenv.DoString(luaVMScript.script); } else { luaVMScript = LuaVMScript.Get(luaVMDB, consAddress); LuaVMContext = luaVMDB.Storages.Get(consAddress); luaVMCall = LuaVMCall.Decode(transfer.data); luaenv.DoString(luaVMScript.script, transfer.addressOut); luaenv.DoString($"Storages = rapidjson.decode('{LuaVMContext.jsonData.ToStr()}')\n"); } object[] args = luaVMCall.args.Select(a => a.GetValue()).ToArray(); LuaFunction luaFun = luaenv.Global.Get <LuaFunction>(luaVMCall.fnName); luaenv.Global.Set("curHeight", height); luaenv.Global.Set("sender", transfer.addressIn); luaenv.Global.Set("addressThis", consAddress); if (luaFun != null) { result = luaFun.Call(args); // rapidjson luaenv.DoString("StoragesJson = rapidjson.encode(Storages)\n"); LuaVMContext.jsonData = luaenv.Global.Get <string>("StoragesJson").ToByteArray(); luaVMDB.Storages.Add(consAddress, LuaVMContext); luaVMDB.Commit(); luaenv.GC(); return(true); } } catch (Exception e) { #if !RELEASE Log.Error(e); Log.Info($"LuaVMEnv.Execute Error, transfer.hash: {transfer.hash} , contract: {transfer.addressOut} func:{luaVMCall.fnName}"); #endif var array = e.Message.Split("\n"); if (array != null && array.Length > 0) { array[0] = array[0].Replace("c# exception:XLua.LuaException: c# exception:System.Exception: ", ""); LuaVMStack.Add2TransferTemp(array[0]); } } finally { LuaVMStack.Reset(null, null, null, null); } return(false); } } }