private bool ProcessIncomingBlock(uint height) { //Console.WriteLine($"Processing block {height}..."); var block = _api.GetBlock(height); if (block == null) { Console.WriteLine($"WARNING: could not fetch block #{height}"); return(false); } foreach (var tx in block.transactions) { Console.WriteLine($"{height} Processing tx {tx.Hash}..."); //if (tx.type != TransactionType.InvocationTransaction) //{ // continue; //} List <AVMInstruction> ops; try { ops = NeoTools.Disassemble(tx.script); Console.WriteLine($"{height} Processing tx {tx.Hash} has {tx.script.Length} byte codes"); } catch { continue; } //ProcessNotifications(height, tx); for (int i = 0; i < ops.Count; i++) { var op = ops[i]; if (op.opcode == OpCode.APPCALL && op.data != null && op.data.Length == 20) { var scriptHash = new UInt160(op.data); var engine = new ExecutionEngine(tx, _listenerVM, _listenerVM); engine.LoadScript(tx.script); engine.Execute(null /*x => * { * debugger.Step(x); * }*/ ); ProcessNotifications(height, tx); } } } //Console.WriteLine($"Processing block {height} success"); return(true); }
private void ProcessIncomingBlock(uint height) { var block = neo_api.GetBlock(height); if (block == null) { throw new Exception($"API failure, could not fetch block #{height}"); } foreach (var tx in block.transactions) { if (tx.type != TransactionType.InvocationTransaction) { continue; } List <AVMInstruction> ops; try { ops = NeoTools.Disassemble(tx.script); } catch { continue; } for (int i = 0; i < ops.Count; i++) { var op = ops[i]; // opcode data must contain the script hash to the Bluzelle contract, otherwise ignore it if (op.opcode == OpCode.APPCALL && op.data != null && op.data.Length == 20) { var scriptHash = new UInt160(op.data); if (scriptHash != bluzelle_contract_hash) { continue; } var engine = new ExecutionEngine(tx, listenerVM, listenerVM); engine.LoadScript(tx.script); engine.Execute(null /*x => * { * debugger.Step(x); * }*/ ); ProcessNotifications(tx); } } } }
private static uint FindBlock(NeoAPI api, uint timestamp, uint min, uint max) { var mid = (1 + max - min) / 2; do { var block = api.GetBlock(mid); var blockTime = block.Date.ToTimestamp(); if (blockTime == timestamp) { return(block.Height); } else if (blockTime < timestamp) { var next = api.GetBlock(mid + 1); var nextTime = next.Date.ToTimestamp(); if (nextTime == timestamp) { return(next.Height); } else if (nextTime > timestamp) { return(block.Height); } else { return(FindBlock(api, timestamp, mid + 1, max)); } } else { return(FindBlock(api, timestamp, min, mid - 1)); } } while (true); }
private void ProcessIncomingBlock(uint height) { var block = neo_api.GetBlock(height); if (block == null) { return; } Console.WriteLine($"Processing block {height}"); foreach (var tx in block.transactions) { if (tx.type != TransactionType.InvocationTransaction) { continue; } List <AVMInstruction> ops; try { ops = NeoTools.Disassemble(tx.script); } catch { continue; } for (int i = 0; i < ops.Count; i++) { var op = ops[i]; // opcode data must contain the script hash to the Bluzelle contract, otherwise ignore it if (op.opcode == OpCode.APPCALL && op.data != null && op.data.Length == 20) { var scriptHash = new UInt160(op.data); if (scriptHash != bluzelle_contract_hash) { continue; } Console.WriteLine($"Found Bluzelle call in tx {tx.Hash}"); var operation = Encoding.ASCII.GetString(ops[i - 1].data); int index = i - 3; var argCount = 1 + ((byte)ops[index].opcode - (byte)OpCode.PUSH1); var args = new List <object>(); while (argCount > 0) { index--; if (ops[index].opcode >= OpCode.PUSHBYTES1 && ops[index].opcode <= OpCode.PUSHBYTES75) { args.Add(ops[index].data); } else if (ops[index].opcode >= OpCode.PUSH1 && ops[index].opcode <= OpCode.PUSH16) { var n = new BigInteger(1 + (ops[index].opcode - OpCode.PUSH1)); args.Add(n); } else if (ops[index].opcode == OpCode.PUSH0) { args.Add(new BigInteger(0)); } else if (ops[index].opcode == OpCode.PUSHM1) { args.Add(new BigInteger(-1)); } else { throw new Exception("Invalid arg type"); } argCount--; } switch (operation) { case "create": { try { var uuid = Encoding.ASCII.GetString((byte[])args[1]); var key = Encoding.ASCII.GetString((byte[])args[2]); var value = Encoding.ASCII.GetString((byte[])args[3]); Console.WriteLine($"CREATE ({uuid},{key},{value})"); this.swarm.Create(uuid, key, value); } catch { Console.WriteLine($"Failed decoding args for tx {tx.Hash}"); } break; } case "delete": { try { var uuid = Encoding.ASCII.GetString((byte[])args[1]); var key = Encoding.ASCII.GetString((byte[])args[2]); Console.WriteLine($"DELETE ({uuid},{key})"); this.swarm.Delete(uuid, key); } catch { Console.WriteLine($"Failed decoding args for tx {tx.Hash}"); } break; } case "update": { try { var uuid = Encoding.ASCII.GetString((byte[])args[1]); var key = Encoding.ASCII.GetString((byte[])args[2]); var value = Encoding.ASCII.GetString((byte[])args[3]); Console.WriteLine($"UPDATE ({uuid},{key},{value})"); this.swarm.Update(uuid, key, value); } catch { Console.WriteLine($"Failed decoding args for tx {tx.Hash}"); } break; } case "read": { try { var uuid = Encoding.ASCII.GetString((byte[])args[1]); var key = Encoding.ASCII.GetString((byte[])args[2]); Console.WriteLine($"READ ({uuid},{key})"); var val = this.swarm.Read(uuid, key); /* * string id = null; * var push_tx = neo_api.CallContract(owner_keys, bluzelle_contract_hash, "push", new object[] {id, val }); * neo_api.WaitForTransaction(owner_keys, push_tx);*/ } catch { // Console.WriteLine($"Failed decoding args for tx {tx.Hash}"); } break; } } break; } } } }
private void ProcessIncomingBlock(uint height) { logger.Info("Processing block #" + height); var block = neo_api.GetBlock(height); if (block == null) { throw new Exception($"API failure, could not fetch block #{height}"); } foreach (var tx in block.transactions) { if (tx.type != TransactionType.InvocationTransaction) { continue; } List <AVMInstruction> code; try { code = NeoTools.Disassemble(tx.script); } catch { continue; } for (int i = 1; i < code.Count; i++) { var op = code[i]; // opcode data must contain the script hash to the Phantasma contract, otherwise ignore it if (op.opcode == OpCode.APPCALL && op.data != null && op.data.Length == 20) { var scriptHash = new UInt160(op.data); if (scriptHash != contract_hash) { continue; } var prev = code[i - 1]; if (prev.data == null) { continue; } var method = Encoding.ASCII.GetString(prev.data); int index = i - 3; var argCount = 1 + ((byte)code[index].opcode - (byte)OpCode.PUSH1); var args = new List <byte[]>(); while (argCount > 0) { index--; args.Add(code[index].data); argCount--; } switch (method) { case "registerMailbox": { var address = new UInt160(args[0]); var name = Encoding.ASCII.GetString(args[1]); string result; if (addressMap.ContainsKey(address)) { result = "Address already has a box"; } else if (nameMap.ContainsKey(name)) { result = "Box name already exists"; } else if (!Mailbox.ValidateMailboxName(args[1])) { result = "Box name is invalid"; } else { var mailbox = new Mailbox(name, address); nameMap[name] = mailbox; addressMap[address] = mailbox; result = "OK"; } logger.Info($"{method} ({address.ToAddress()}, {name}) => {result}"); break; } } } } } }
private bool ProcessIncomingBlock(uint height) { //Console.WriteLine($"Processing block {height}..."); var block = _api.GetBlock(height); if (block == null) { Console.WriteLine($"WARNING: could not fetch block #{height}"); return(false); } foreach (var tx in block.transactions) { //Console.WriteLine($"{height} Processing tx {tx.Hash}..."); //if (tx.type != TransactionType.InvocationTransaction) //{ // continue; //} List <AVMInstruction> txScript; try { txScript = NeoTools.Disassemble(tx.script); Console.WriteLine($"{height} Processing tx {tx.Hash} has {txScript.Count} instructions ({tx.script.Length} bytes. hash {tx.script.ToScriptHash()})"); } catch { continue; } var engine = new ExecutionEngine(tx, _listenerVM, _listenerVM); engine.LoadScript(tx.script); for (int i = 0; i < txScript.Count; i++) { AVMInstruction instruction = txScript[i]; Console.WriteLine($"Opcode {i}\t{instruction.opcode} ({(int)instruction.opcode}, {Helpers.ToHex(new byte[] { (byte)instruction.opcode })})\t{Helpers.ToHex(instruction.data)}\t{(instruction.data == null ? "(null)" : Encoding.ASCII.GetString(instruction.data))}"); if (instruction.opcode == OpCode.APPCALL && instruction.data != null && instruction.data.Length == 20) { var scriptHash = new UInt160(instruction.data); string scriptHashString = scriptHash.ToString(); Console.WriteLine($"scriptHashString: {scriptHashString}"); if (scriptHash != _contractScriptHash) { Console.WriteLine($"scriptHashString: {scriptHashString} != _contractScriptHash: {_contractScriptHash}: skipping"); continue; } var prevInstruction = txScript[i - 1]; if (prevInstruction.data == null) { Console.WriteLine($"scriptHashString: {scriptHashString}: no method - skipping"); continue; } _listenerVM.AddScript(_contractBytecode); var method = Encoding.ASCII.GetString(prevInstruction.data); int index = i - 3; int argCount = (byte)txScript[index].opcode - 0x50; // (byte)OpCode.PUSH0; var args = new List <byte[]>(); Console.WriteLine($"method: {method}: argCount {argCount}"); while (argCount > 0) { index--; if (txScript[index].data != null) { args.Add(txScript[index].data); Console.WriteLine($"arg: index {index} value {txScript[index].data.ToHexString()}"); } else if ((byte)txScript[index].opcode >= (byte)OpCode.PUSH1 && (byte)txScript[index].opcode <= (byte)OpCode.PUSH16) { int value = (byte)txScript[index].opcode - 0x50; Console.WriteLine($"arg: index {index} value {value}"); } argCount--; } engine.Execute(null /*x => * { * debugger.Step(x); * }*/ ); ProcessNotifications(height, tx); } } } //Console.WriteLine($"Processing block {height} success"); return(true); }