Closed nidhaloff closed 2 years ago
You will not be able to make an HTTP request directly from within a smart contract.
Producing data and consuming data from the outside world on the blockchain is normally done through oracles. You might want to take a look at Provable, LiquidOracles
Another option would be to monitor the chain through the state_history_plugin, use fill-queue or fill-pg(aka history-tools), filter based on contract type, then act accordingly.
@praphael Thanks for the answer, but why isn't it possible though?
Is this specific to http or do you mean that it is generally prohibited to connect to the outside world from the smart contract?
Nondeterministic behavior is not allowed, because the blockchain has to be able to validate smart contract execution.
@praphael But why is sending http requests nondeterministic? can you please explain?
My goal is to send http requests without updating state (so just notify), so how can this be a nondeterministic behavior?
@heifner Can you please explain why this is not possible before closing the issue?
http is not deterministic. The endpoint might not be available when validation nodes are attempting to validate the contract execution.
@praphael But why is sending http requests nondeterministic? can you please explain?
My goal is to notify an external server whenever I update my multi_index table or after transaction validation, so how can this be a nondeterministic behavior?
Because the server could have one response at a certain time, and then when another node tries to replay the transaction, the server could responds with something different. Or not even exist at all. This is major problem with a blockchain as two or more nodes may not be able to reach a consensus on the results of the execution of the smart contract.
Please see https://developers.eos.io/welcome/latest/protocol-guides/consensus_protocol
This discussion is probably better suited for Stackexchange https://eosio.stackexchange.com/
@praphael @heifner thanks for the explanation. So how can I listen on table changes?
I know that I can read the multi_index table using eosjs, but is there any publish/subscribe approach, where I can just connect to the network and receive changes whenever something happens on the chain?
This must be possible because some EOSIO websites show how the mainnet is being updated in real time
I would look at something like: https://dfuse.eosnation.io/
@heifner thanks, however, dfuse.eosnation.io is an external service provider and I need to get an api key to use their services.
Why can't I do this alone without any external services or how did they implement this? that's what I'm actually interested in.
You can do this yourself using state_history_plugin (push) or trace_api_plugin (pull) but it will take some work to create a client. https://developers.eos.io/welcome/latest/tools/history-tools/index
I would recommend you ask for advice on telegram https://t.me/joinchat/0uhWYfXVpPlkNTA1
@nidhaloff If it was not clear from Kevin's post, in order to do this yourself you would have to be running your own nodeos instance, connecting P2P to the chain of interest. For some chains such as mainnet this will most likely require a dedicated machine/instance of moderate capability. You can then experiment with the different plugins ( trace_history, state_history), and then write a a client in any language you want, e.g Python, which acts appropriately on the information.
@praphael Thank you. That's exactly what I'm doing now I'm running a private chain (a private nodeos instance in a VM) and I'm working on a proof of concept. So can I write an extra plugin that will expose a web socket or an mqtt pub-sub interface? Is there any example for this?
If you are referring to a nodeos plugin, that would be unnecessary and time consuming.
From your use case (private_chain) it sounds like the simplest and fastest way is to use the trace_api_plugin, as it uses standard HTTP requests. It is a pull API however and so doesn't have filtering, etc. so you would have to inspect every block https://developers.eos.io/manuals/eos/latest/nodeos/plugins/trace_api_plugin/index
You can also use the state_history_plugin, which is a push API. https://developers.eos.io/manuals/eos/latest/nodeos/plugins/state_history_plugin/index
This would be more suitable for chains which can get busy such as mainnet and WAX .
The two endpoints we have for state_history are currently fill-pg (fills up PostgreSQL db) https://github.com/eosio/history-tools
and fill-queue ( pushes to MQ protocol, e.g RabbitMQ). https://github.com/EOSIO/fill-queue.
In theory you could also write your own state_history endpoint, but probably unnecessary.
I want to use this header-only library to make http requests. I used the lib many times and I had no issues. However, I think there is compatibility issues with eosio.cdt, but I'm not sure therefore I'm asking here.
I'm using eosio-cpp to compile the contract. It is working perfectly. I don't know how to link external libraries therefore, I prefer to use header-only libraries in my project. Basically, I copy paste the header files under include/ and then build the contract with eosio-cpp. I used nlohmann::json in the past and I could build the contract with eosio-cpp. Now I want to do the same thing by adding cpp-httplib, but I'm getting the error
I used this library in many projects and never got this error, so is it a compatibility issue with eosio.cdt? If yes can you please suggest an alternative? and how to build/include external libraries in my smart contract project? I could not find any resources on this topic.