In some cases, it is desirable to be able to call HTTP or REST APIs from the Smart Contract. This allows you to move complex or expensive computation from the blockchain to a centrally or peer-hosted service.
Alternatively, a Smart Contract function may wish to call third-party HTTP or REST APIs that provide external data. For example, a third-party API may provide data about the current price of a stock, or the current weather and temperature, which can be used to determine whether or not the conditions of a contract have been fulfilled.
Hyperledger Consensus Considerations
In Hyperledger Fabric, the consensus in a business network is achieved by having peer nodes in multiple organizations endorse transactions. Transactions are endorsed by executing the chaincode and signing the results of that execution. In order for the transaction to be committed by the blockchain network, all peer nodes endorsing the transaction must produce the same results from executing the chaincode.
When a business network makes an HTTP request using the APIs described above, those HTTP requests will be executed on all peer nodes endorsing the transaction. This will result in n HTTP requests, where n is the number of peer nodes endorsing the transaction.
In order for consensus to be achieved when business networks make HTTP requests, you must be careful to ensure that transaction processor functions make the same HTTP requests on all peer nodes and then perform the same processing on the HTTP responses on all peer nodes.
For example, consider a business network that uses an HTTP request to look up a stock price from an external symbol. The business network then uses the stock price to adjust the balance on a participant's account. If different peer nodes receive different stock prices, then they will attempt to make different adjustments to the balance on the participants' accounts. This will result in a consensus failure, and the transaction is rejected.
HTTP requests may result in different responses for multiple reasons:
Peer nodes in different organizations may run in different data centers, in different countries, and in different time zones.
- Peer nodes in different organizations may not have access to the HTTP server depending on public internet access and firewall restrictions.
- Peer nodes in different organizations may authenticate to the HTTP server as different users, resulting in different HTTP responses.
In order to minimize the risks of consensus failures when making HTTP requests from a transaction processor function, it is recommended you use to make HTTP requests that are either:
- Safe, in that the HTTP request does not modify any state on the HTTP server.
- Idempotent, in that the same HTTP request can be made many times without different outcomes.
CORS (Cross-Origin Resource Sharing)
Business networks deployed to the Web Browser connection from the Hyperledger Composer Playground run inside the web browser. When transaction processor functions inside these business networks make HTTP requests using the APIs described above, those HTTP requests are handled using the HTTP client built into the web browser.
HTTP clients built into the web browser require that the HTTP server is CORS (Cross-Origin Resource Sharing) compliant. If you deploy business networks to the Web Browser connection, then you must ensure that the HTTP server has been configured to be CORS compliant.
For more information, see: https://enable-cors.org
Docker Network Resolution
Business networks deployed to Hyperledger Fabric run within a chaincode Docker container. This means that the business networks are subject to the DNS resolution and network services provided by Docker, instead of those services provided by the host machine. Additionally, the chaincode Docker container has its own IP address.
This means that localhost resolves to the chaincode Docker container, rather than the host machine. Any HTTP requests made to localhost, for example, https://localhost:3000/api/Vehicle, will not work as expected.
The easiest workaround is to use a DNS name for your REST server that is publicly resolvable.