예제 #1
0
        public VirtualChain(CronAPI api, KeyPair owner, ChainTime time = null)
        {
            Reset();

            if (time == null)
            {
                time = new RealTime();
            }

            this.Time = time;

            var scripthash = new UInt160(owner.signatureHash.ToArray());

            var txs = new List <Transaction>();

            foreach (var entry in _assetMap)
            {
                var assetID = entry.Key;
                var tx      = new Transaction();
                tx.outputs = new Transaction.Output[] { new Transaction.Output()
                                                        {
                                                            assetID = assetID, scriptHash = scripthash, value = 1000000000
                                                        } };
                tx.inputs = new Transaction.Input[] { };
                txs.Add(tx);
            }
            GenerateBlock(txs);
        }
예제 #2
0
        public static uint FindBlock(CronAPI api, DateTime date)
        {
            uint min = 0;
            var  max = api.GetBlockHeight();

            var timestamp = date.ToTimestamp();

            return(FindBlock(api, timestamp, min, max));
        }
예제 #3
0
        public void SyncWithNode(CronAPI api)
        {
            var max = api.GetBlockHeight();

            var min = (uint)_blocks.Count;

            for (uint i = min; i <= max; i++)
            {
                var block = api.GetBlock(i);
                AddBlock(block);
            }
        }
예제 #4
0
파일: NEP5.cs 프로젝트: george-key/cron-lux
        public static Transaction MintTokens(NEP5 token, KeyPair buyer_key, string symbol, decimal amount)
        {
            var attachs = new List <Transaction.Output>();

            attachs.Add(new Transaction.Output()
            {
                assetID = CronAPI.GetAssetID(symbol), scriptHash = token.ScriptHash, value = amount
            });
            var response = token.api.CallContract(buyer_key, token.ScriptHash, "mintTokens", new object[] { }, symbol, attachs);

            return(response);
        }
예제 #5
0
        public Transaction ClaimGas(KeyPair ownerKey)
        {
            var targetScriptHash = new UInt160(ownerKey.address.AddressToScriptHash());

            decimal amount;
            var     claimable = GetClaimable(targetScriptHash, out amount);

            var references = new List <Transaction.Input>();

            foreach (var entry in claimable)
            {
                references.Add(new Transaction.Input()
                {
                    prevHash = entry.hash, prevIndex = entry.index
                });
            }

            if (amount <= 0)
            {
                throw new ArgumentException("No GAS to claim at this address");
            }

            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(ownerKey, "CRON", null, out inputs, out outputs);

            outputs.Add(
                new Transaction.Output()
            {
                scriptHash = targetScriptHash,
                assetID    = CronAPI.GetAssetID("CRON"),
                value      = amount
            });

            Transaction tx = new Transaction()
            {
                type            = TransactionType.ClaimTransaction,
                version         = 0,
                script          = null,
                gas             = -1,
                claimReferences = references.ToArray(),
                inputs          = inputs.ToArray(),
                outputs         = outputs.ToArray(),
            };

            tx.Sign(ownerKey);

            var ok = SendTransaction(tx);

            return(ok ? tx : null);
        }
예제 #6
0
        private void MergeTransaction(CronAPI api, Transaction tx)
        {
            transactions[tx.Hash] = tx;

            foreach (var input in tx.inputs)
            {
                if (!transactions.ContainsKey(input.prevHash))
                {
                    var other = api.GetTransaction(input.prevHash);
                    transactions[other.Hash] = other;
                    external_txs.Add(other.Hash);
                }
            }
        }
예제 #7
0
        protected override void Reset()
        {
            base.Reset();

            foreach (var entry in CronAPI.Assets)
            {
                var symbol  = entry.Key;
                var assetID = CronAPI.GetAssetID(symbol);
                _assetMap[assetID] = new Asset()
                {
                    hash = new UInt256(assetID), name = symbol
                };
            }
        }
예제 #8
0
파일: NEP5.cs 프로젝트: george-key/cron-lux
        // transfer to multiple addresses
        public Transaction Transfer(KeyPair from_key, Dictionary <byte[], decimal> transfers)
        {
            if (transfers.Count > max_transfer_count)
            {
                throw new ArgumentException("Max transfers per call = " + max_transfer_count);
            }

            var scripts = new List <byte[]>();

            var sender_address_hash = from_key.address.GetScriptHashFromAddress();

            int index = 0;

            foreach (var entry in transfers)
            {
                if (entry.Value <= 0)
                {
                    var addr = new UInt160(entry.Key).ToAddress();
                    throw new ArgumentException($"Invalid amount {entry.Value} for address {addr}");
                }

                BigInteger amount = ConvertToBigInt(entry.Value);

                var isLast = index == transfers.Count - 1;
                var args   = new object[] { sender_address_hash, entry.Key, amount };
                var bytes  = CronAPI.GenerateScript(ScriptHash, new object[] { "transfer", args }, isLast);

                scripts.Add(bytes);
                index++;
            }

            var final_size = scripts.Sum(x => x.Length);

            byte[] final_script = new byte[final_size];

            using (var stream = new MemoryStream(final_script))
            {
                foreach (byte[] bytes in scripts)
                {
                    stream.Write(bytes, 0, bytes.Length);
                }
            }

            var response = api.CallContract(from_key, ScriptHash, final_script);

            return(response);
        }
예제 #9
0
        private static uint FindBlock(CronAPI 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);
        }
예제 #10
0
        // claim from contract, without having private key
        public Transaction ClaimGas(KeyPair ownerKey, UInt160 fromScripthash, byte[] verificationScript)
        {
            var check = verificationScript.ToScriptHash();

            if (check != fromScripthash)
            {
                throw new ArgumentException("Invalid verification script");
            }

            decimal amount;
            var     claimable = GetClaimable(fromScripthash, out amount);

            var references = new List <Transaction.Input>();

            foreach (var entry in claimable)
            {
                references.Add(new Transaction.Input()
                {
                    prevHash = entry.hash, prevIndex = entry.index
                });
            }

            if (amount <= 0)
            {
                throw new ArgumentException("No GAS to claim at this address");
            }

            List <Transaction.Input>  inputs;
            List <Transaction.Output> outputs;

            GenerateInputsOutputs(ownerKey, "CRON", null, out inputs, out outputs);

            outputs.Add(
                new Transaction.Output()
            {
                scriptHash = fromScripthash,
                assetID    = CronAPI.GetAssetID("CRON"),
                value      = amount
            });

            Transaction tx = new Transaction()
            {
                type            = TransactionType.ClaimTransaction,
                version         = 0,
                script          = null,
                gas             = -1,
                claimReferences = references.ToArray(),
                inputs          = inputs.ToArray(),
                outputs         = outputs.ToArray(),
            };

            var witness = new Witness {
                invocationScript = ("0014" + ownerKey.address.AddressToScriptHash().ByteToHex()).HexToBytes(), verificationScript = verificationScript
            };

            tx.Sign(ownerKey, new Witness[] { witness });

            var ok = SendTransaction(tx);

            return(ok ? tx : null);
        }
예제 #11
0
 public BlockIterator(CronAPI api)
 {
     this.currentBlock       = api.GetBlockHeight();
     this.currentTransaction = 0;
 }
예제 #12
0
        public void Execute(CronAPI api, UInt160 script_hash, Action <ListenerVM> visitor)
        {
            var balances = new Dictionary <UInt160, decimal>();

            var vm = new ListenerVM(this);

            /*vm.AddScript(token_script);
             *
             * var debugger = new DebugClient();
             * debugger.SendScript(token_script);
             */
            throw new NotImplementedException();

            IEnumerable <Block> sorted_blocks = blocks.Values.OrderBy(x => x.Date);

            foreach (var block in sorted_blocks)
            {
                vm.SetCurrentBlock(block);

                bool executed = false;

                foreach (var tx in block.transactions)
                {
                    switch (tx.type)
                    {
                    case TransactionType.InvocationTransaction:
                    {
                        List <AVMInstruction> ops;
                        try
                        {
                            ops = CronTools.Disassemble(tx.script);
                        }
                        catch
                        {
                            continue;
                        }

                        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 otherScriptHash = new UInt160(op.data);

                                if (otherScriptHash != script_hash)
                                {
                                    continue;
                                }

                                var engine = new ExecutionEngine(tx, vm, vm);
                                engine.LoadScript(tx.script);

                                engine.Execute(
                                    x =>
                                    {
                                        //debugger.Step(x);
                                    }
                                    );

                                executed = true;
                            }
                        }

                        break;
                    }
                    }
                }

                if (executed)
                {
                    visitor(vm);
                }
            }
        }
예제 #13
0
파일: NEP5.cs 프로젝트: george-key/cron-lux
 public NEP5(CronAPI api, string contractHash) : this(api, CronAPI.GetScriptHashFromString(contractHash))
 {
 }
예제 #14
0
        public Snapshot(UInt160 scriptHash, CronAPI api, uint startBlock, uint endBlock = 0)
        {
            if (endBlock == 0)
            {
                endBlock = api.GetBlockHeight();
            }

            if (endBlock < startBlock)
            {
                throw new ArgumentException("End block cannot be smaller than start block");
            }

            for (uint height = startBlock; height <= endBlock; height++)
            {
                var block = api.GetBlock(height);

                var snapCount = 0;

                foreach (var tx in block.transactions)
                {
                    switch (tx.type)
                    {
                    case TransactionType.ContractTransaction:
                    {
                        foreach (var output in tx.outputs)
                        {
                            if (output.scriptHash == scriptHash)
                            {
                                MergeTransaction(api, tx);
                                snapCount++;
                                break;
                            }
                        }

                        break;
                    }

                    case TransactionType.InvocationTransaction:
                    {
                        List <AVMInstruction> ops;
                        try
                        {
                            ops = CronTools.Disassemble(tx.script);
                        }
                        catch
                        {
                            continue;
                        }

                        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 otherScriptHash = new UInt160(op.data);

                                if (otherScriptHash == scriptHash)
                                {
                                    MergeTransaction(api, tx);
                                    snapCount++;
                                    break;
                                }
                            }
                        }

                        break;
                    }
                    }
                }

                if (snapCount > 0)
                {
                    blocks[block.Hash] = block;
                }
            }
        }
예제 #15
0
파일: NEP5.cs 프로젝트: george-key/cron-lux
 public NEP5(CronAPI api, string contractHash, string name, BigInteger decimals)
     : this(api, contractHash)
 {
     this._decimals = decimals;
     this._name     = name;
 }
예제 #16
0
파일: NEP5.cs 프로젝트: george-key/cron-lux
 public NEP5(CronAPI api, UInt160 contractHash)
 {
     this.api        = api;
     this.ScriptHash = contractHash;
 }
예제 #17
0
파일: NEP5.cs 프로젝트: george-key/cron-lux
 public NEP5(CronAPI api, byte[] contractHash) : this(api, new UInt160(contractHash))
 {
 }