Exemplo n.º 1
0
        private static byte[] calcDigest(Transaction tx, bool needSigns)
        {
            string encoded  = "";
            var    settings = new JsonSerializerSettings()
            {
                Formatting           = Formatting.None,
                DefaultValueHandling = DefaultValueHandling.Ignore,
                NullValueHandling    = NullValueHandling.Ignore,
            };

            if (tx.TxInputs != null)
            {
                for (var i = 0; i < tx.TxInputs.Count; i++)
                {
                    var input = tx.TxInputs[i];
                    if (input.RefTxid.Length > 0)
                    {
                        encoded += JsonConvert.SerializeObject(input.RefTxid) + "\n";
                    }
                    encoded += JsonConvert.SerializeObject(input.RefOffset) + "\n";
                    if (input.FromAddr.Length > 0)
                    {
                        encoded += JsonConvert.SerializeObject(input.FromAddr) + "\n";
                    }
                    if (input.Amount.Length > 0)
                    {
                        encoded += JsonConvert.SerializeObject(input.Amount) + "\n";
                    }
                    encoded += JsonConvert.SerializeObject(input.FrozenHeight) + "\n";
                }
            }

            encoded += JsonConvert.SerializeObject(tx.TxOutputs, settings) + "\n";
            if (tx.Desc != null && tx.Desc.Length > 0)
            {
                encoded += JsonConvert.SerializeObject(tx.Desc) + "\n";
            }
            encoded += JsonConvert.SerializeObject(tx.Nonce, settings) + "\n";
            encoded += JsonConvert.SerializeObject(tx.Timestamp) + "\n";
            encoded += JsonConvert.SerializeObject(tx.Version) + "\n";
            if (tx.TxInputsExt != null)
            {
                for (var i = 0; i < tx.TxInputsExt.Count; i++)
                {
                    var input = tx.TxInputsExt[i];
                    encoded += JsonConvert.SerializeObject(input.Bucket) + "\n";
                    if (input.Key.Length > 0)
                    {
                        encoded += JsonConvert.SerializeObject(input.Key) + "\n";
                    }
                    if (input.RefTxid.Length > 0)
                    {
                        encoded += JsonConvert.SerializeObject(input.RefTxid) + "\n";
                    }
                    encoded += JsonConvert.SerializeObject(input.RefOffset) + "\n";
                }
            }

            if (tx.TxOutputsExt != null)
            {
                foreach (var output in tx.TxOutputsExt)
                {
                    encoded += (JsonConvert.SerializeObject(output.Bucket) + "\n");
                    if (output.Key.Length > 0)
                    {
                        encoded += (JsonConvert.SerializeObject(output.Key) + "\n");
                    }
                    if (output.Value.Length > 0)
                    {
                        encoded += (JsonConvert.SerializeObject(output.Value) + "\n");
                    }
                }
            }

            encoded += (JsonConvert.SerializeObject(tx.ContractRequests, settings) + "\n");
            encoded += (JsonConvert.SerializeObject(tx.Initiator) + "\n");
            encoded += (JsonConvert.SerializeObject(tx.AuthRequire) + "\n");

            if (needSigns)
            {
                encoded += (JsonConvert.SerializeObject(tx.InitiatorSigns) + "\n");
                encoded += (JsonConvert.SerializeObject(tx.AuthRequireSigns) + "\n");
            }

            encoded += (JsonConvert.SerializeObject(tx.Coinbase) + "\n");
            encoded += (JsonConvert.SerializeObject(tx.Autogen) + "\n");
            Console.WriteLine("Debug: digest=\n" + encoded);
            var encodedBytes = Encoding.ASCII.GetBytes(encoded);

            return(XCrypto.DoubleSha256(encodedBytes));
        }
Exemplo n.º 2
0
        private Transaction AssembleTx(Pb.UtxoOutput utxo, XCAccount account, List <string> authRequire,
                                       string to, BigInteger amount, Pb.InvokeResponse contractInvoke, string desc)
        {
            var tx = new Transaction();

            // check param
            if (amount < 0 || account == null)
            {
                return(null);
            }
            // if have utxo, assemble utxo input/ouput
            if (utxo != null)
            {
                // assemble TxInputs
                tx.TxInputs = new List <TxInput>();
                var total = BigInteger.Parse(utxo.TotalSelected);
                for (var i = 0; i < utxo.UtxoList.Count; i++)
                {
                    var utxoItem = utxo.UtxoList[i];
                    var input    = new TxInput
                    {
                        FromAddr  = utxoItem.ToAddr.ToByteArray(),
                        Amount    = utxoItem.Amount.ToByteArray(),
                        RefTxid   = utxoItem.RefTxid.ToByteArray(),
                        RefOffset = utxoItem.RefOffset,
                    };
                    tx.TxInputs.Add(input);
                }

                tx.TxOutputs = new List <TxOutput>();
                // Assemble utxo Output for transferring to
                if (amount > 0 && to != "")
                {
                    // utxo check
                    if (amount > total)
                    {
                        Console.WriteLine("Utxo use greater than utxo selected" + ", selected=" + total + ", use=", amount);
                        return(null);
                    }
                    var output = new TxOutput()
                    {
                        ToAddr = Encoding.ASCII.GetBytes(to),
                        Amount = amount.ToByteArray(),
                    };
                    Array.Reverse(output.Amount, 0, output.Amount.Length);
                    tx.TxOutputs.Add(output);
                    total -= amount;
                }

                // Assemble contract fee
                if (contractInvoke != null && contractInvoke.GasUsed > 0)
                {
                    var gasUsed = new BigInteger(contractInvoke.GasUsed);
                    if (gasUsed > total)
                    {
                        Console.WriteLine("Utxo use greater than utxo selected" + ", selected=" + total + ", use=", gasUsed);
                        return(null);
                    }
                    var output = new TxOutput()
                    {
                        ToAddr = Encoding.ASCII.GetBytes("$"),
                        Amount = gasUsed.ToByteArray(),
                    };
                    Array.Reverse(output.Amount, 0, output.Amount.Length);
                    tx.TxOutputs.Add(output);
                    total -= gasUsed;
                }

                // charge utxo to user
                if (total > 0)
                {
                    var chargeOutput = new TxOutput()
                    {
                        ToAddr = Encoding.ASCII.GetBytes(account.Address),
                        Amount = total.ToByteArray(),
                    };
                    Array.Reverse(chargeOutput.Amount, 0, chargeOutput.Amount.Length);
                    tx.TxOutputs.Add(chargeOutput);
                }
            }

            // Assemble contracts
            if (contractInvoke != null)
            {
                if (contractInvoke.Inputs.Count > 0)
                {
                    tx.TxInputsExt = new List <TxInputExt>();
                }
                if (contractInvoke.Outputs.Count > 0)
                {
                    tx.TxOutputsExt = new List <TxOutputExt>();
                }
                if (contractInvoke.Requests.Count > 0)
                {
                    tx.ContractRequests = new List <InvokeRequest>();
                }
                // TODO: transfer within contract is not supported
                foreach (var input in contractInvoke.Inputs)
                {
                    var inputExt = new TxInputExt
                    {
                        Bucket    = input.Bucket,
                        Key       = input.Key.ToByteArray(),
                        RefTxid   = input.RefTxid.ToByteArray(),
                        RefOffset = input.RefOffset,
                    };
                    tx.TxInputsExt.Add(inputExt);
                }
                foreach (var output in contractInvoke.Outputs)
                {
                    var outputExt = new TxOutputExt
                    {
                        Bucket = output.Bucket,
                        Key    = output.Key.ToByteArray(),
                        Value  = output.Value.ToByteArray(),
                    };
                    tx.TxOutputsExt.Add(outputExt);
                }
                foreach (var request in contractInvoke.Requests)
                {
                    var invoke = new InvokeRequest
                    {
                        ModuleName   = request.ModuleName,
                        ContractName = request.ContractName,
                        MethodName   = request.MethodName,
                    };
                    foreach (var arg in request.Args)
                    {
                        invoke.Args.Add(arg.Key, arg.Value.ToByteArray());
                    }
                    foreach (var limit in request.ResourceLimits)
                    {
                        invoke.ResourceLimits.Add(new ResourceLimit
                        {
                            Type  = (ResourceType)limit.Type,
                            Limit = limit.Limit,
                        });
                    }
                    tx.ContractRequests.Add(invoke);
                }
            }

            // Assemble other data
            tx.Desc      = Encoding.ASCII.GetBytes(desc);
            tx.Version   = 1;
            tx.Coinbase  = false;
            tx.Autogen   = false;
            tx.Initiator = account.Address;
            if (authRequire != null && authRequire.Count > 0)
            {
                tx.AuthRequire = authRequire;
            }
            var digestHash = XDigest.MakeDigestHash(tx);
            var sign       = XCrypto.SignHash(account.PrivateKey, digestHash);
            var signInfo   = new SignatureInfo()
            {
                PublicKey = account.PublicKey.RawKey,
                Sign      = sign,
            };

            tx.InitiatorSigns = new List <SignatureInfo>();
            tx.InitiatorSigns.Add(signInfo);
            if (authRequire != null && authRequire.Count > 0)
            {
                tx.AuthRequireSigns = new List <SignatureInfo>();
                tx.AuthRequireSigns.Add(signInfo);
            }
            var txid = XDigest.MakeTransactionID(tx);

            tx.Txid = txid;
            return(tx);
        }
Exemplo n.º 3
0
        static void Main(string[] args)
        {
            var client = new XChainClient();

            if (!client.Init("./data/keys", "127.0.0.1:37101"))
            {
                Console.WriteLine("Create client failed");
                return;
            }

            // test asn1
            BigInteger r      = new BigInteger(190);
            BigInteger s      = new BigInteger(1024567);
            var        result = XCrypto.Asn1EncodeSign(r, s);

            Console.WriteLine("Encode result=" + XConvert.ByteArrayToHexString(result));

            // test sign
            var data = Encoding.ASCII.GetBytes("123abc");
            var sign = XCrypto.SignHash(client.Account.PrivateKey, data);

            Console.WriteLine("Sign result=" + XConvert.ByteArrayToHexString(sign));

            // test verify sign
            var sign2 = XConvert.HexStringToByteArray("30450221008fb23b0a4e0c1b23cb11517fe25e2eb9ab92c57f62d0d2acf1485a2498ae5dfa02202f480e71c36784af24ca1af1aade44c689fd7a7805a3963e345de3fce71c6b96");
            var valid = XCrypto.VerifySign(client.Account.PublicKey, sign2, data);

            Console.WriteLine("Verify result=" + valid);

            // test get balance
            var balance = client.GetBalance("xuper");

            Console.WriteLine("Account balance=" + balance.ToString());

            // hash test
            var tx = new Transaction();

            tx.Desc     = Encoding.ASCII.GetBytes("this is a desc");
            tx.TxInputs = new List <TxInput>()
            {
                new TxInput {
                    Amount       = Encoding.ASCII.GetBytes("888"),
                    FromAddr     = Encoding.ASCII.GetBytes("dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN"),
                    RefTxid      = XConvert.HexStringToByteArray("3027697986fb8f926dc272697e5bc03b8286ef1d1e6604c85b043661b5a8b750"),
                    RefOffset    = 0,
                    FrozenHeight = 0,
                }
            };
            tx.TxOutputs = new List <TxOutput>()
            {
                new TxOutput
                {
                    Amount = Encoding.ASCII.GetBytes("888"),
                    ToAddr = Encoding.ASCII.GetBytes("alice"),
                }
            };
            var digest = XDigest.MakeDigestHash(tx);

            Console.WriteLine("Digest hash=" + BitConverter.ToString(digest).Replace("-", ""));

            // make transaction
            var transRes = client.Transfer("xuper", "alice", new BigInteger(100), "test");

            if (transRes.Error.ErrorCode != Errors.Success)
            {
                Console.WriteLine("Transfer failed, err=" + transRes.Error.ErrorMessage);
            }
            else
            {
                Console.WriteLine("Transfer success, txid=" + transRes.Txid);
            }

            // query transaction
            var txRes = client.QueryTx("xuper", transRes.Txid);

            if (txRes == null || txRes.Error.ErrorCode != Errors.Success)
            {
                Console.WriteLine("query tx failed");
            }
            else
            {
                var txData = (Transaction)txRes.Data;
                Console.WriteLine("-------------- Transaction Info: -------------");
                Console.WriteLine("Txid: " + transRes.Txid);
                if (tx.Blockid != null)
                {
                    Console.WriteLine("Blockid: " + XConvert.ByteArrayToHexString(txData.Blockid));
                }
                if (tx.Desc != null)
                {
                    Console.WriteLine("Desc: " + Encoding.ASCII.GetString(tx.Desc));
                }
            }

            //test new account
            var newAccountRes = client.NewContractAccount("xuper", "1111111111111111");

            if (newAccountRes == null || newAccountRes.Error.ErrorCode != Errors.Success)
            {
                Console.WriteLine("New account failed");
            }
            else
            {
                Console.WriteLine("New account success, account=" + (string)newAccountRes.Data);
            }

            //test deploy account
            var initArgs = new Dictionary <string, byte[]>();

            initArgs["creator"] = Encoding.ASCII.GetBytes("xchain");
            var deployRes = client.DeployWASMContract("xuper", "counter",
                                                      "/Users/wangyucao/code/yucaowang/xuperunion/output/counter.wasm",
                                                      "XC1111111111111111@xuper", initArgs, "c");

            if (deployRes == null || deployRes.Error.ErrorCode != Errors.Success)
            {
                Console.WriteLine("Deploy Contract Failed");
            }

            // test invoke contract
            var cArgs = new SortedDictionary <string, byte[]>();

            cArgs.Add("key", Encoding.ASCII.GetBytes("xchain"));
            var invokeRes = client.InvokeContract("xuper", "counter", "increase", cArgs);

            if (invokeRes == null || invokeRes.Error.ErrorCode != Errors.Success)
            {
                Console.WriteLine("Invoke Contract Failed");
            }
            else
            {
                Console.WriteLine("Contract Response:" + JsonConvert.SerializeObject(invokeRes.Data));
            }
        }