Neo: Using Oracle Protocol to access NeoFS from Smart Contract code

Created on 25 Nov 2019  路  5Comments  路  Source: neo-project/neo

Summary or problem description

For access to NeoFS from Smart Contract code we propose to use Oracle protocol.

The most obvious reason is that for Neo Smart Contract, NeoFS is an external data source with state not reflected in Neo Blockchain directly. It may change independently and at any time.

Oracle protocol was supposed to solve exactly this problem, enabling Smart Contracts to interact with external entities in a safe way. Re-implementing the same functionality set for NeoFS in a separate InterOp service may be inefficient and error prone.

Do you have any solution you want to propose?

As a solution, we propose to introduce NeoFS Oracle type that would process requests to neofs:// protocol.

In this case all operations with NeoFS will be reflected on-chain in a form of Oracle Transactions. This will not only enable proper Tx and State verification, but also reduce load on NeoFS Oracle nodes by using OracleResultCache mechanism.

All operations in NeoFS require to have request signed by a key associated with Neo Account/Wallet. Without Oracle protocol this can't be done, as SC code(bytecode) is freely available and there is no mechanism to hide secret keys as SC must be executable by any node to verify and calculate State. While using Oracle protocol, this problem may be solved with NeoFS ACL mechanism by allowing certain operations for NeoFS Oracle Nodes, identified by key pairs.

NeoFS API available for SC

We propose to have a limited set of NeoFS operations available from SC runtime.

We propose not to have Container operations. For most cases those may be done not from SC code by SC owner.

Note, that Object.Get* method will require to store the returned data in OracleTx, so the size of NeoFS objects being get from Smart Contract must not exceed maximal Tx data size. the same is valid for Object.Search operation. The returned list of objects found must be limited to fit Tx data limits.

For Object.Put and Object.Delete operations, that just need to fix the returned operation status, TX data limit is not a problem.

Neo Version

  • Neo 3

Where in the software does this update applies to?

  • Ledger
  • SDK
  • VM
  • Other: Oracles
discussion neofs

Most helpful comment

c# Oracle.Get($"neofs://{ContainerID}/{ObjectID}"); //Object.Get Oracle.Get($"neofs://{ContainerID}/{ObjectID}/range/{Offset}|{Length}"); //Object.GetRange Oracle.Get($"neofs://{ContainerID}/{ObjectID}/hash/{Offset}|{Length}"); //Object.GetRangeHash Oracle.Get($"neofs://{ContainerID}/{ObjectID}/header"); //Object.Head

All 5 comments

If we decide to allow SC to access NeoFS through oracle, the NeoFS should not provide any interface to the SC directly. It only need to provide interfaces to oracle. The NeoFS native contract should only provide deposit and withdrawal services.

If we decide to allow SC to access NeoFS through oracle, the NeoFS should not
provide any interface to the SC directly. It only need to provide interfaces
to oracle.

Yes, Smart Contract will not issue gRPC requests to NeoFS directly, but issue
corresponding operations through NeoFS Oracle. Something like

data = Oracle.NeoFs.Object.Get("ContainerID" + "/" + "ObjectID");

The NeoFS native contract should only provide deposit and withdrawal services.

NeoFS Smart Contract also needs to manage InnerRing nodes list.

I prefer to use this style:

```c#
data = Oracle.Get($"neofs://{ContainerID}/{ObjectID}");

It is unified with https request:

```c#
data = Oracle.Get("https://example.com/xxx");

Agree, this simplified style maybe used for simple get requests, as DX improvement and syntax sugar, but for more fine-grained NeoFS operations a full Oracle.NeoFS runtime namespace must be supported.

c# Oracle.Get($"neofs://{ContainerID}/{ObjectID}"); //Object.Get Oracle.Get($"neofs://{ContainerID}/{ObjectID}/range/{Offset}|{Length}"); //Object.GetRange Oracle.Get($"neofs://{ContainerID}/{ObjectID}/hash/{Offset}|{Length}"); //Object.GetRangeHash Oracle.Get($"neofs://{ContainerID}/{ObjectID}/header"); //Object.Head

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vncoelho picture vncoelho  路  3Comments

igormcoelho picture igormcoelho  路  3Comments

doubiliu picture doubiliu  路  3Comments

igormcoelho picture igormcoelho  路  4Comments

igormcoelho picture igormcoelho  路  4Comments