コード例 #1
0
        // Array request, string service, Action<string> callback, string callbackUrl
        public async Task <Texture2D> SendTransaction()
        {
            // Uri for transaction
            string baseRequestUri = "meta://transaction?", trxRequestUri = "";

            // URI for to, value, data
            baseRequestUri += "t=" + to + "&v=" + HexBigIntegerConvertorExtensions.ToHex(value, true) + "&d=" + HexStringUTF8ConvertorExtensions.ToHexUTF8(data);

            // URI for usage
            baseRequestUri += "&u=" + usage;

            // URI for callbackUrl and callback
            if (!string.IsNullOrEmpty(callbackUrl))
            {
                baseRequestUri += "&c=" + WWW.EscapeURL(callbackUrl);
            }
            else
            {
                baseRequestUri += "&c=https%3A%2F%2F0s5eebblre.execute-api.ap-northeast-2.amazonaws.com/dev?key=" + session;
            }

            Debug.Log("Transaction baseRequestUri: " + baseRequestUri);

            // URI for IPFS
            IPFSClass ipfs = new IPFSClass();

            trxRequestUri = await ipfs.IpfsAdd(baseRequestUri);

            Debug.Log("Transaction trxRequestUri(IPFS hash): " + trxRequestUri);

            // Polling request using timer
            timer = new Timer {
                Interval = 2000
            };
            timer.Elapsed  += HttpRequest;
            timer.AutoReset = true;
            timer.Enabled   = true;
            timer.Start();

            // Make QRCode for request
            QRcode.QRcode metaQR = new QRcode.QRcode();
            return(metaQR.MakeQR(256, trxRequestUri));
        }
コード例 #2
0
        private async Task SendRawTransaction(TimestampDao timestamp, IWeb3 web3, string secretKey, double estimateGasPrice, EthSettings ethSettings)
        {
            if (!Enum.TryParse(ethSettings.Network, true, out Chain networkChain))
            {
                networkChain = Chain.MainNet;
                _logger.Warning($"Unable to parse '{ethSettings.Network}' to type '{typeof(Chain)}', so setting default to '{networkChain}'.");
            }

            bool proofVerified = _ethHelper.VerifyStamp(timestamp);

            if (!proofVerified)
            {
                var message = $"Unable to verify the signature '{timestamp.Signature}'.";
                _logger.Warning(message);
                throw new TimestampException(message);
            }

            string proofStr = JsonConvert.SerializeObject(
                new
            {
                file      = timestamp.FileName,
                hash      = timestamp.FileHash,
                publicKey = timestamp.PublicKey,
                signature = timestamp.Signature
            });

            var txData = HexStringUTF8ConvertorExtensions.ToHexUTF8(proofStr);

            var fromAddress = web3.TransactionManager.Account.Address;
            var futureNonce = await web3.TransactionManager.Account.NonceService.GetNextNonceAsync();

            _logger.Information($"Signed transaction on chain: {networkChain}, To: {ethSettings.ToAddress}, Nonce: {futureNonce}, GasPrice: {estimateGasPrice}, From Address :{fromAddress}");

            var offlineTransactionSigner = new TransactionSigner();
            var encoded = offlineTransactionSigner.SignTransaction(
                secretKey,
                networkChain,
                ethSettings.ToAddress,
                Web3.Convert.ToWei(0, UnitConversion.EthUnit.Gwei),
                futureNonce,
                Web3.Convert.ToWei(estimateGasPrice, UnitConversion.EthUnit.Gwei),
                new BigInteger(100000),
                txData);

            var verified = offlineTransactionSigner.VerifyTransaction(encoded);

            if (!verified)
            {
                var message = $"Unable to verify the transaction for data '{txData}'.";
                _logger.Error(message);
                throw new TimestampException(message);
            }

            try
            {
                var txId = await web3.Eth.Transactions.SendRawTransaction.SendRequestAsync("0x" + encoded);

                timestamp.Address       = fromAddress;
                timestamp.Nonce         = (long)futureNonce.Value;
                timestamp.TransactionId = txId;
                timestamp.Network       = networkChain.ToString();
                timestamp.BlockNumber   = -1;

                if (string.IsNullOrWhiteSpace(txId))
                {
                    timestamp.Status = TimestampState.Failed;
                    var message = $"Transaction failed for an user '{timestamp.UserId}' with file name '{timestamp.FileName}'.";
                    _logger.Error(message);
                }
            }
            catch (RpcResponseException ex)
            {
                await web3.TransactionManager.Account.NonceService.ResetNonce();

                if (ex.Message.Contains("nonce too low", StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new RpcClientNonceException(ex.Message);
                }
                else if (ex.Message.Contains("transaction underpriced", StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new RpcClientUnderpricedException(ex.Message);
                }

                throw;
            }
        }