private static ECDsa loadECDSAFromPrivateKey(AccountPrivateKey privateKey) { var ecparams = new ECParameters(); ecparams.Curve = ECCurve.NamedCurves.nistP256; var ecPoint = new ECPoint(); ecPoint.X = XConvert.GetECBytesFromBigInteger(privateKey.X); ecPoint.Y = XConvert.GetECBytesFromBigInteger(privateKey.Y); ecparams.Q = ecPoint; ecparams.D = XConvert.GetECBytesFromBigInteger(privateKey.D); return(ECDsa.Create(ecparams)); }
private static ECDsa loadECDSAFromPublicKey(AccountPublicKey publicKey) { var param = new ECParameters { Curve = ECCurve.NamedCurves.nistP256, Q = new ECPoint { X = XConvert.GetECBytesFromBigInteger(publicKey.X), Y = XConvert.GetECBytesFromBigInteger(publicKey.Y), }, }; return(ECDsa.Create(param)); }
private Pb.CommonReply PostTx(string bcname, Transaction tx) { var pbtx = XConvert.LocalTxToPbTx(tx); var reqTx = new Pb.TxStatus { Txid = pbtx.Txid, Tx = pbtx, Bcname = bcname, }; var postRes = client.PostTx(reqTx); if (postRes.Header.Error != Pb.XChainErrorEnum.Success) { Console.WriteLine("post tx failed, txid=" + tx.Txid + " err=" + (int)postRes.Header.Error); return(null); } return(postRes); }
// Query a block with block id /// <summary>Query a block with block id</summary> /// <param name="bcname">the name of blockchain</param> /// <param name="blockid">block id</param> /// <return>the request response, the <c>Data</c> field is a Block type</return> public Response QueryBlock(string bcname, string blockid) { var req = new Pb.BlockID { Header = GetDefaultHeader(), Bcname = bcname, Blockid = ByteString.CopyFrom(XConvert.HexStringToByteArray(blockid)), NeedContent = true, }; var res = client.GetBlock(req); if (res.Header.Error != Pb.XChainErrorEnum.Success) { Console.WriteLine("query block failed. errcode=" + (int)res.Header.Error + ", logid=" + req.Header.Logid); return(MakeErrorResponse(ErrorCode.ConnectFailed, null)); } var block = XConvert.PbBlockToLocalBlock(res); return(MakeResponse("", block)); }
// Transfer given amount of UTXO resource to another address /// <summary>Transfer given amount of UTXO resource to another address</summary> /// <param name="bcname">the name of the blockchain</param> /// <param name="to">the receiver address</param> /// <param name="amount">the amount of UTXO resource</param> /// <param name="desc">addtional information attached to this transaction</param> /// <return>the response contains the Txid of this transaction</return> public Response Transfer(string bcname, string to, BigInteger amount, string desc) { var response = new Response() { Error = new XChainError() { ErrorCode = ErrorCode.Success, ErrorMessage = "Success", } }; if (string.IsNullOrEmpty(bcname) || string.IsNullOrEmpty(to)) { return(MakeErrorResponse(ErrorCode.ParamError, null)); } var utxo = SelectUTXO(bcname, this.Account.Address, this.Account.PublicKey, amount); if (utxo == null) { Console.WriteLine("Select utxo failed"); return(MakeErrorResponse(ErrorCode.SelectUTXOError, null)); } var tx = AssembleTx(utxo, this.Account, null, to, amount, null, desc); if (tx == null) { Console.WriteLine("AssembleTx failed"); return(MakeErrorResponse(ErrorCode.UnknownError, null)); } // post transaction var postRes = PostTx(bcname, tx); if (postRes == null || postRes.Header.Error != Pb.XChainErrorEnum.Success) { Console.WriteLine("InvokeContract: PostTx failed"); return(MakeErrorResponse(ErrorCode.PostError, null)); } response.Txid = XConvert.ByteArrayToHexString(tx.Txid).ToLower(); return(response); }
// Invokes contract method with given args // TODO: multisig is not supported /// <param name="contractName">the name of contract to invoke</param> /// <param name="method">the method name of contract to invoke</param> /// <param name="args">the arguments of contract</param> /// <param name="authRequire">add more address if multisig needed, otherwise keep null</param> public Response InvokeContract(string bcname, string contractName, string method, SortedDictionary <string, byte[]> args, List <string> authRequire = null, string desc = "", ContactVMType.Type contractType = ContactVMType.Type.WASM) { // pre-execute contract var execRes = PreExecWithSelectUTXO(bcname, this.Account.Address, this.Account.PrivateKey, 0, contractName, method, args, contractType, this.Account.Address, authRequire); if (execRes == null) { Console.WriteLine("InvokeContract: PreExecWithSelectUTXO failed"); return(null); } // check contract response var contractResult = new Dictionary <string, string>(); for (var i = 0; i < execRes.Response.Responses.Count; i++) { if (execRes.Response.Responses[i].Status >= 400) { Console.WriteLine("Contract execute failed. res=" + JsonConvert.SerializeObject(execRes.Response.Responses[i])); return(new Response { Error = new XChainError { ErrorCode = Errors.Success, }, }); } contractResult.Add(execRes.Response.Requests[i].ContractName + ":" + execRes.Response.Requests[i].MethodName, Encoding.ASCII.GetString(execRes.Response.Responses[i].Body.ToByteArray())); } // assemble transaction var tx = AssembleTx(execRes.UtxoOutput, this.Account, authRequire, "", 0, execRes.Response, desc); if (tx == null) { Console.WriteLine("InvokeContract: AssembleTx failed"); return(null); } // post transaction var postRes = PostTx(bcname, tx); if (postRes == null || postRes.Header.Error != Pb.XChainErrorEnum.Success) { Console.WriteLine("InvokeContract: PostTx failed"); return(null); } var res = new Response { Error = new XChainError { ErrorCode = Errors.Success, }, Txid = XConvert.ByteArrayToHexString(tx.Txid), Data = contractResult, }; return(res); }
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)); } }