Example #1
0
        public void EndiannessHash256()
        {
            // A sequence of bytes, all different, each line fills an entire ulong
            var bytes = new byte[]
            {
                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
                0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
                0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
                0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
            };

            var hash = new Hash256(bytes);

            // Did the bytes move to the correct locations in the four ulongs ?
            Assert.Equal(0x1112131415161718UL, hash.Var1);
            Assert.Equal(0x2122232425262728UL, hash.Var2);
            Assert.Equal(0x3132333435363738UL, hash.Var3);
            Assert.Equal(0x4142434445464748UL, hash.Var4);

            // Does ToString() display the correct overall hash, in hex ?
            Assert.Equal(
                "1112131415161718 2122232425262728 3132333435363738 4142434445464748",
                hash.ToString());

            // Does writing out the hash back to a byte array restore the right order ?
            var write = new byte[Hash256.SizeInBytes];

            hash.WriteTo(write);

            Assert.Equal(bytes, write);
        }
Example #2
0
        private Transaction MakeTransaction(Dictionary <string, List <UTXO> > dic_UTXO, string fromAddress, string targetAddress, Hash256 asset, decimal sendCount)
        {
            //从字典取出utxo列表
            List <UTXO> uTXOs = dic_UTXO[asset.ToString()];

            Transaction transaction = new Transaction();

            decimal count = decimal.Zero;
            List <TransactionInput> transactionInputs = new List <TransactionInput>();

            for (int i = 0; i < uTXOs.Count; i++)
            {
                TransactionInput transactionInput = new TransactionInput();
                transactionInput.hash  = uTXOs[i].txid;
                transactionInput.index = (ushort)uTXOs[i].n;

                transactionInputs.Add(transactionInput);
                count += uTXOs[i].value;
                if (count >= sendCount)
                {
                    break;
                }
            }

            transaction.inputs = transactionInputs.ToArray();

            //输入大于等于输出
            if (count >= sendCount)
            {
                List <TransactionOutput> transactionOutputs = new List <TransactionOutput>();
                //输出
                if (sendCount > decimal.Zero)
                {
                    TransactionOutput transactionOutput = new TransactionOutput();
                    transactionOutput.assetId   = asset;
                    transactionOutput.value     = sendCount;
                    transactionOutput.toAddress = Helper.GetPublicKeyHashFromAddress(targetAddress);
                    transactionOutputs.Add(transactionOutput);
                }

                //找零
                decimal change = count - sendCount;
                if (change > decimal.Zero)
                {
                    TransactionOutput transactionOutput = new TransactionOutput();
                    transactionOutput.toAddress = Helper.GetPublicKeyHashFromAddress(fromAddress);
                    transactionOutput.value     = change;
                    transactionOutput.assetId   = asset;
                    transactionOutputs.Add(transactionOutput);
                }
                transaction.outputs = transactionOutputs.ToArray();
            }
            else
            {
                throw new Exception("余额不足!");
            }
            return(transaction);
        }
        async Task cancel()
        {
            subPrintLine("    Input full domain just like test.neo :");
            string fulldomain;

            string[] domains;
            try
            {
                fulldomain = Console.ReadLine();
                domains    = fulldomain.Split('.');
                if (domains.Length <= 1)
                {
                    subPrintLine("    Input incorret fulldomain");
                    return;
                }
            }
            catch (Exception e)
            {
                subPrintLine("    Input incorret fulldomain");
                return;
            }
            Hash256 rootHash = nns_tools.nameHash(domains[domains.Length - 1]);
            Hash256 fullHash = rootHash;

            for (var i = domains.Length - 2; i == 0; i--)
            {
                fullHash = nns_tools.nameHashSub(rootHash, domains[i]);
                if (i != 0)
                {
                    rootHash = fullHash;
                }
            }
            subPrintLine("calc=" + fullHash.ToString());
            //先查询这个域名的所有者是不是自己
            var info = await nns_tools.api_InvokeScript(Config.sc_nns, "getOwnerInfo", "(hex256)" + fullHash.ToString());

            var sh = info.value.subItem[0].subItem[0].AsHash160();

            if (sh == null)
            {
                subPrintLine(" Domain not exist ");
                return;
            }
            var owner = ThinNeo.Helper.GetAddressFromScriptHash(sh);

            subPrintLine("getinfo owner=" + owner);
            if (owner != ThinNeo.Helper.GetAddressFromScriptHash(Config.domainTransactionhash))
            {
                subPrintLine(" Domain is not dt ");
                return;
            }

            var result = await nns_tools.api_SendTransaction(prikey, Config.domainTransactionhash, "cancel", "(hex256)" + fullHash.ToString());

            subPrintLine("result=" + result);
        }
        async Task buy()
        {
            subPrintLine("    Input full domain just like test.neo :");
            string fulldomain;

            string[] domains;
            try
            {
                fulldomain = Console.ReadLine();
                domains    = fulldomain.Split('.');
                if (domains.Length <= 1)
                {
                    subPrintLine("    Input incorret fulldomain");
                    return;
                }
            }
            catch (Exception e)
            {
                subPrintLine("    Input incorret fulldomain");
                return;
            }
            Hash256 rootHash = nns_tools.nameHash(domains[domains.Length - 1]);
            Hash256 fullHash = rootHash;

            for (var i = domains.Length - 2; i == 0; i--)
            {
                fullHash = nns_tools.nameHashSub(rootHash, domains[i]);
                if (i != 0)
                {
                    rootHash = fullHash;
                }
            }
            subPrintLine("calc=" + fullHash.ToString());

            var info = await nns_tools.api_InvokeScript(Config.domainTransactionhash, "getDomainSellingInfo", "(hex256)" + fullHash.ToString());

            var price = info.value.subItem[0].subItem[2].AsInteger();

            var result = await nns_tools.api_SendTransaction(prikey, Config.domainTransactionhash, "buy", "(addr)" + address, "(hex256)" + fullHash.ToString());

            subPrintLine("result=" + result);
        }
Example #5
0
 public void ToStringAndTryParse()
 {
     {
         Hash256 hash1   = new Hash256(141251, 1510092, 9079235, 1234);
         string  hashStr = hash1.ToString();
         Assert.IsTrue(Hash256.TryParse(hashStr, out Hash256 hash2));
         Assert.AreEqual(hash1, hash2);
         Assert.AreEqual(hash1.GetHashCode(), hash2.GetHashCode());
         Assert.AreEqual(141251, hash1.GetHashCode());
     }
     {
         Hash256 hash1   = new Hash256(1, 2, 3, 4);
         string  hashStr = hash1.ToString();
         Assert.AreEqual("0000000000000001000000000000000200000000000000030000000000000004", hashStr);
         Assert.IsTrue(Hash256.TryParse(hashStr, out Hash256 hash2));
         Assert.AreEqual(hash1, hash2);
         Assert.AreEqual(hash1.GetHashCode(), hash2.GetHashCode());
         Assert.AreEqual(1, hash1.GetHashCode());
     }
 }
        async Task getDomainSellingInfo()
        {
            subPrintLine("    Input full domain just like test.neo :");
            string fulldomain;

            string[] domains;
            try
            {
                fulldomain = Console.ReadLine();
                domains    = fulldomain.Split('.');
                if (domains.Length <= 1)
                {
                    subPrintLine("    Input incorret fulldomain");
                    return;
                }
            }
            catch (Exception e)
            {
                subPrintLine("    Input incorret fulldomain");
                return;
            }
            Hash256 rootHash = nns_tools.nameHash(domains[domains.Length - 1]);
            Hash256 fullHash = rootHash;

            for (var i = domains.Length - 2; i == 0; i--)
            {
                fullHash = nns_tools.nameHashSub(rootHash, domains[i]);
                if (i != 0)
                {
                    rootHash = fullHash;
                }
            }
            subPrintLine("calc=" + fullHash.ToString());
            //先查询这个域名的所有者是不是自己
            var info = await nns_tools.api_InvokeScript(Config.domainTransactionhash, "getDomainSellingInfo", "(hex256)" + fullHash.ToString());

            subPrintLine("getDomainSellingInfo hash=" + info.value.subItem[0].subItem[0].AsHash256());
            subPrintLine("getDomainSellingInfo owner=" + ThinNeo.Helper.GetAddressFromScriptHash(info.value.subItem[0].subItem[1].AsHash160()));
            subPrintLine("getDomainSellingInfo price=" + info.value.subItem[0].subItem[2].AsInteger());
        }
Example #7
0
        public void TestDefault()
        {
            var hash = new Hash256();

            Assert.Equal("0000000000000000000000000000000000000000000000000000000000000000", hash.ToString());
        }
Example #8
0
        public void TestRoundTrip(string hex)
        {
            var hash = new Hash256(hex);

            Assert.Equal(hex, hash.ToString());
        }
Example #9
0
        async Task test_refund()
        {
            decimal amount = 0;

            while (true)
            {
                subPrintLine("Input amount:");
                string str_amount = Console.ReadLine();
                try
                {
                    amount = decimal.Parse(str_amount);
                    break;
                }
                catch (Exception e)
                {
                    subPrintLine("input number");
                }
            }

            string sgas_address = ThinNeo.Helper.GetAddressFromScriptHash(Config.dapp_sgas);

            //获取sgas合约地址的资产列表
            Dictionary <string, List <Utxo> > dir = await Helper.GetBalanceByAddress(Config.api, sgas_address);

            if (dir.ContainsKey(Config.id_GAS) == false)
            {
                subPrintLine("no gas");
                return;
            }
            List <Utxo> newlist = new List <Utxo>(dir[Config.id_GAS]);

            //检查sgas地址拥有的gas的utxo是否有被标记过
            for (var i = newlist.Count - 1; i >= 0; i--)
            {
                byte[] script = null;
                using (var sb = new ThinNeo.ScriptBuilder())
                {
                    var array = new MyJson.JsonNode_Array();
                    array.AddArrayValue("(hex256)" + newlist[i].txid.ToString());
                    sb.EmitParamJson(array);                                                   //参数倒序入
                    sb.EmitParamJson(new MyJson.JsonNode_ValueString("(str)getRefundTarget")); //参数倒序入
                    var shash = Config.dapp_sgas;
                    sb.EmitAppCall(shash);                                                     //nep5脚本
                    script = sb.ToArray();
                }
                if (newlist[i].n > 0)
                {
                    continue;
                }

                var    urlCheckUTXO    = Helper.MakeRpcUrl(Config.api, "invokescript", new MyJson.JsonNode_ValueString(ThinNeo.Helper.Bytes2HexString(script)));
                string resultCheckUTXO = await Helper.HttpGet(urlCheckUTXO);

                var jsonCU = MyJson.Parse(resultCheckUTXO);
                var stack  = jsonCU.AsDict()["result"].AsList()[0].AsDict()["stack"].AsList()[0].AsDict();
                var value  = stack["value"].AsString();
                if (value.Length > 0)//已经标记的UTXO,不能使用
                {
                    newlist.RemoveAt(i);
                }
            }


            //添加系统费
            Dictionary <string, List <Utxo> > dir2 = await Helper.GetBalanceByAddress(Config.api, address);

            List <Utxo> newlist2 = new List <Utxo>(dir2[Config.id_GAS]);

            ThinNeo.Transaction tran = null;
            {
                byte[] script = null;
                using (var sb = new ThinNeo.ScriptBuilder())
                {
                    var array = new MyJson.JsonNode_Array();
                    array.AddArrayValue("(bytes)" + ThinNeo.Helper.Bytes2HexString(scriptHash));
                    sb.EmitParamJson(array);                                          //参数倒序入
                    sb.EmitParamJson(new MyJson.JsonNode_ValueString("(str)refund")); //参数倒序入
                    var shash = Config.dapp_sgas;
                    sb.EmitAppCall(shash);                                            //nep5脚本
                    script = sb.ToArray();
                }

                //sgas 自己给自己转账   用来生成一个utxo  合约会把这个utxo标记给发起的地址使用
                tran      = Helper.makeTran(newlist, sgas_address, new ThinNeo.Hash256(Config.id_GAS), (decimal)0.00000001, (decimal)0.00000001, newlist2, address);
                tran.type = ThinNeo.TransactionType.InvocationTransaction;
                var idata = new ThinNeo.InvokeTransData();
                tran.extdata = idata;
                idata.script = script;

                //附加鉴证
                tran.attributes          = new ThinNeo.Attribute[1];
                tran.attributes[0]       = new ThinNeo.Attribute();
                tran.attributes[0].usage = ThinNeo.TransactionAttributeUsage.Script;
                tran.attributes[0].data  = scriptHash;
            }

            //sign and broadcast
            {//做智能合约的签名
                byte[] sgasScript = null;
                {
                    var urlgetscript    = Helper.MakeRpcUrl(Config.api, "getcontractstate", new MyJson.JsonNode_ValueString(Config.dapp_sgas.ToString()));
                    var resultgetscript = await Helper.HttpGet(urlgetscript);

                    var _json    = MyJson.Parse(resultgetscript).AsDict();
                    var _resultv = _json["result"].AsList()[0].AsDict();
                    sgasScript = ThinNeo.Helper.HexString2Bytes(_resultv["script"].AsString());
                }
                byte[] iscript = null;
                using (var sb = new ThinNeo.ScriptBuilder())
                {
                    sb.EmitPushString("whatever");
                    sb.EmitPushNumber(250);
                    iscript = sb.ToArray();
                }
                tran.AddWitnessScript(sgasScript, iscript);
            }
            {//做提款人的签名
                var signdata = ThinNeo.Helper.Sign(tran.GetMessage(), prikey);
                tran.AddWitness(signdata, pubkey, address);
            }
            var trandata    = tran.GetRawData();
            var strtrandata = ThinNeo.Helper.Bytes2HexString(trandata);

            byte[] postdata;
            var    url = Helper.MakeRpcUrlPost(Config.api, "sendrawtransaction", out postdata, new MyJson.JsonNode_ValueString(strtrandata));

            var result = await Helper.HttpPost(url, postdata);

            subPrintLine("得到的结果是:" + result);
            var json = MyJson.Parse(result).AsDict();

            if (json.ContainsKey("result"))
            {
                bool bSucc = false;
                if (json["result"].type == MyJson.jsontype.Value_Number)
                {
                    bSucc = json["result"].AsBool();
                    subPrintLine("cli=" + json["result"].ToString());
                }
                else
                {
                    var resultv = json["result"].AsList()[0].AsDict();
                    var txid    = resultv["txid"].AsString();
                    bSucc = txid.Length > 0;
                }
                if (bSucc)
                {
                    Hash256 txid = tran.GetHash();
                    url = Helper.MakeRpcUrlPost(Config.api, "getrawtransaction", out postdata, new MyJson.JsonNode_ValueString(txid.ToString()));
                    while (true)
                    {
                        subPrintLine("正在等待交易验证,请稍后。。。。");
                        result = await Helper.HttpPost(url, postdata);

                        json = MyJson.Parse(result).AsDict();
                        if (json.ContainsKey("result"))
                        {
                            //tx的第一个utxo就是给自己的
                            Utxo utxo = new Utxo(address, txid, Config.id_GAS, amount, 0);
                            //把这个txid里的utxo[0]的value转给自己
                            TranGas(new List <Utxo>()
                            {
                                utxo
                            }, amount);
                            break;
                        }
                        await Task.Delay(5000);
                    }
                }
                else
                {
                }
            }
        }
Example #10
0
        Transaction MakeTransaction(Dictionary <string, List <UTXO> > dir_utxos, string targetaddr, Hash256 assetid, decimal sendcount)
        {
            if (!dir_utxos.ContainsKey(assetid.ToString()))
            {
                throw new Exception("no enough money.");
            }

            List <UTXO> utxos = dir_utxos[assetid.ToString()];
            var         tran  = new Transaction();

            tran.type    = TransactionType.ContractTransaction;
            tran.version = 0;//0 or 1
            tran.extdata = null;

            tran.attributes = new ThinNeo.Attribute[0];
            var scraddr = "";

            utxos.Sort((a, b) => {
                if (a.value > b.value)
                {
                    return(1);
                }
                else if (a.value < b.value)
                {
                    return(-1);
                }
                else
                {
                    return(0);
                }
            });
            decimal count = decimal.Zero;
            List <TransactionInput> list_inputs = new List <TransactionInput>();

            for (var i = 0; i < utxos.Count; i++)
            {
                TransactionInput input = new TransactionInput();
                input.hash  = utxos[i].txid;
                input.index = (ushort)utxos[i].n;
                list_inputs.Add(input);
                count  += utxos[i].value;
                scraddr = utxos[i].address;
                if (count >= sendcount)
                {
                    break;
                }
            }
            tran.inputs = list_inputs.ToArray();
            if (count >= sendcount)//输入大于等于输出
            {
                List <TransactionOutput> list_outputs = new List <TransactionOutput>();
                //输出
                if (sendcount > decimal.Zero && targetaddr != null)
                {
                    TransactionOutput output = new TransactionOutput();
                    output.assetId   = assetid;
                    output.value     = sendcount;
                    output.toAddress = Helper.GetPublicKeyHashFromAddress(targetaddr);
                    list_outputs.Add(output);
                }

                //找零
                var change = count - sendcount;
                if (change > decimal.Zero)
                {
                    TransactionOutput outputchange = new TransactionOutput();
                    outputchange.toAddress = Helper.GetPublicKeyHashFromAddress(scraddr);
                    outputchange.value     = change;
                    outputchange.assetId   = assetid;
                    list_outputs.Add(outputchange);
                }
                tran.outputs = list_outputs.ToArray();
            }
            else
            {
                throw new Exception("no enough money.");
            }
            return(tran);
        }
Example #11
0
 public void GetContentsHash()
 {
     {
         System.IO.Stream stream1 = this.getRandomStream(54611);
         System.IO.Stream stream2 = this.getRandomStream(54611);
         Hash256          hash1   = Hash256.GetContentsHash(stream1);
         Hash256          hash2   = Hash256.GetContentsHash(stream2);
         Assert.AreEqual(hash1, hash2);
         Assert.AreEqual(hash1.GetHashCode(), hash2.GetHashCode());
     }
     {
         System.IO.Stream stream1 = this.getRandomStream(54600);
         System.IO.Stream stream2 = this.getRandomStream(54611);
         Hash256          hash1   = Hash256.GetContentsHash(stream1);
         Hash256          hash2   = Hash256.GetContentsHash(stream2);
         Assert.AreNotEqual(hash1, hash2);
         Assert.AreNotEqual(hash1.GetHashCode(), hash2.GetHashCode());
     }
     {
         Random         random1a   = new Random(123151);
         Random         random1b   = new Random(123151);
         Random         random1c   = new Random(123151);
         Random         random2    = new Random(9876);
         MockFileSystem fileSystem = new MockFileSystem(new Dictionary <string, MockFileData>()
         {
             { "getfilehashtest1a.file", new MockFileData(Enumerable.Range(0, 10240).Select((i) => (byte)random1a.Next(256)).ToArray()) },
             { "getfilehashtest1b.file", new MockFileData(Enumerable.Range(0, 10240).Select((i) => (byte)random1b.Next(256)).ToArray()) },
             { "getfilehashtest1c.file", new MockFileData(Enumerable.Range(0, 10241).Select((i) => (byte)random1c.Next(256)).ToArray()) },
             { "getfilehashtest2.file", new MockFileData(Enumerable.Range(0, 10240).Select((i) => (byte)random2.Next(256)).ToArray()) },
         });
         Hash256 hash1a = Hash256.GetContentsHash(fileSystem.File.OpenRead("getfilehashtest1a.file"));
         Hash256 hash1b = Hash256.GetContentsHash(fileSystem.File.OpenRead("getfilehashtest1b.file"));
         Hash256 hash1c = Hash256.GetContentsHash(fileSystem.File.OpenRead("getfilehashtest1c.file"));
         Hash256 hash2  = Hash256.GetContentsHash(fileSystem.File.OpenRead("getfilehashtest2.file"));
         Assert.AreEqual(hash1a, hash1b);
         Assert.AreNotEqual(hash1a, hash1c);
         Assert.AreNotEqual(hash1a, hash2);
         Assert.AreNotEqual(hash1c, hash2);
         Assert.AreEqual(new Hash256(-4503150692253193366, -4589931198477819425, -7393329944829092212, 1525878695725488611), hash1a);
         Assert.AreEqual("c181984dda31ab6ac04d49e4bb3f21df99659d9633341e8c152d0296dd0dd9e3", hash1a.ToString());
         Assert.AreEqual(new Hash256(-4503150692253193366, -4589931198477819425, -7393329944829092212, 1525878695725488611), hash1b);
         Assert.AreEqual("c181984dda31ab6ac04d49e4bb3f21df99659d9633341e8c152d0296dd0dd9e3", hash1b.ToString());
         Assert.AreEqual(new Hash256(4050519298861383970, -7596970268443003904, -6680004443397598450, -8393995096044701854), hash1c);
         Assert.AreEqual("383655d77c7f4122969223ca94403400a34bdb59d541530e8b8289eef5e27762", hash1c.ToString());
         Assert.AreEqual(new Hash256(8844761264859441472, 3207933974862152339, 7733136889014184772, 1800345724947963099), hash2);
         Assert.AreEqual("7abee7824314e9402c84def42a90c2936b519f075528eb4418fc1ce5f06a9cdb", hash2.ToString());
     }
 }
Example #12
0
        public static Transaction MakeTran(Dictionary <string, List <Utxo> > dic_UTXO, string targetAddr, Hash256 assetid, decimal sendCount)
        {
            if (!dic_UTXO.ContainsKey(assetid.ToString()))
            {
                throw new Exception("No Money!");
            }
            List <Utxo> utxos = dic_UTXO[assetid.ToString()];
            var         tran  = new ThinNeo.Transaction();

            tran.type       = ThinNeo.TransactionType.ContractTransaction;
            tran.version    = 0;
            tran.extdata    = null;
            tran.attributes = new ThinNeo.Attribute[0];
            var scraddr = "";

            utxos.Sort((a, b) =>
            {
                if (a.value > b.value)
                {
                    return(1);
                }
                else if (a.value < b.value)
                {
                    return(-1);
                }
                else
                {
                    return(0);
                }
            });

            decimal count = decimal.Zero;
            List <ThinNeo.TransactionInput> list_inputs = new List <TransactionInput>();

            for (int i = 0; i < utxos.Count; i++)
            {
                ThinNeo.TransactionInput input = new TransactionInput();
                input.hash  = utxos[i].txid;
                input.index = (ushort)utxos[i].n;
                list_inputs.Add(input);
                count  += utxos[i].value;
                scraddr = utxos[i].addr;
                if (count >= sendCount)
                {
                    break;
                }
            }
            tran.inputs = list_inputs.ToArray();
            if (count >= sendCount)
            {
                List <ThinNeo.TransactionOutput> list_outputs = new List <TransactionOutput>();
                if (sendCount > decimal.Zero && targetAddr != null)
                {
                    ThinNeo.TransactionOutput output = new TransactionOutput();
                    output.assetId   = assetid;
                    output.value     = sendCount;
                    output.toAddress = ThinNeo.Helper_NEO.GetScriptHash_FromAddress(targetAddr);
                    list_outputs.Add(output);
                }

                var change = count - sendCount;
                if (change > decimal.Zero)
                {
                    ThinNeo.TransactionOutput outputchange = new TransactionOutput();
                    outputchange.assetId   = assetid;
                    outputchange.toAddress = ThinNeo.Helper_NEO.GetScriptHash_FromAddress(scraddr);
                    outputchange.value     = change;
                    list_outputs.Add(outputchange);
                }

                tran.outputs = list_outputs.ToArray();
            }
            else
            {
                throw new Exception("no enough money!");
            }

            return(tran);
        }
Example #13
0
        private static Transaction MakeTran(Dictionary <string, List <UTXO> > dic_UTXO, string address, string targetAddr, Hash256 assetid, decimal sendCount)
        {
            if (!dic_UTXO.ContainsKey(assetid.ToString()))
            {
                throw new Exception("no money!");
            }

            List <UTXO> utxos = dic_UTXO[assetid.ToString()];
            Transaction tran  = new Transaction();

            utxos.Sort((a, b) =>
            {
                if (a.value > b.value)
                {
                    return(1);
                }
                else if (a.value < b.value)
                {
                    return(-1);
                }
                else
                {
                    return(0);
                }
            });

            decimal count = decimal.Zero;
            List <TransactionInput> list_inputs = new List <TransactionInput>();

            for (var i = 0; i < utxos.Count; i++)
            {
                TransactionInput input = new TransactionInput();
                input.hash  = utxos[i].txid;
                input.index = (ushort)utxos[i].n;
                list_inputs.Add(input);
                count += utxos[i].value;
                if (count >= sendCount)
                {
                    break;
                }
            }

            tran.inputs = list_inputs.ToArray();

            if (count >= sendCount)
            {
                List <TransactionOutput> list_outputs = new List <TransactionOutput>();
                if (sendCount > decimal.Zero)
                {
                    TransactionOutput output = new TransactionOutput();
                    output.assetId   = assetid;
                    output.value     = sendCount;
                    output.toAddress = ThinNeo.Helper.GetPublicKeyHashFromAddress(targetAddr);
                    list_outputs.Add(output);
                }

                var change = count - sendCount;
                if (change > decimal.Zero)
                {
                    TransactionOutput outputchange = new TransactionOutput();
                    outputchange.toAddress = ThinNeo.Helper.GetPublicKeyHashFromAddress(address);
                    outputchange.value     = change;
                    outputchange.assetId   = assetid;
                    list_outputs.Add(outputchange);
                }

                tran.outputs = list_outputs.ToArray();
            }
            else
            {
                throw new Exception("No money!");
            }

            return(tran);
        }