Advance Topics
Encrypted Queries (To Be Updated…)
(Coming Soon on Testnet and Mainnet compatible with Iris update)
Certain contexts, such as smart contracts on public blockchains, might require a level of privacy to protect data from public scrutiny. Developers can make encrypted Say network queries by encrypting all of a query with a secret key. The encrypted queries feature may be of interested to developers who want to deploy their blockchain applications of public networks. For example, if an application leverages data from an authenticated API, it would be dangerous to disclose the API key to anyway who is monitoring the public chain.
One the query is encrypted, only Saynetwork will then be able to decrypt the request using the same secret key
To encrypt the query, Saynetwork provides a public webpage interface, which can be found at https://ae.say.network the backend is serving from api
subdomain. Alternatively, A CLI tool is under development to encrypt an arbitrary string of text.
Encrypting of datasource URL in our case:
http://api.openweathermap.org/data/2.5/weather?q=amritsar&appid=my_real_key
Returns:
cf349a4ca439fc621bd5a76f4a87faf3b125baee81fcc1023ca361627e7dd58670e79bfffeb94591b1bcd86196e96b9395b47d74d2c6215743b75c35f857d77f98e085d1a98efb3c758504a34be5b276fe5e6044fcf86836cfcd7f267ccbb3f6531783b08413544ab2ff2f8b0309c0a413590948fff79ef9099635649cccb3cef06dd2a238ecfbbb38d015ed20a54e941c0b3867ca47b93247
The encryption uses aes-256-gcm
, you just need to pass the query as UTF-8 string, salt
and iv
are randomly generated.
Example
include "Say.aes"
contract MyContract =
record state = {
query_id : bytes(32),
answer: option(string)
}
stateful entrypoint init() =
Say.setOracle("oracle_ukey")
{query_id = #000000000000000000000000000000000000000000000000000000000000000,
answer = None}
public entrypoint plus() : address =
Say.getOracleAddress()
payable stateful entrypoint query() : bytes(32) =
require(Say.getBaseFee() =< Call.value, "Insufficient fee")
let _id : bytes(32) = Say.query("cf349a4ca439fc621bd5a76f4a87faf3b125baee81fcc1023ca361627e7dd58670e79bfffeb94591b1bcd86196e96b9395b47d74d2c6215743b75c35f857d77f98e085d1a98efb3c758504a34be5b276fe5e6044fcf86836cfcd7f267ccbb3f6531783b08413544ab2ff2f8b0309c0a413590948fff79ef9099635649cccb3cef06dd2a238ecfbbb38d015ed20a54e941c0b3867ca47b93247", Call.value)
put(state{query_id=_id})
_id
stateful entrypoint getAnswer() : option(string) =
Say.getAnswer(state.query_id)
stateful entrypoint useAnswer() : option(string) =
put(state{answer = Say.getAnswer(state.query_id)})
state.answer