Beispiel #1
0
        /// <summary>
        /// ABI decoder. Used to parse rpc responses from the EVM.
        /// Based on the Solidity specification <see href="https://solidity.readthedocs.io/en/v0.5.3/abi-spec.html" />.
        /// </summary>
        /// <param name="signature">Function signature i.e. <i>>(address,string,uint256)</i> or <i>>getBalance(uint256):uint256</i>. In case of the latter, the function signature will be ignored and only the return types will be parsed.</param>
        /// <param name="encodedData">Abi encoded values. Usually the string returned from a rpc to the EVM.</param>
        /// <returns>The decoded argugments for the function call given the encded data.</returns>
        public async Task <object[]> AbiDecode(string signature, string encodedData)
        {
            string jsonResponse = await _in3.SendRpc(In3AbiDecode, new object[] {
                signature, encodedData
            });

            // This is ugly, unsemantic and error prone and SHOULD be changed.
            JsonElement result = (JsonElement)RpcHandler.From <object>(jsonResponse);

            if (result.ValueKind == JsonValueKind.String)
            {
                string singleResult = result.GetString();
                return(new[] { singleResult });
            }

            IEnumerator <JsonElement> arr = result.EnumerateArray();

            object[] arrayResult = new object[result.GetArrayLength()];
            int      i           = 0;

            while (arr.MoveNext())
            {
                arrayResult[i] = arr.Current.ValueKind switch
                {
                    JsonValueKind.String => arr.Current.GetString(),
                    JsonValueKind.Number => arr.Current.GetUInt32(),
                    JsonValueKind.False or JsonValueKind.True => arr.Current.GetBoolean(),
                    _ => arrayResult[i]
                };
                i++;
            }

            return(arrayResult);
        }
Beispiel #2
0
        /// <summary>
        /// Transactions can be identified by root hash of the transaction merkle tree (this) or by its position in the block transactions merkle tree.
        /// Every transaction hash is unique for the whole chain. Collision could in theory happen, chances are 67148E-63%.
        /// See also <see cref="Eth1.Api.GetTransactionByBlockNumberAndIndex" />.
        /// </summary>
        /// <param name="blockHash">Desired block hash.</param>
        /// <param name="index">The index of the <see cref="Transaction" /> in a <see cref="Block" /></param>
        /// <returns>The <see cref="Transaction" /> (if it exists).</returns>
        public async Task <Transaction> GetTransactionByBlockHashAndIndex(String blockHash, int index)
        {
            string jsonResponse = await _in3.SendRpc(EthGetTransactionByBlockHashAndIndex,
                                                     new object[] { blockHash, BlockParameter.AsString(index) });

            return(RpcHandler.From <Transaction>(jsonResponse));
        }
Beispiel #3
0
        /// <summary>
        /// Retrieve the of uncle of a block for the given <paramref name="blockNumber" /> and a position. Uncle blocks are valid blocks and are mined in a genuine manner, but get rejected from the main blockchain.
        /// </summary>
        /// <param name="blockNumber">Block number or <see cref="BlockParameter.Latest" /> or <see cref="BlockParameter.Earliest" />.</param>
        /// <param name="position">Position of the block.</param>
        /// <returns>The uncle block.</returns>
        public async Task <Block> GetUncleByBlockNumberAndIndex(BigInteger blockNumber, int position)
        {
            string jsonResponse = await _in3.SendRpc(EthGetUncleByBlockNumberAndIndex,
                                                     new object[] { BlockParameter.AsString(blockNumber), DataTypeConverter.BigIntToPrefixedHex(position) });

            return(RpcHandler.From <TransactionBlock>(jsonResponse));
        }
Beispiel #4
0
        /// <summary>
        /// Transactions can be identified by root hash of the transaction merkle tree (this) or by its position in the block transactions merkle tree.
        /// Every transaction hash is unique for the whole chain. Collision could in theory happen, chances are 67148E-63%.
        /// </summary>
        /// <param name="blockNumber">Block number or <see cref="BlockParameter.Latest" /> or <see cref="BlockParameter.Earliest" />.</param>
        /// <param name="index">The index of the <see cref="Transaction" /> in a <see cref="Block" /></param>
        /// <returns>The <see cref="Transaction" /> (if it exists).</returns>
        public async Task <Transaction> GetTransactionByBlockNumberAndIndex(BigInteger blockNumber, int index)
        {
            string jsonResponse = await _in3.SendRpc(EthGetTransactionByBlockNumberAndIndex,
                                                     new object[] { BlockParameter.AsString(blockNumber), BlockParameter.AsString(index) });

            return(RpcHandler.From <Transaction>(jsonResponse));
        }
Beispiel #5
0
        public void From_ErrorString()
        {
            string nonCompliantJsonRpc =
                "{\"id\":0,\"jsonrpc\":\"2.0\",\"error\":{\"code\":-1,\"message\":\"The Stack is empty\"}}";

            Assert.Throws <RpcException>(() => RpcHandler.From <string>(nonCompliantJsonRpc));
        }
Beispiel #6
0
        public void From_ErrorObject()
        {
            string nonCompliantJsonRpc =
                "{\"id\":1,\"error\":\"getaddrinfo ENOTFOUND ipfs.iotlayer-deploy\",\"jsonrpc\":\"2.0\"}";

            Assert.Throws <RpcException>(() => RpcHandler.From <string>(nonCompliantJsonRpc));
        }
Beispiel #7
0
        /// <summary>
        /// Decryot an encrypted private key.
        /// </summary>
        /// <param name="pk">Private key.</param>
        /// <param name="passphrase">Passphrase whose <paramref name="pk" />.</param>
        /// <returns>Decrypted key.</returns>
        public async Task <string> DecryptKey(string pk, string passphrase)
        {
            Dictionary <string, object> res = JsonSerializer.Deserialize <Dictionary <string, object> >(pk);
            string jsonResponse             = await in3.SendRpc(CryptoDecryptKey, new object[] { res, passphrase });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #8
0
        /// <summary>
        /// Stored value in designed position at a given <paramref name="address" />. Storage can be used to store a smart contract state, constructor or just any data.
        /// Each contract consists of a EVM bytecode handling the execution and a storage to save the state of the contract.
        /// </summary>
        /// <param name="address">Ethereum account address.</param>
        /// <param name="position">Position index, 0x0 up to 100.</param>
        /// <param name="blockNumber">Block number or <see cref="BlockParameter.Latest" /> or <see cref="BlockParameter.Earliest" />.</param>
        /// <returns>Stored value in designed position.</returns>
        public async Task <string> GetStorageAt(string address, BigInteger position, BigInteger blockNumber)
        {
            string jsonResponse = await _in3.SendRpc(EthGetStorageAt, new object[] {
                address, DataTypeConverter.BigIntToPrefixedHex(position), BlockParameter.AsString(blockNumber)
            });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #9
0
        /// <summary>
        /// ABI encoder. Used to serialize a rpc to the EVM.
        /// Based on the Solidity specification <see href="https://solidity.readthedocs.io/en/v0.5.3/abi-spec.html" />.
        /// Note: Parameters refers to the list of variables in a method declaration.
        /// Arguments are the actual values that are passed in when the method is invoked.
        /// When you invoke a method, the arguments used must match the declaration's parameters in type and order.
        /// </summary>
        /// <param name="signature">Function signature, with parameters. i.e. <i>>getBalance(uint256):uint256</i>, can contain the return types but will be ignored.</param>
        /// <param name="args">Function parameters, in the same order as in passed on to <b>signature</b>.</param>
        /// <returns>The encoded data.</returns>
        public async Task <string> AbiEncode(string signature, object[] args)
        {
            string jsonResponse = await _in3.SendRpc(In3AbiEncode, new object[] {
                signature, args
            });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #10
0
        /// <summary>
        /// Signs and sends the assigned transaction. The <see cref="Signer" /> used to sign the transaction is the one set by <see cref="IN3.Signer" />.
        /// Transactions change the state of an account, just the balance, or additionally, the storage and the code.
        /// Every transaction has a cost, gas, paid in Wei. The transaction gas is calculated over estimated gas times the gas cost, plus an additional miner fee, if the sender wants to be sure that the transaction will be mined in the latest block.
        /// See <see cref="Eth1.Api.SendTransactionAndWait"/> to wait for the <see cref="TransactionReceipt"/> in the same call.
        /// </summary>
        /// <param name="tx">All information needed to perform a transaction.</param>
        /// <returns>Transaction hash, used to get the receipt and check if the transaction was mined.</returns>
        /// <example>
        ///   <code>
        ///    SimpleWallet wallet = (SimpleWallet) client.Signer;
        ///    TransactionRequest tx = new TransactionRequest();
        ///    tx.From = wallet.AddRawKey(pk);;
        ///    tx.To = "0x3940256B93c4BE0B1d5931A6A036608c25706B0c";
        ///    tx.Gas = 21000;
        ///    tx.Value = 100000000;
        ///    client.Eth1.SendTransaction(tx);
        ///   </code>
        /// </example>
        public async Task <string> SendTransaction(TransactionRequest tx)
        {
            ValidateTransaction(tx);
            tx = _in3.Signer.PrepareTransaction(tx);

            string jsonResponse = await _in3.SendRpc(EthSendTransaction, new object[] { await MapTransactionToRpc(tx) });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #11
0
        internal Task <string> SendRpc(string method, object[] args, Dictionary <string, object> in3 = null)
        {
            if (Configuration.HasChanged())
            {
                NativeClient.ApplyConfiguration(Configuration);
            }

            return(new Runner(NativeClient).Run(RpcHandler.To(method, args, in3)));
        }
Beispiel #12
0
        public void From_String()
        {
            string nonCompliantJsonRpc =
                "{\"jsonrpc\":\"2.0\",\"result\":\"0x7d2b7500\",\"id\":1}";

            string result = RpcHandler.From <string>(nonCompliantJsonRpc);

            Assert.That(result, Is.EqualTo("0x7d2b7500"));
        }
Beispiel #13
0
        /// <summary>
        ///  Remove name and methods from internal lists
        /// </summary>
        /// <param name="handler">IRpcHandler instance</param>
        void Unregister(RpcHandler handler)
        {
            lock (mHandlers)
                mHandlers.Remove(handler);

            if (OnListChanged != null)
            {
                OnListChanged(Methods());
            }
        }
Beispiel #14
0
        /// <summary>
        /// Calls a smart-contract method. Will be executed locally by Incubed's EVM or signed and sent over to save the state changes.
        /// Check https://ethereum.stackexchange.com/questions/3514/how-to-call-a-contract-method-using-the-eth-call-json-rpc-api for more.
        /// </summary>
        /// <param name="request">The transaction request to be processed.</param>
        /// <param name="blockNumber">Block number or <see cref="BlockParameter.Latest" /> or <see cref="BlockParameter.Earliest" />.</param>
        /// <returns>Ddecoded result. If only one return value is expected the Object will be returned, if not an array of objects will be the result.</returns>
        public async Task <object> Call(TransactionRequest request, BigInteger blockNumber)
        {
            string jsonResponse = await _in3.SendRpc(EthCall, new object[] { await MapTransactionToRpc(request), BlockParameter.AsString(blockNumber) });

            if (request.IsFunctionInvocation())
            {
                return(await AbiDecode(request.Function, RpcHandler.From <string>(jsonResponse)));
            }

            return(RpcHandler.From <object>(jsonResponse));
        }
Beispiel #15
0
        /// <summary>
        /// Returns the content associated with specified multihash on success OR <lang cref="Chain.Ipfs" /> on error.
        /// </summary>
        /// <param name="multihash">The multihash.</param>
        /// <returns>The content that was stored by <see cref="Ipfs.Api.Put(byte[])" /> or <see cref="Ipfs.Api.Put(string)" />.</returns>
        public async Task <byte[]> Get(string multihash)
        {
            if (multihash == null)
            {
                throw new ArgumentException();
            }

            string result = await in3.SendRpc(IpfsGet, new object[] { multihash, IpfsEncoding.Base64.Value });

            return(RpcHandler.From <byte[]>(result));
        }
Beispiel #16
0
        /// <summary>
        /// Stores content on ipfs. The content is encoded as base64 before storing.
        /// </summary>
        /// <param name="content">The content that will be stored via ipfs.</param>
        /// <returns>The multihash.</returns>
        public async Task <string> Put(byte[] content)
        {
            if (content == null)
            {
                throw new ArgumentException();
            }

            string encodedContent = Convert.ToBase64String(content);
            string result         = await in3.SendRpc(IpfsPut, new object[] { encodedContent });

            return(RpcHandler.From <string>(result));
        }
Beispiel #17
0
        /// <summary>
        /// Blocks can be identified by root hash of the block merkle tree (this), or sequential number in which it was mined <see cref="Eth1.Api.GetBlockByNumber" />.
        /// </summary>
        /// <param name="blockHash">Desired block hash.</param>
        /// <param name="shouldIncludeTransactions">If true, returns the full transaction objects, otherwise only its hashes. The default value is <see langword="false"/>.</param>
        /// <returns>The <see cref="Block" /> of the requested <b>blockHash</b> (if exists).</returns>
        /// <remarks>
        /// <para>
        /// Returning <see cref="Block" /> must be cast to <see cref="TransactionBlock" /> or <see cref="TransactionHashBlock" /> to access the transaction data.
        /// </para>
        /// </remarks>
        public async Task <Block> GetBlockByHash(string blockHash, bool shouldIncludeTransactions = true)
        {
            string jsonResponse = await _in3.SendRpc(EthGetBlockByHash,
                                                     new object[] { blockHash, shouldIncludeTransactions });

            if (shouldIncludeTransactions)
            {
                return(RpcHandler.From <TransactionBlock>(jsonResponse));
            }
            else
            {
                return(RpcHandler.From <TransactionHashBlock>(jsonResponse));
            }
        }
        public ServiceProxyInterceptor(
            Type serviceType,
            IServiceResolver serviceResolver,
            RpcHandler handler,
            RpcMethodFixture fixture,
            IServiceLoadBalancingStrategy strategy)
        {
            _serviceType     = serviceType;
            _serviceResolver = serviceResolver;

            _handler  = handler;
            _fixture  = fixture;
            _strategy = strategy;
        }
Beispiel #19
0
        /// <summary>
        /// Blocks can be identified by sequential number in which it was mined, or root hash of the block merkle tree <see cref="Eth1.Api.GetBlockByHash" />.
        /// </summary>
        /// <param name="blockNumber">Desired block number or <see cref="BlockParameter.Latest" /> or <see cref="BlockParameter.Earliest" />.</param>
        /// <param name="shouldIncludeTransactions">If <see langword="true"/>, returns the full transaction objects, otherwise only its hashes. The default value is <see langword="true"/>.</param>
        /// <returns>The <see cref="Block" /> of the requested <b>blockNumber</b> (if exists).</returns>
        /// <remarks>
        /// <para>
        /// Returning <see cref="Block" /> must be cast to <see cref="TransactionBlock" /> or <see cref="TransactionHashBlock" /> to access the transaction data.
        /// </para>
        /// </remarks>
        /// <example>
        ///   <code>
        ///   TransactionBlock latest = (TransactionBlock) _client.Eth1.GetBlockByNumber(BlockParameter.Latest, true);
        ///   TransactionHashBlock earliest = (TransactionHashBlock) _client.Eth1.GetBlockByNumber(BlockParameter.Earliest, false);
        ///   </code>
        /// </example>
        public async Task <Block> GetBlockByNumber(BigInteger blockNumber, bool shouldIncludeTransactions = true)
        {
            string jsonResponse = await _in3.SendRpc(EthGetBlockByNumber,
                                                     new object[] { BlockParameter.AsString(blockNumber), shouldIncludeTransactions });

            if (shouldIncludeTransactions)
            {
                return(RpcHandler.From <TransactionBlock>(jsonResponse));
            }
            else
            {
                return(RpcHandler.From <TransactionHashBlock>(jsonResponse));
            }
        }
Beispiel #20
0
        public ServerConnection(ILog logger, IProxy proxy, string host, int port)
        {
            mLogger = logger;
            mProxy  = proxy;
            mProxy.OnListChanged += ProxyOnOnListChanged;
            mHost = host;
            mPort = port;

            ReconnectionTimeout = new TimeSpan(0, 0, 10);
            mRequestGuardtime   = new TimeSpan(0, 5, 0);

            mThread = new Thread(ProcessingThread);

            mRpcHandler = new RpcHandler();
        }
Beispiel #21
0
        /// <summary>
        ///  Add name and methods to internal lists
        /// </summary>
        /// <param name="handler">IRpcHandler instance</param>
        void AddHandler(RpcHandler handler)
        {
            lock (mHandlers)
            {
                if (handler.IsActive)
                {
                    mHandlers.Add(handler);
                }

                if (OnListChanged != null)
                {
                    OnListChanged(Methods());
                }
            }
        }
Beispiel #22
0
        private void HandlerRouteRpc(EventMsg eventMsg)
        {
            RpcEventMsg rpcMsg = (RpcEventMsg)eventMsg;

            RpcHandler handler = null;

            if (rpcHandlerMap.TryGetValue(rpcMsg.rpcName, out handler))
            {
                workerContext.s = rpcMsg.sAgent;
                handler(workerContext, rpcMsg.attachData);
            }
            else
            {
                sLog.Error("executor", "executor {0} handle route rpc type {1} null.", this.mName, rpcMsg.rpcName);
            }
        }
Beispiel #23
0
        public T CreateServiceProxy <T>(RpcHandler handler, RpcMethodFixture fixture, IServiceLoadBalancingStrategy strategy)
        {
            var proxy = _proxyGenerator.CreateInterfaceProxyWithoutTarget(
                typeof(T),
                new ProxyGenerationOptions(),
                new IInterceptor[]
            {
                new ServiceProxyInterceptor(
                    typeof(T),
                    _serviceResolver,
                    handler,
                    fixture,
                    strategy)
            });

            return((T)proxy);
        }
Beispiel #24
0
        public RpcAgent(PluginManager pluginMgr)
            : base(pluginMgr)
        {
            handler = new RpcHandler();

            var config = new TcpSocketServerConfiguration();

            config.AllowNatTraversal = false;

            server = new TcpSocketServer(Settings.Default.Port, config);
            server.ClientConnected    += OnClientConnected;
            server.ClientDisconnected += OnClientDisconnected;
            server.ClientDataReceived += OnClientDataReceived;
            server.Listen();

            Console.WriteLine(string.Format("Rpc agent is running on port {0}.", Settings.Default.Port));
        }
Beispiel #25
0
        private async void Startup()
        {
            // Setup RPC handlers
            RpcManager.Configure(this.EventHandlers);

            var ticks  = new TickManager(c => this.Tick += c, c => this.Tick -= c);
            var events = new EventManager();
            var rpc    = new RpcHandler();
            var nui    = new NuiManager(this.EventHandlers);

            var user = await rpc.Event("clientInitialize").Request <User>("1.0.0");

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (assembly.GetCustomAttribute <ClientPluginAttribute>() == null)
                {
                    continue;
                }

                this.logger.Info(assembly.GetName().Name);

                foreach (var type in assembly.GetTypes().Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(Service))))
                {
                    this.logger.Info($"\t{type.FullName}");

                    var service = (Service)Activator.CreateInstance(type, new Logger($"Plugin|{type.Name}"), ticks, events, rpc, nui, user);
                    await service.Loaded();

                    this.services.Add(service);
                }
            }

            this.logger.Info("Plugins loaded");

#pragma warning disable 4014
            foreach (var service in this.services)
            {
                service.Started();
            }
#pragma warning restore 4014

            this.logger.Info("Plugins started");

            rpc.Event("clientInitialized").Trigger();
        }
Beispiel #26
0
        /// <summary>
        /// Signs and sends the assigned transaction. The <see cref="Signer" /> used to sign the transaction is the one set by <see cref="IN3.Signer" />.
        /// Transactions change the state of an account, just the balance, or additionally, the storage and the code.
        /// Every transaction has a cost, gas, paid in Wei. The transaction gas is calculated over estimated gas times the gas cost, plus an additional miner fee, if the sender wants to be sure that the transaction will be mined in the latest block.
        /// </summary>
        /// <param name="tx">All information needed to perform a transaction.</param>
        /// <returns>Transaction hash, used to get the receipt and check if the transaction was mined.</returns>
        /// <example>
        ///   <code>
        ///    SimpleWallet wallet = (SimpleWallet) client.Signer;
        ///    TransactionRequest tx = new TransactionRequest();
        ///    tx.From = wallet.AddRawKey(pk);;
        ///    tx.To = "0x3940256B93c4BE0B1d5931A6A036608c25706B0c";
        ///    tx.Gas = 21000;
        ///    tx.Value = 100000000;
        ///    client.Eth1.SendTransaction(tx);
        ///   </code>
        /// </example>
        public async Task <string> SendTransaction(TransactionRequest tx)
        {
            if (_in3.Signer == null)
            {
                throw new SystemException("No Signer set. This is needed in order to sign transaction.");
            }
            if (tx.From == null)
            {
                throw new SystemException("No from address set");
            }
            if (!_in3.Signer.CanSign(tx.From))
            {
                throw new SystemException("The from address is not supported by the signer");
            }
            tx = _in3.Signer.PrepareTransaction(tx);

            string jsonResponse = await _in3.SendRpc(EthSendTransaction, new object[] { await MapTransactionToRpc(tx) });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #27
0
        /// <summary>
        /// We wait new connection from IRpcHandlers in this thread
        /// </summary>
        private void HandlerThread()
        {
            mHandlerListener.Start();

            while (true)
            {
                try
                {
                    var client = mHandlerListener.AcceptTcpClient();

                    var module = new RpcHandler {
                        RequestGuardtime = new TimeSpan(0, 5, 0)
                    };                                                                        // 5 minute is default
                    module.Handler(client);
                    AddHandler(module);

                    if (mLogger != null)
                    {
                        mLogger.Debug("IRpcHandler connection request received");
                    }

                    Thread.Sleep(200);
                }
                catch (ThreadAbortException)
                {
                    mHandlerListener.Stop();

                    throw;
                }
                catch (Exception ex)
                {
                    if (!(ex is SocketException || ex is IOException || ex is InvalidOperationException))
                    {
                        if (mLogger != null)
                        {
                            mLogger.Warn("Unexpected exception " + ex.GetType() + " at HandlerThread " + ex.Message);
                        }
                    }
                }
            }
        }
Beispiel #28
0
        /// <summary>
        /// Hash the input data using sha3 algorithm.
        /// </summary>
        /// <param name="data">Content to be hashed.</param>
        /// <returns>Hashed output.</returns>
        public async Task <string> Sha3(string data)
        {
            string jsonResponse = await in3.SendRpc(CryptoSha3, new object[] { data });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #29
0
        /// <summary>
        /// Recovers the account associated with the signed data.
        /// </summary>
        /// <param name="signedData">Data that was signed with.</param>
        /// <param name="signature">The signature.</param>
        /// <param name="signatureType">One of <see cref="SignatureType" />.</param>
        /// <returns>The account.</returns>
        public async Task <Account> EcRecover(string signedData, string signature, SignatureType signatureType)
        {
            string jsonResponse = await in3.SendRpc(CryptoEcRecover, new object[] { signedData, signature, signatureType?.Value });

            return(RpcHandler.From <Account>(jsonResponse));
        }
Beispiel #30
0
        /// <summary>
        /// Derives public key from the given private (<paramref name="pk"/>) key using SHA-3 algorithm.
        /// </summary>
        /// <param name="pk">Private key.</param>
        /// <returns>The public key.</returns>
        public async Task <string> Pk2Public(string pk)
        {
            string jsonResponse = await in3.SendRpc(CryptoPk2Public, new object[] { pk });

            return(RpcHandler.From <string>(jsonResponse));
        }
Beispiel #31
0
 void Awake() {
     instance = this;
 }
Beispiel #32
0
 internal void Register(string method, RpcHandler handler)
 {
     if (!_handlers.TryAdd(method, handler))
         throw new Exception("Duplicate RPC handler");
 }