Beispiel #1
0
 public Utxo(string _addr, ThinNeo.Hash256 _txid, string _asset, decimal _value, int _n)
 {
     this.addr  = _addr;
     this.txid  = _txid;
     this.asset = _asset;
     this.value = _value;
     this.n     = _n;
 }
Beispiel #2
0
        public static ThinNeo.Transaction makeTran(List <Utxo> utxos, string targetaddr, ThinNeo.Hash256 assetid, decimal sendcount)
        {
            var tran = new ThinNeo.Transaction();

            tran.type    = ThinNeo.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 <ThinNeo.TransactionInput> list_inputs = new List <ThinNeo.TransactionInput>();

            for (var i = 0; i < utxos.Count; i++)
            {
                ThinNeo.TransactionInput input = new ThinNeo.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 <ThinNeo.TransactionOutput>();
                //输出
                if (sendcount > decimal.Zero && targetaddr != null)
                {
                    ThinNeo.TransactionOutput output = new ThinNeo.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)
                {
                    ThinNeo.TransactionOutput outputchange = new ThinNeo.TransactionOutput();
                    outputchange.toAddress = ThinNeo.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);
        }
Beispiel #3
0
        async public Task Demo()
        {
            byte[] prikey     = ThinNeo.Helper.GetPrivateKeyFromWIF(Nep55_1.testwif);
            byte[] pubkey     = ThinNeo.Helper.GetPublicKeyFromPrivateKey(prikey);
            string address    = ThinNeo.Helper.GetAddressFromPublicKey(pubkey);
            var    scripthash = ThinNeo.Helper.GetPublicKeyHashFromAddress(address);

            var    nep55_shash   = new ThinNeo.Hash160(Nep55_1.nep55);
            string nep55_address = ThinNeo.Helper.GetAddressFromScriptHash(nep55_shash);


            Console.WriteLine("address=" + address);

            //获取地址的资产列表
            Dictionary <string, List <Utxo> > dir = await Helper.GetBalanceByAddress(Nep55_1.api, nep55_address);

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

            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 = new ThinNeo.Hash160(Nep55_1.nep55);
                    sb.EmitAppCall(shash);                                                     //nep5脚本
                    script = sb.ToArray();
                }
                if (newlist[i].n > 0)
                {
                    continue;
                }

                var    urlCheckUTXO    = Helper.MakeRpcUrl(Nep55_1.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);
                }
            }


            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 = new ThinNeo.Hash160(Nep55_1.nep55);
                    sb.EmitAppCall(shash);                                            //nep5脚本
                    script = sb.ToArray();
                }
                Console.WriteLine("contract address=" + nep55_address);//往合约地址转账

                //生成交易
                tran      = Helper.makeTran(newlist, nep55_address, new ThinNeo.Hash256(Nep55_1.id_GAS), (decimal)2.1);
                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[] n55contract = null;
                {
                    var urlgetscript    = Helper.MakeRpcUrl(Nep55_1.api, "getcontractstate", new MyJson.JsonNode_ValueString(Nep55_1.nep55));
                    var resultgetscript = await Helper.HttpGet(urlgetscript);

                    var _json    = MyJson.Parse(resultgetscript).AsDict();
                    var _resultv = _json["result"].AsList()[0].AsDict();
                    n55contract = 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(n55contract, iscript);
            }
            {//做提款人的签名
                var signdata = ThinNeo.Helper.Sign(tran.GetMessage(), prikey);
                tran.AddWitness(signdata, pubkey, address);
            }
            var trandata    = tran.GetRawData();
            var strtrandata = ThinNeo.Helper.Bytes2HexString(trandata);

            ThinNeo.Transaction testde = new ThinNeo.Transaction();
            testde.Deserialize(new System.IO.MemoryStream(trandata));

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


            //bug
            //sendraw api 有bug,所以先加这个
            //url = "http://localhost:20332";

            string poststr = System.Text.Encoding.UTF8.GetString(postdata);

            Console.WriteLine("-----post info begin----");
            Console.WriteLine(poststr);
            Console.WriteLine("-----post info end----");
            var result = await Helper.HttpPost(url, postdata);

            Console.WriteLine("得到的结果是:" + 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();
                    Console.WriteLine("cli=" + json["result"].ToString());
                }
                else
                {
                    var resultv = json["result"].AsList()[0].AsDict();
                    var txid    = resultv["txid"].AsString();
                    bSucc = txid.Length > 0;
                    Console.WriteLine("txid=" + txid);
                }
                if (bSucc)
                {
                    lasttxid             = tran.GetHash();
                    Nep55_1.lastNep5Tran = tran.GetHash();
                    Console.WriteLine("你可以从这个UTXO拿走GAS了 txid=" + lasttxid.ToString() + "[0]");
                }
                else
                {
                    lasttxid = null;
                }
            }
        }
Beispiel #4
0
        //拼交易体
        ThinNeo.Transaction makeTran(Dictionary <string, List <Utxo> > dir_utxos1, Dictionary <string, List <Utxo> > dir_utxos2, string[] targetaddrs, ThinNeo.Hash256 assetid, decimal sendcount)
        {
            if (!dir_utxos1.ContainsKey(assetid.ToString()) || !dir_utxos2.ContainsKey(assetid.ToString()))
            {
                throw new Exception("no enough money.");
            }

            List <Utxo> utxos1 = dir_utxos1[assetid.ToString()];
            List <Utxo> utxos2 = dir_utxos2[assetid.ToString()];

            var tran = new ThinNeo.Transaction();

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

            tran.attributes = new ThinNeo.Attribute[0];
            utxos1.Sort((a, b) =>
            {
                if (a.value > b.value)
                {
                    return(1);
                }
                else if (a.value < b.value)
                {
                    return(-1);
                }
                else
                {
                    return(0);
                }
            });
            utxos2.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;
            string  scraddr = "";
            List <ThinNeo.TransactionInput> list_inputs = new List <ThinNeo.TransactionInput>();

            for (var i = 0; i < utxos1.Count; i++)
            {
                ThinNeo.TransactionInput input = new ThinNeo.TransactionInput();
                input.hash  = utxos1[i].txid;
                input.index = (ushort)utxos1[i].n;
                list_inputs.Add(input);
                count  += utxos1[i].value;
                scraddr = utxos1[i].addr;
                if (count >= (sendcount / 2))
                {
                    break;
                }
            }
            decimal count2   = decimal.Zero;
            string  scraddr2 = "";

            for (var i = 0; i < utxos2.Count; i++)
            {
                ThinNeo.TransactionInput input = new ThinNeo.TransactionInput();
                input.hash  = utxos2[i].txid;
                input.index = (ushort)utxos2[i].n;
                list_inputs.Add(input);
                count2  += utxos2[i].value;
                scraddr2 = utxos2[i].addr;
                if (count2 >= (sendcount / 2))
                {
                    break;
                }
            }
            tran.inputs = list_inputs.ToArray();

            if (count + count2 >= sendcount)//输入大于等于输出
            {
                List <ThinNeo.TransactionOutput> list_outputs = new List <ThinNeo.TransactionOutput>();
                //输出
                if (sendcount > decimal.Zero && targetaddrs.Length > 0)
                {
                    foreach (string targetaddr in targetaddrs)
                    {
                        ThinNeo.TransactionOutput output = new ThinNeo.TransactionOutput();
                        output.assetId   = assetid;
                        output.value     = sendcount / 2;
                        output.toAddress = ThinNeo.Helper.GetPublicKeyHashFromAddress(targetaddr);
                        list_outputs.Add(output);
                    }
                }

                //找零
                var change1 = count - sendcount / 2;
                var change2 = count2 - sendcount / 2;
                if (change1 > decimal.Zero)
                {
                    ThinNeo.TransactionOutput outputchange = new ThinNeo.TransactionOutput();
                    outputchange.toAddress = ThinNeo.Helper.GetPublicKeyHashFromAddress(scraddr);
                    outputchange.value     = change1;
                    outputchange.assetId   = assetid;
                    list_outputs.Add(outputchange);
                }
                if (change2 > decimal.Zero)
                {
                    ThinNeo.TransactionOutput outputchange = new ThinNeo.TransactionOutput();
                    outputchange.toAddress = ThinNeo.Helper.GetPublicKeyHashFromAddress(scraddr2);
                    outputchange.value     = change2;
                    outputchange.assetId   = assetid;
                    list_outputs.Add(outputchange);
                }
                tran.outputs = list_outputs.ToArray();
            }
            else
            {
                throw new Exception("no enough money.");
            }
            return(tran);
        }
Beispiel #5
0
        public static ThinNeo.Transaction makeTran(Dictionary <string, List <Utxo> > dir_utxos, string targetaddr, ThinNeo.Hash256 assetid, decimal sendcount)
        {
            var tran = new ThinNeo.Transaction();

            tran.type    = ThinNeo.TransactionType.ContractTransaction;
            tran.version = 0;
            tran.extdata = null;

            tran.attributes = new ThinNeo.Attribute[0];
            var     scraddr = "";
            decimal count   = decimal.Zero;
            List <ThinNeo.TransactionInput> list_inputs = new List <ThinNeo.TransactionInput>();

            tran.inputs = list_inputs.ToArray();
            List <ThinNeo.TransactionOutput> list_outputs = new List <ThinNeo.TransactionOutput>();

            tran.outputs = list_outputs.ToArray();

            return(tran);
        }